@stll/folio-core 0.43.0 → 0.45.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 (237) hide show
  1. package/dist/ai-edits/__fixtures__/paragraphs.js +2 -2
  2. package/dist/ai-edits/headless.js +7 -5
  3. package/dist/ai-edits/index.d.ts +2 -2
  4. package/dist/ai-edits/index.js +2 -2
  5. package/dist/ai-edits/snapshot.js +13 -9
  6. package/dist/compare/content-alignment.js +94 -54
  7. package/dist/compare/inline-atoms.js +34 -20
  8. package/dist/compare/style-resources.js +6 -0
  9. package/dist/content-controls/mutateContentControls.js +4 -2
  10. package/dist/display-list/dom/renderDisplayListToDom.js +8 -8
  11. package/dist/document-operations.js +14 -3
  12. package/dist/docx/appVersionNormalization.d.ts +0 -18
  13. package/dist/docx/blockContentParser.js +8 -0
  14. package/dist/docx/blockRangeMarkers.d.ts +36 -0
  15. package/dist/docx/blockRangeMarkers.js +59 -0
  16. package/dist/docx/bookmarkParser.d.ts +2 -20
  17. package/dist/docx/bookmarkParser.js +6 -30
  18. package/dist/docx/borderParser.d.ts +13 -0
  19. package/dist/docx/borderParser.js +71 -0
  20. package/dist/docx/builtInStyles.d.ts +165 -0
  21. package/dist/docx/builtInStyles.js +239 -0
  22. package/dist/docx/commentIdNormalization.d.ts +3 -1
  23. package/dist/docx/commentIdNormalization.js +18 -1
  24. package/dist/docx/commentParser.d.ts +2 -1
  25. package/dist/docx/commentParser.js +80 -42
  26. package/dist/docx/commentReferenceNormalization.d.ts +4 -1
  27. package/dist/docx/commentReferenceNormalization.js +23 -14
  28. package/dist/docx/commentThreadKey.d.ts +18 -0
  29. package/dist/docx/commentThreadKey.js +22 -0
  30. package/dist/docx/danglingRelationshipReferences.d.ts +15 -0
  31. package/dist/docx/danglingRelationshipReferences.js +30 -0
  32. package/dist/docx/defaultParagraphStyle.d.ts +18 -1
  33. package/dist/docx/defaultParagraphStyle.js +23 -1
  34. package/dist/docx/diagramPreview.js +87 -27
  35. package/dist/docx/documentParser.d.ts +2 -1
  36. package/dist/docx/documentParser.js +2 -2
  37. package/dist/docx/drawingUtils.d.ts +8 -1
  38. package/dist/docx/drawingUtils.js +12 -3
  39. package/dist/docx/fieldParser.js +3 -5
  40. package/dist/docx/footnoteParser.d.ts +3 -2
  41. package/dist/docx/footnoteParser.js +19 -4
  42. package/dist/docx/groupDrawingParser.js +4 -4
  43. package/dist/docx/headerFooterRefParser.d.ts +4 -3
  44. package/dist/docx/headerFooterRefParser.js +42 -12
  45. package/dist/docx/headerFooterReferenceNormalization.d.ts +4 -1
  46. package/dist/docx/headerFooterReferenceNormalization.js +5 -1
  47. package/dist/docx/hyperlinkParser.js +13 -17
  48. package/dist/docx/imageParser.d.ts +10 -2
  49. package/dist/docx/imageParser.js +80 -30
  50. package/dist/docx/imageRawXml.d.ts +14 -1
  51. package/dist/docx/imageRawXml.js +35 -11
  52. package/dist/docx/markupRangeMarker.d.ts +15 -0
  53. package/dist/docx/markupRangeMarker.js +44 -0
  54. package/dist/docx/mathToMathml.js +12 -14
  55. package/dist/docx/nonVisualDrawingProps.d.ts +34 -0
  56. package/dist/docx/nonVisualDrawingProps.js +46 -0
  57. package/dist/docx/noteReferenceStyles.d.ts +29 -0
  58. package/dist/docx/noteReferenceStyles.js +70 -0
  59. package/dist/docx/numberingReferenceNormalization.d.ts +4 -1
  60. package/dist/docx/numberingReferenceNormalization.js +20 -1
  61. package/dist/docx/paraIdRangeNormalization.d.ts +0 -19
  62. package/dist/docx/paragraphParser.js +66 -99
  63. package/dist/docx/paragraphPropertySource.js +1 -0
  64. package/dist/docx/paragraphTextBoxEnrichment.js +3 -0
  65. package/dist/docx/paragraphTraversal.d.ts +37 -1
  66. package/dist/docx/paragraphTraversal.js +84 -1
  67. package/dist/docx/parseContext.d.ts +37 -0
  68. package/dist/docx/parseContext.js +67 -0
  69. package/dist/docx/parseWarningMessage.d.ts +6 -0
  70. package/dist/docx/parseWarningMessage.js +44 -0
  71. package/dist/docx/parser.js +83 -29
  72. package/dist/docx/previewBudget.d.ts +64 -0
  73. package/dist/docx/previewBudget.js +88 -0
  74. package/dist/docx/relsParser.d.ts +28 -11
  75. package/dist/docx/relsParser.js +26 -13
  76. package/dist/docx/revisionIdNormalization.js +96 -10
  77. package/dist/docx/rezip.js +80 -40
  78. package/dist/docx/runConsolidator.js +1 -2
  79. package/dist/docx/runParser.d.ts +8 -1
  80. package/dist/docx/runParser.js +30 -48
  81. package/dist/docx/sdtPropertiesPatch.js +24 -18
  82. package/dist/docx/sectionParser.d.ts +2 -1
  83. package/dist/docx/sectionParser.js +21 -65
  84. package/dist/docx/sectionReferenceHistory.js +2 -2
  85. package/dist/docx/selectiveSave.js +6 -6
  86. package/dist/docx/serializer/blockSdtSerializer.js +38 -26
  87. package/dist/docx/serializer/borderSerializer.d.ts +2 -3
  88. package/dist/docx/serializer/borderSerializer.js +13 -12
  89. package/dist/docx/serializer/commentSerializer.d.ts +41 -16
  90. package/dist/docx/serializer/commentSerializer.js +82 -72
  91. package/dist/docx/serializer/documentSerializer.d.ts +1 -5
  92. package/dist/docx/serializer/documentSerializer.js +6 -16
  93. package/dist/docx/serializer/fontTableSerializer.js +6 -6
  94. package/dist/docx/serializer/headerFooterSerializer.js +10 -5
  95. package/dist/docx/serializer/markupRangeAttributes.d.ts +8 -0
  96. package/dist/docx/serializer/markupRangeAttributes.js +24 -0
  97. package/dist/docx/serializer/noteSerializer.js +5 -0
  98. package/dist/docx/serializer/numberingSerializer.js +7 -6
  99. package/dist/docx/serializer/paragraphSerializer.d.ts +1 -5
  100. package/dist/docx/serializer/paragraphSerializer.js +47 -52
  101. package/dist/docx/serializer/partNamespaces.js +2 -2
  102. package/dist/docx/serializer/runSerializer.js +57 -31
  103. package/dist/docx/serializer/sectionPropertiesSerializer.js +11 -10
  104. package/dist/docx/serializer/settingsSerializer.js +4 -3
  105. package/dist/docx/serializer/stylesSerializer.js +6 -6
  106. package/dist/docx/serializer/tableSerializer.js +37 -21
  107. package/dist/docx/serializer/textFormattingSerializer.d.ts +2 -3
  108. package/dist/docx/serializer/textFormattingSerializer.js +29 -28
  109. package/dist/docx/serializer/themeSerializer.js +6 -6
  110. package/dist/docx/serializer/trackedChangeAttributes.js +2 -2
  111. package/dist/docx/serializer/xmlUtils.d.ts +1 -2
  112. package/dist/docx/serializer/xmlUtils.js +1 -13
  113. package/dist/docx/server/boundedArchive.d.ts +12 -0
  114. package/dist/docx/server/boundedArchive.js +20 -1
  115. package/dist/docx/server/build.js +8 -1
  116. package/dist/docx/server/createBilingualDocument.js +10 -18
  117. package/dist/docx/server/extractDocxText.js +3 -4
  118. package/dist/docx/server/validateDocxConformance.js +22 -1
  119. package/dist/docx/shadingParser.d.ts +6 -0
  120. package/dist/docx/shadingParser.js +32 -0
  121. package/dist/docx/shapeParser.js +10 -8
  122. package/dist/docx/styleParser.js +13 -87
  123. package/dist/docx/styleReferenceResolution.d.ts +36 -0
  124. package/dist/docx/styleReferenceResolution.js +51 -0
  125. package/dist/docx/tableLook.d.ts +57 -0
  126. package/dist/docx/tableLook.js +63 -0
  127. package/dist/docx/tableParser.d.ts +7 -9
  128. package/dist/docx/tableParser.js +64 -110
  129. package/dist/docx/textBoxParser.js +11 -6
  130. package/dist/docx/trackedMoveRangeNormalization.d.ts +3 -1
  131. package/dist/docx/trackedMoveRangeNormalization.js +11 -21
  132. package/dist/docx/transitionalSpelling.d.ts +13 -2
  133. package/dist/docx/transitionalSpelling.js +23 -1
  134. package/dist/docx/unzip.d.ts +23 -0
  135. package/dist/docx/unzip.js +32 -22
  136. package/dist/docx/verbatimCapture.js +5 -12
  137. package/dist/docx/vmlImageParser.js +5 -4
  138. package/dist/docx/vmlPreview.d.ts +1 -3
  139. package/dist/docx/vmlPreview.js +2 -30
  140. package/dist/docx/watermarkParser.js +2 -2
  141. package/dist/docx/xmlParser.d.ts +38 -33
  142. package/dist/docx/xmlParser.js +92 -47
  143. package/dist/docx/xmlResourceLimits.d.ts +89 -9
  144. package/dist/docx/xmlResourceLimits.js +105 -24
  145. package/dist/internal/pageBreakRunSourceDescendantIndex.js +2 -1
  146. package/dist/internal/paragraphFormattingSerialization.d.ts +2 -3
  147. package/dist/internal/paragraphFormattingSerialization.js +29 -8
  148. package/dist/layout-bridge/convert/footnoteLayout.js +2 -7
  149. package/dist/layout-engine/index.d.ts +2 -2
  150. package/dist/layout-engine/index.js +2 -2
  151. package/dist/layout-engine/measure/measureBlocks.js +1 -6
  152. package/dist/layout-engine/types.d.ts +8 -2
  153. package/dist/layout-engine/types.js +35 -2
  154. package/dist/layout-painter/renderImage.js +4 -3
  155. package/dist/layout-painter/renderParagraph.js +4 -3
  156. package/dist/managers/autoSaveCodec.js +2 -8
  157. package/dist/markdown/images.js +1 -4
  158. package/dist/markdown/index.js +1 -1
  159. package/dist/markdown/internals.d.ts +6 -1
  160. package/dist/markdown/internals.js +14 -1
  161. package/dist/markdown/renderBlock.js +35 -21
  162. package/dist/markdown/renderParagraph.js +14 -5
  163. package/dist/markdown/renderRuns.js +4 -3
  164. package/dist/markdown/renderTable.js +4 -3
  165. package/dist/markdown/trailers.js +41 -7
  166. package/dist/markdown/types.d.ts +3 -7
  167. package/dist/prosemirror/attrs/index.js +71 -5
  168. package/dist/prosemirror/bookmarkBoundaryAttrs.d.ts +11 -1
  169. package/dist/prosemirror/bookmarkBoundaryAttrs.js +18 -3
  170. package/dist/prosemirror/commands/image.js +1 -0
  171. package/dist/prosemirror/commands/index.d.ts +3 -3
  172. package/dist/prosemirror/commands/index.js +2 -2
  173. package/dist/prosemirror/commands/paragraph.d.ts +3 -3
  174. package/dist/prosemirror/commands/paragraph.js +2 -2
  175. package/dist/prosemirror/commentIdAllocator.js +2 -7
  176. package/dist/prosemirror/conversion/fromProseDoc.js +197 -68
  177. package/dist/prosemirror/conversion/toProseDoc.d.ts +1 -14
  178. package/dist/prosemirror/conversion/toProseDoc.js +458 -335
  179. package/dist/prosemirror/extensions/core/ParagraphExtension.d.ts +14 -1
  180. package/dist/prosemirror/extensions/core/ParagraphExtension.js +11 -6
  181. package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.js +3 -3
  182. package/dist/prosemirror/extensions/features/PasteCleanupExtension.d.ts +4 -1
  183. package/dist/prosemirror/extensions/features/PasteCleanupExtension.js +6 -2
  184. package/dist/prosemirror/extensions/features/pastedHeadingStyles.d.ts +7 -0
  185. package/dist/prosemirror/extensions/features/pastedHeadingStyles.js +74 -0
  186. package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +2 -3
  187. package/dist/prosemirror/extensions/marks/markUtils.d.ts +11 -3
  188. package/dist/prosemirror/extensions/marks/markUtils.js +98 -19
  189. package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.js +7 -3
  190. package/dist/prosemirror/extensions/nodes/ImageExtension.js +6 -1
  191. package/dist/prosemirror/extensions/nodes/ShapeExtension.js +8 -2
  192. package/dist/prosemirror/extensions/nodes/TableExtension.js +15 -1
  193. package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +8 -4
  194. package/dist/prosemirror/extensions/types.d.ts +2 -2
  195. package/dist/prosemirror/index.d.ts +3 -3
  196. package/dist/prosemirror/index.js +3 -3
  197. package/dist/prosemirror/insertOperations.d.ts +9 -2
  198. package/dist/prosemirror/insertOperations.js +9 -4
  199. package/dist/prosemirror/paragraphFormattingProvenance.d.ts +162 -0
  200. package/dist/prosemirror/paragraphFormattingProvenance.js +115 -0
  201. package/dist/prosemirror/plugins/documentStyles.d.ts +9 -1
  202. package/dist/prosemirror/plugins/documentStyles.js +11 -1
  203. package/dist/prosemirror/plugins/index.d.ts +2 -2
  204. package/dist/prosemirror/plugins/index.js +2 -2
  205. package/dist/prosemirror/plugins/revisionIds.d.ts +11 -2
  206. package/dist/prosemirror/plugins/revisionIds.js +21 -6
  207. package/dist/prosemirror/runFormattingReconciliation.js +3 -2
  208. package/dist/prosemirror/runStyleFormatting.d.ts +1 -1
  209. package/dist/prosemirror/schema/nodes.d.ts +81 -1
  210. package/dist/prosemirror/styles/resolvedStyleAttrs.js +2 -0
  211. package/dist/prosemirror/styles/styleResolver.d.ts +9 -0
  212. package/dist/prosemirror/styles/styleResolver.js +12 -0
  213. package/dist/style-engine/styleEngine.d.ts +3 -0
  214. package/dist/style-engine/styleEngine.js +3 -0
  215. package/dist/style-sets/extract.js +1 -23
  216. package/dist/style-sets/stellaStyle.js +46 -39
  217. package/dist/style-sets/styleSetNormalization.d.ts +19 -0
  218. package/dist/style-sets/styleSetNormalization.js +99 -0
  219. package/dist/types/content.d.ts +2 -2
  220. package/dist/utils/base64.d.ts +36 -0
  221. package/dist/utils/base64.js +40 -0
  222. package/dist/utils/clipboard.js +2 -1
  223. package/dist/utils/createDocument.js +145 -20
  224. package/dist/utils/headingCollector.d.ts +8 -5
  225. package/dist/utils/headingCollector.js +23 -25
  226. package/dist/utils/tableOfContentsStyle.js +9 -2
  227. package/dist/utils/units.d.ts +10 -1
  228. package/dist/utils/units.js +12 -1
  229. package/dist/utils/urlSecurity.d.ts +8 -2
  230. package/dist/utils/urlSecurity.js +21 -3
  231. package/package.json +2 -2
  232. package/dist/docx/textWhitespace.d.ts +0 -4
  233. package/dist/docx/textWhitespace.js +0 -4
  234. package/dist/layout-bridge/engine/tableWidthUtils.d.ts +0 -6
  235. package/dist/layout-bridge/engine/tableWidthUtils.js +0 -25
  236. package/dist/markdown/headings.d.ts +0 -13
  237. package/dist/markdown/headings.js +0 -20
@@ -1,2 +1,2 @@
1
- import { BlockContent, BlockSdt, BookmarkEnd, BookmarkStart, BreakContent, Column, Comment, CommentRangeEnd, CommentRangeStart, CommentReference, ComplexField, Deletion, DocumentBody, DrawingContent, DrawingRawXmlMode, Endnote, EndnotePosition, EndnoteProperties, Field, FieldCharContent, FieldType, FooterReference, Footnote, FootnotePosition, FootnoteProperties, HeaderFooter, HeaderFooterType, HeaderReference, Hyperlink, Image, ImageCrop, ImagePadding, ImagePosition, ImageSize, ImageTransform, ImageWrap, InlineSdt, Insertion, InstrTextContent, LineNumberRestart, MathEquation, MoveFrom, MoveFromRangeEnd, MoveFromRangeStart, MoveTo, MoveToRangeEnd, MoveToRangeStart, NoBreakHyphenContent, NoteNumberRestart, NoteReferenceContent, PageOrientation, Paragraph, ParagraphContent, ParagraphPropertyChange, PositionalTab, PropertyChangeInfo, Run, RunContent, RunPropertyChange, SdtProperties, SdtType, Section, SectionProperties, SectionStart, Shape, ShapeContent, ShapeFill, ShapeGeometryAdjustment, ShapeOutline, ShapeTextBody, ShapeType, SimpleField, SoftHyphenContent, SymbolContent, TabContent, Table, TableCell, TableCellPropertyChange, TableRow, TableRowPropertyChange, TableStructuralChangeInfo, TextBox, TextContent, TrackedChangeInfo, TrackedRunChange, TrackedRunContent, VerticalAlign } from "@stll/docx-core/model";
2
- export type { BlockContent, BlockSdt, BookmarkEnd, BookmarkStart, BreakContent, Column, Comment, CommentRangeEnd, CommentRangeStart, CommentReference, ComplexField, Deletion, DocumentBody, DrawingContent, DrawingRawXmlMode, Endnote, EndnotePosition, EndnoteProperties, Field, FieldCharContent, FieldType, FooterReference, Footnote, FootnotePosition, FootnoteProperties, HeaderFooter, HeaderFooterType, HeaderReference, Hyperlink, Image, ImageCrop, ImagePadding, ImagePosition, ImageSize, ImageTransform, ImageWrap, InlineSdt, Insertion, InstrTextContent, LineNumberRestart, MathEquation, MoveFrom, MoveFromRangeEnd, MoveFromRangeStart, MoveTo, MoveToRangeEnd, MoveToRangeStart, NoBreakHyphenContent, NoteNumberRestart, NoteReferenceContent, PageOrientation, Paragraph, ParagraphContent, ParagraphPropertyChange, PositionalTab, PropertyChangeInfo, Run, RunContent, RunPropertyChange, SdtProperties, SdtType, Section, SectionProperties, SectionStart, Shape, ShapeContent, ShapeFill, ShapeGeometryAdjustment, ShapeOutline, ShapeTextBody, ShapeType, SimpleField, SoftHyphenContent, SymbolContent, TabContent, Table, TableCell, TableCellPropertyChange, TableRow, TableRowPropertyChange, TableStructuralChangeInfo, TextBox, TextContent, TrackedChangeInfo, TrackedRunChange, TrackedRunContent, VerticalAlign };
1
+ import { BlockContent, BlockRangeMarkerCapture, BlockSdt, BookmarkEnd, BookmarkStart, BreakContent, Column, Comment, CommentRangeEnd, CommentRangeStart, CommentReference, ComplexField, Deletion, DisplacedByCustomXml, DocumentBody, DrawingContent, DrawingRawXmlMode, Endnote, EndnotePosition, EndnoteProperties, Field, FieldCharContent, FieldType, FooterReference, Footnote, FootnotePosition, FootnoteProperties, HeaderFooter, HeaderFooterType, HeaderReference, Hyperlink, Image, ImageCrop, ImagePadding, ImagePosition, ImageSize, ImageTransform, ImageWrap, InlineSdt, Insertion, InstrTextContent, LineNumberRestart, MathEquation, MoveFrom, MoveFromRangeEnd, MoveFromRangeStart, MoveTo, MoveToRangeEnd, MoveToRangeStart, NoBreakHyphenContent, NoteNumberRestart, NoteReferenceContent, PageOrientation, Paragraph, ParagraphContent, ParagraphPropertyChange, PositionalTab, PropertyChangeInfo, Run, RunContent, RunPropertyChange, SdtProperties, SdtType, Section, SectionProperties, SectionStart, Shape, ShapeContent, ShapeFill, ShapeGeometryAdjustment, ShapeOutline, ShapeTextBody, ShapeType, SimpleField, SoftHyphenContent, SymbolContent, TabContent, Table, TableCell, TableCellPropertyChange, TableRow, TableRowPropertyChange, TableStructuralChangeInfo, TextBox, TextContent, TrackedChangeInfo, TrackedRunChange, TrackedRunContent, VerticalAlign } from "@stll/docx-core/model";
2
+ export type { BlockContent, BlockRangeMarkerCapture, BlockSdt, BookmarkEnd, BookmarkStart, BreakContent, Column, Comment, CommentRangeEnd, CommentRangeStart, CommentReference, ComplexField, Deletion, DisplacedByCustomXml, DocumentBody, DrawingContent, DrawingRawXmlMode, Endnote, EndnotePosition, EndnoteProperties, Field, FieldCharContent, FieldType, FooterReference, Footnote, FootnotePosition, FootnoteProperties, HeaderFooter, HeaderFooterType, HeaderReference, Hyperlink, Image, ImageCrop, ImagePadding, ImagePosition, ImageSize, ImageTransform, ImageWrap, InlineSdt, Insertion, InstrTextContent, LineNumberRestart, MathEquation, MoveFrom, MoveFromRangeEnd, MoveFromRangeStart, MoveTo, MoveToRangeEnd, MoveToRangeStart, NoBreakHyphenContent, NoteNumberRestart, NoteReferenceContent, PageOrientation, Paragraph, ParagraphContent, ParagraphPropertyChange, PositionalTab, PropertyChangeInfo, Run, RunContent, RunPropertyChange, SdtProperties, SdtType, Section, SectionProperties, SectionStart, Shape, ShapeContent, ShapeFill, ShapeGeometryAdjustment, ShapeOutline, ShapeTextBody, ShapeType, SimpleField, SoftHyphenContent, SymbolContent, TabContent, Table, TableCell, TableCellPropertyChange, TableRow, TableRowPropertyChange, TableStructuralChangeInfo, TextBox, TextContent, TrackedChangeInfo, TrackedRunChange, TrackedRunContent, VerticalAlign };
@@ -0,0 +1,36 @@
1
+ //#region src/utils/base64.d.ts
2
+ /**
3
+ * The package's one bytes-to-base64 encoder.
4
+ *
5
+ * Every call site that spelled this itself got a different answer to the same
6
+ * two questions, and one of them got the first question wrong:
7
+ *
8
+ * - `btoa(new TextDecoder("latin1").decode(bytes))` is not a binary string.
9
+ * The Encoding standard maps the `latin1` label to windows-1252, so bytes
10
+ * 0x80-0x9F decode to characters outside Latin-1 and `btoa` throws
11
+ * `InvalidCharacterError` on them. Ordinary image bytes contain those values,
12
+ * so the browser path of that spelling fails on real input.
13
+ * - `String.fromCharCode(...chunk)` is correct but spreads a chunk's worth of
14
+ * arguments per call, and the intermediate binary string is as large as the
15
+ * input.
16
+ *
17
+ * Neither question has to be asked per call site, so it is asked here once.
18
+ * The runtime's own encoder answers it when the runtime has one, and the
19
+ * portable encoder below answers it when not; both produce canonical base64,
20
+ * so the choice is invisible in the output.
21
+ */
22
+ /**
23
+ * Encode into exactly one intermediate buffer: ASCII codes are written into a
24
+ * single array and decoded once, so a megabyte-scale input leaves the output
25
+ * string and nothing else.
26
+ *
27
+ * Exported because the runtimes the tests run on all carry a native encoder,
28
+ * and the fallback is the branch the browsers that lack one take.
29
+ */
30
+ declare const encodeBase64Portable: (bytes: Uint8Array) => string;
31
+ /** Encode bytes as canonical, padded, standard-alphabet base64. */
32
+ declare const bytesToBase64: (bytes: Uint8Array) => string;
33
+ /** Encode bytes as a `data:` URL with the given media type. */
34
+ declare const bytesToDataUrl: (bytes: Uint8Array, mimeType: string) => string;
35
+ //#endregion
36
+ export { bytesToBase64, bytesToDataUrl, encodeBase64Portable };
@@ -0,0 +1,40 @@
1
+ //#region src/utils/base64.ts
2
+ const BASE64_CODES = Uint8Array.from("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", (character) => character.charCodeAt(0));
3
+ const BASE64_PAD = 61;
4
+ /**
5
+ * Encode into exactly one intermediate buffer: ASCII codes are written into a
6
+ * single array and decoded once, so a megabyte-scale input leaves the output
7
+ * string and nothing else.
8
+ *
9
+ * Exported because the runtimes the tests run on all carry a native encoder,
10
+ * and the fallback is the branch the browsers that lack one take.
11
+ */
12
+ const encodeBase64Portable = (bytes) => {
13
+ const groups = Math.ceil(bytes.length / 3);
14
+ const encoded = new Uint8Array(groups * 4);
15
+ let read = 0;
16
+ let write = 0;
17
+ for (; read + 2 < bytes.length; read += 3) {
18
+ const triple = bytes[read] << 16 | bytes[read + 1] << 8 | bytes[read + 2];
19
+ encoded[write] = BASE64_CODES[triple >> 18 & 63];
20
+ encoded[write + 1] = BASE64_CODES[triple >> 12 & 63];
21
+ encoded[write + 2] = BASE64_CODES[triple >> 6 & 63];
22
+ encoded[write + 3] = BASE64_CODES[triple & 63];
23
+ write += 4;
24
+ }
25
+ const remaining = bytes.length - read;
26
+ if (remaining > 0) {
27
+ const tail = bytes[read] << 16 | (remaining === 2 ? bytes[read + 1] << 8 : 0);
28
+ encoded[write] = BASE64_CODES[tail >> 18 & 63];
29
+ encoded[write + 1] = BASE64_CODES[tail >> 12 & 63];
30
+ encoded[write + 2] = remaining === 2 ? BASE64_CODES[tail >> 6 & 63] : BASE64_PAD;
31
+ encoded[write + 3] = BASE64_PAD;
32
+ }
33
+ return new TextDecoder().decode(encoded);
34
+ };
35
+ /** Encode bytes as canonical, padded, standard-alphabet base64. */
36
+ const bytesToBase64 = ("toBase64" in Uint8Array.prototype ? (bytes) => bytes.toBase64() : void 0) ?? encodeBase64Portable;
37
+ /** Encode bytes as a `data:` URL with the given media type. */
38
+ const bytesToDataUrl = (bytes, mimeType) => `data:${mimeType};base64,${bytesToBase64(bytes)}`;
39
+ //#endregion
40
+ export { bytesToBase64, bytesToDataUrl, encodeBase64Portable };
@@ -1,5 +1,6 @@
1
1
  import { htmlCommentEnd } from "./htmlComments.js";
2
2
  import { stripXmlDeclarations } from "./stripXmlDeclarations.js";
3
+ import { sanitizeXmlCharacters } from "@stll/docx-core";
3
4
  import createDOMPurify from "dompurify";
4
5
  //#region src/utils/clipboard.ts
5
6
  /**
@@ -567,7 +568,7 @@ function createTextRun(text, formatting) {
567
568
  ...formatting !== void 0 ? { formatting } : {},
568
569
  content: [{
569
570
  type: "text",
570
- text
571
+ text: sanitizeXmlCharacters(text)
571
572
  }]
572
573
  };
573
574
  }
@@ -1,3 +1,8 @@
1
+ import { BUILT_IN_STYLE_NAME, builtInHeadingStyleName } from "../docx/builtInStyles.js";
2
+ import "../docx/defaultParagraphStyle.js";
3
+ import { createParseWarningCollector } from "../docx/parseContext.js";
4
+ import { formatParseWarnings } from "../docx/parseWarningMessage.js";
5
+ import { STYLE_SET_PART, normalizeDocumentStyleSet } from "../style-sets/styleSetNormalization.js";
1
6
  import "../style-sets/types.js";
2
7
  import { panic } from "better-result";
3
8
  import { DOCX_CONFORMANCE_CLASSES } from "@stll/docx-core/model";
@@ -12,13 +17,17 @@ import { DOCX_CONFORMANCE_CLASSES } from "@stll/docx-core/model";
12
17
  *
13
18
  * Font sizes are in half-points (e.g., 22 = 11pt, 40 = 20pt)
14
19
  * Colors are RGB hex without # prefix
20
+ *
21
+ * Each style carries the built-in `w:name` it stands for, which is how every
22
+ * consumer recognises it (`docx/builtInStyles.ts`), and the headings carry
23
+ * `w:outlineLvl` so a Word TOC field and the navigation pane list them.
15
24
  */
16
25
  function getDefaultStyles() {
17
26
  return [
18
27
  {
19
28
  styleId: "Normal",
20
29
  type: "paragraph",
21
- name: "Normal",
30
+ name: BUILT_IN_STYLE_NAME.normal,
22
31
  default: true,
23
32
  qFormat: true,
24
33
  uiPriority: 0,
@@ -34,7 +43,7 @@ function getDefaultStyles() {
34
43
  {
35
44
  styleId: "Title",
36
45
  type: "paragraph",
37
- name: "Title",
46
+ name: BUILT_IN_STYLE_NAME.title,
38
47
  basedOn: "Normal",
39
48
  next: "Normal",
40
49
  qFormat: true,
@@ -52,7 +61,7 @@ function getDefaultStyles() {
52
61
  {
53
62
  styleId: "Subtitle",
54
63
  type: "paragraph",
55
- name: "Subtitle",
64
+ name: BUILT_IN_STYLE_NAME.subtitle,
56
65
  basedOn: "Normal",
57
66
  next: "Normal",
58
67
  qFormat: true,
@@ -70,7 +79,7 @@ function getDefaultStyles() {
70
79
  {
71
80
  styleId: "Heading1",
72
81
  type: "paragraph",
73
- name: "Heading 1",
82
+ name: builtInHeadingStyleName(0),
74
83
  basedOn: "Normal",
75
84
  next: "Normal",
76
85
  qFormat: true,
@@ -86,13 +95,14 @@ function getDefaultStyles() {
86
95
  pPr: {
87
96
  spaceBefore: 400,
88
97
  spaceAfter: 120,
89
- lineSpacing: 240
98
+ lineSpacing: 240,
99
+ outlineLevel: 0
90
100
  }
91
101
  },
92
102
  {
93
103
  styleId: "Heading2",
94
104
  type: "paragraph",
95
- name: "Heading 2",
105
+ name: builtInHeadingStyleName(1),
96
106
  basedOn: "Normal",
97
107
  next: "Normal",
98
108
  qFormat: true,
@@ -108,13 +118,14 @@ function getDefaultStyles() {
108
118
  pPr: {
109
119
  spaceBefore: 360,
110
120
  spaceAfter: 80,
111
- lineSpacing: 240
121
+ lineSpacing: 240,
122
+ outlineLevel: 1
112
123
  }
113
124
  },
114
125
  {
115
126
  styleId: "Heading3",
116
127
  type: "paragraph",
117
- name: "Heading 3",
128
+ name: builtInHeadingStyleName(2),
118
129
  basedOn: "Normal",
119
130
  next: "Normal",
120
131
  qFormat: true,
@@ -130,13 +141,14 @@ function getDefaultStyles() {
130
141
  pPr: {
131
142
  spaceBefore: 320,
132
143
  spaceAfter: 80,
133
- lineSpacing: 240
144
+ lineSpacing: 240,
145
+ outlineLevel: 2
134
146
  }
135
147
  },
136
148
  {
137
149
  styleId: "Heading4",
138
150
  type: "paragraph",
139
- name: "Heading 4",
151
+ name: builtInHeadingStyleName(3),
140
152
  basedOn: "Normal",
141
153
  next: "Normal",
142
154
  qFormat: true,
@@ -152,6 +164,121 @@ function getDefaultStyles() {
152
164
  pPr: {
153
165
  spaceBefore: 280,
154
166
  spaceAfter: 80,
167
+ lineSpacing: 240,
168
+ outlineLevel: 3
169
+ }
170
+ },
171
+ {
172
+ styleId: "Heading5",
173
+ type: "paragraph",
174
+ name: builtInHeadingStyleName(4),
175
+ basedOn: "Normal",
176
+ next: "Normal",
177
+ qFormat: true,
178
+ uiPriority: 9,
179
+ rPr: {
180
+ fontSize: 22,
181
+ bold: true,
182
+ fontFamily: {
183
+ ascii: "Arial",
184
+ hAnsi: "Arial"
185
+ }
186
+ },
187
+ pPr: {
188
+ spaceBefore: 240,
189
+ spaceAfter: 80,
190
+ lineSpacing: 240,
191
+ outlineLevel: 4
192
+ }
193
+ },
194
+ {
195
+ styleId: "Heading6",
196
+ type: "paragraph",
197
+ name: builtInHeadingStyleName(5),
198
+ basedOn: "Normal",
199
+ next: "Normal",
200
+ qFormat: true,
201
+ uiPriority: 9,
202
+ rPr: {
203
+ fontSize: 22,
204
+ bold: true,
205
+ color: { rgb: "595959" },
206
+ fontFamily: {
207
+ ascii: "Arial",
208
+ hAnsi: "Arial"
209
+ }
210
+ },
211
+ pPr: {
212
+ spaceBefore: 240,
213
+ spaceAfter: 80,
214
+ lineSpacing: 240,
215
+ outlineLevel: 5
216
+ }
217
+ },
218
+ {
219
+ styleId: "TableNormal",
220
+ type: "table",
221
+ name: BUILT_IN_STYLE_NAME.normalTable,
222
+ uiPriority: 99,
223
+ semiHidden: true,
224
+ unhideWhenUsed: true
225
+ },
226
+ {
227
+ styleId: "TableGrid",
228
+ type: "table",
229
+ name: BUILT_IN_STYLE_NAME.tableGrid,
230
+ basedOn: "TableNormal",
231
+ uiPriority: 39,
232
+ tblPr: { borders: {
233
+ top: {
234
+ style: "single",
235
+ size: 4,
236
+ space: 0
237
+ },
238
+ bottom: {
239
+ style: "single",
240
+ size: 4,
241
+ space: 0
242
+ },
243
+ left: {
244
+ style: "single",
245
+ size: 4,
246
+ space: 0
247
+ },
248
+ right: {
249
+ style: "single",
250
+ size: 4,
251
+ space: 0
252
+ },
253
+ insideH: {
254
+ style: "single",
255
+ size: 4,
256
+ space: 0
257
+ },
258
+ insideV: {
259
+ style: "single",
260
+ size: 4,
261
+ space: 0
262
+ }
263
+ } }
264
+ },
265
+ {
266
+ styleId: "Quote",
267
+ type: "paragraph",
268
+ name: BUILT_IN_STYLE_NAME.quote,
269
+ basedOn: "Normal",
270
+ next: "Normal",
271
+ qFormat: true,
272
+ uiPriority: 29,
273
+ rPr: {
274
+ italic: true,
275
+ color: { rgb: "404040" }
276
+ },
277
+ pPr: {
278
+ indentLeft: 720,
279
+ indentRight: 720,
280
+ spaceBefore: 160,
281
+ spaceAfter: 160,
155
282
  lineSpacing: 240
156
283
  }
157
284
  }
@@ -203,9 +330,10 @@ function getDefaultSectionProperties() {
203
330
  * ```
204
331
  */
205
332
  function createEmptyDocument(options = {}) {
206
- const styleSet = options.preset?.styleSet ?? options.styleSet;
207
- validateDocumentStyleSet(styleSet);
333
+ const suppliedStyleSet = options.preset?.styleSet ?? options.styleSet;
208
334
  if (options.preset?.version !== void 0 && options.preset.version !== 1) return panic(`Unsupported document preset version: ${options.preset.version}`);
335
+ const { context: styleSetContext, warnings: styleSetWarnings } = createParseWarningCollector(STYLE_SET_PART);
336
+ const styleSet = suppliedStyleSet === void 0 ? void 0 : normalizeDocumentStyleSet(suppliedStyleSet, styleSetContext);
209
337
  const sectionProps = structuredClone(options.preset?.sectionProperties ?? getDefaultSectionProperties());
210
338
  if (options.pageWidth !== void 0) sectionProps.pageWidth = Math.round(options.pageWidth);
211
339
  if (options.pageHeight !== void 0) sectionProps.pageHeight = Math.round(options.pageHeight);
@@ -253,18 +381,15 @@ function createEmptyDocument(options = {}) {
253
381
  if (styleSet?.theme) docxPackage.theme = structuredClone(styleSet.theme);
254
382
  if (styleSet?.fontTable) docxPackage.fontTable = structuredClone(styleSet.fontTable);
255
383
  if (styleSet?.settings) docxPackage.settings = structuredClone(styleSet.settings);
256
- return {
384
+ const parseWarnings = styleSetWarnings();
385
+ const document = {
257
386
  package: docxPackage,
258
387
  templateVariables: [],
259
- warnings: []
388
+ warnings: formatParseWarnings(parseWarnings)
260
389
  };
390
+ if (parseWarnings.length > 0) document.parseWarnings = parseWarnings;
391
+ return document;
261
392
  }
262
- const validateDocumentStyleSet = (styleSet) => {
263
- if (!styleSet) return;
264
- if (styleSet.version !== 1) return panic(`Unsupported document style set version: ${styleSet.version}`);
265
- if (styleSet.name.trim().length === 0) return panic("Document style set name cannot be empty");
266
- if (styleSet.styles.styles.find((style) => style.styleId === styleSet.initialParagraphStyleId)?.type !== "paragraph") return panic(`Initial paragraph style "${styleSet.initialParagraphStyleId}" is missing from style set "${styleSet.name}"`);
267
- };
268
393
  /**
269
394
  * Create a document with a single paragraph containing the given text
270
395
  *
@@ -1,3 +1,4 @@
1
+ import { BuiltInStyleIndex } from "../docx/builtInStyles.js";
1
2
  import { Node } from "prosemirror-model";
2
3
  //#region src/utils/headingCollector.d.ts
3
4
  /**
@@ -14,12 +15,14 @@ type HeadingInfo = {
14
15
  pageNumber?: number | null;
15
16
  };
16
17
  /**
17
- * Collect all headings from a ProseMirror document.
18
+ * Collect all headings from a ProseMirror document, in document order.
18
19
  *
19
- * Detection logic:
20
- * 1. Check `outlineLevel` attr (set by OOXML parsing or style resolution)
21
- * 2. Fallback to `styleId` matching /^[Hh]eading(\d)$/
20
+ * Classification is {@link resolveHeadingLevel}'s: the paragraph's effective
21
+ * outline level, else the style's built-in `w:name`. Pass the open document's
22
+ * index (`styleResolver.builtInStyles`) so a localized style id such as
23
+ * `Nadpis1` or `berschrift1` resolves through its name rather than falling out
24
+ * of the outline.
22
25
  */
23
- declare function collectHeadings(doc: Node): HeadingInfo[];
26
+ declare function collectHeadings(doc: Node, styles: BuiltInStyleIndex): HeadingInfo[];
24
27
  //#endregion
25
28
  export { HeadingInfo, collectHeadings };
@@ -1,34 +1,32 @@
1
+ import { resolveHeadingLevel } from "../docx/builtInStyles.js";
1
2
  //#region src/utils/headingCollector.ts
2
3
  /**
3
- * Collect all headings from a ProseMirror document.
4
+ * Collect all headings from a ProseMirror document, in document order.
4
5
  *
5
- * Detection logic:
6
- * 1. Check `outlineLevel` attr (set by OOXML parsing or style resolution)
7
- * 2. Fallback to `styleId` matching /^[Hh]eading(\d)$/
6
+ * Classification is {@link resolveHeadingLevel}'s: the paragraph's effective
7
+ * outline level, else the style's built-in `w:name`. Pass the open document's
8
+ * index (`styleResolver.builtInStyles`) so a localized style id such as
9
+ * `Nadpis1` or `berschrift1` resolves through its name rather than falling out
10
+ * of the outline.
8
11
  */
9
- function collectHeadings(doc) {
12
+ function collectHeadings(doc, styles) {
10
13
  const headings = [];
11
14
  doc.descendants((node, pos) => {
12
- if (node.type.name === "paragraph") {
13
- const level = node.attrs["outlineLevel"];
14
- const styleId = node.attrs["styleId"];
15
- let effectiveLevel = level;
16
- if (effectiveLevel === null && styleId) {
17
- const match = /^[Hh]eading(?<level>\d)$/u.exec(styleId);
18
- if (match) effectiveLevel = Number.parseInt(match.groups["level"], 10) - 1;
19
- }
20
- if (effectiveLevel !== null && effectiveLevel >= 0 && effectiveLevel <= 8) {
21
- let text = "";
22
- node.forEach((child) => {
23
- if (child.isText) text += child.text || "";
24
- });
25
- if (text.trim()) headings.push({
26
- text: text.trim(),
27
- level: effectiveLevel,
28
- pmPos: pos
29
- });
30
- }
31
- }
15
+ if (node.type.name !== "paragraph") return;
16
+ const level = resolveHeadingLevel({
17
+ outlineLevel: node.attrs["outlineLevel"],
18
+ styleId: node.attrs["styleId"]
19
+ }, styles);
20
+ if (level === void 0) return;
21
+ let text = "";
22
+ node.forEach((child) => {
23
+ if (child.isText) text += child.text || "";
24
+ });
25
+ if (text.trim()) headings.push({
26
+ text: text.trim(),
27
+ level,
28
+ pmPos: pos
29
+ });
32
30
  });
33
31
  return headings;
34
32
  }
@@ -1,6 +1,13 @@
1
+ import { normalizeStyleName } from "../docx/builtInStyles.js";
1
2
  //#region src/utils/tableOfContentsStyle.ts
2
3
  const TABLE_OF_CONTENTS_STYLE_ID = /^TOC(?<level>\d*)$/iu;
3
- const TABLE_OF_CONTENTS_STYLE_NAME = /^toc\s+(?<level>\d+)$/iu;
4
+ /**
5
+ * Against an already-normalised name, so the same tolerance applies here as in
6
+ * `builtInStyles.ts`: the corpus carries `toc 1`, `TOC 1` and even `TOC 1`
7
+ * with a double space, and a producer that drops the space entirely would
8
+ * otherwise fall out.
9
+ */
10
+ const TABLE_OF_CONTENTS_STYLE_NAME = /^toc(?<level>\d+)$/u;
4
11
  const parsedLevel = (match) => {
5
12
  if (!match) return;
6
13
  const rawLevel = match.groups?.["level"];
@@ -9,6 +16,6 @@ const parsedLevel = (match) => {
9
16
  return Number.isSafeInteger(level) && level > 0 ? level : void 0;
10
17
  };
11
18
  /** Resolve a built-in TOC entry style without relying on its localized style id. */
12
- const tableOfContentsStyleLevel = ({ styleId, styleName }) => parsedLevel(TABLE_OF_CONTENTS_STYLE_ID.exec(styleId ?? "")) ?? parsedLevel(TABLE_OF_CONTENTS_STYLE_NAME.exec(styleName ?? ""));
19
+ const tableOfContentsStyleLevel = ({ styleId, styleName }) => parsedLevel(TABLE_OF_CONTENTS_STYLE_ID.exec(styleId ?? "")) ?? parsedLevel(TABLE_OF_CONTENTS_STYLE_NAME.exec(normalizeStyleName(styleName ?? "")));
13
20
  //#endregion
14
21
  export { tableOfContentsStyleLevel };
@@ -48,6 +48,15 @@ declare function emuToPixels(emu: number | undefined | null): number;
48
48
  * floating-point drift (e.g. 52 px → 495299.99999999994) out of the document.
49
49
  */
50
50
  declare function pixelsToEmu(px: number): number;
51
+ /**
52
+ * Convert EMUs to pixels for a stroke width.
53
+ *
54
+ * Strokes are sub-pixel, so unlike a box size they keep two decimals rather
55
+ * than rounding to whole pixels. The projection is still lossy: a consumer that
56
+ * has to write the document's own number back carries the authored EMU beside
57
+ * the pixels rather than converting these back.
58
+ */
59
+ declare function emuToStrokePixels(emu: number): number;
51
60
  /**
52
61
  * Convert EMUs to twips. Twips are integer-typed in OOXML; round here.
53
62
  */
@@ -96,4 +105,4 @@ declare function clamp(value: number, min: number, max: number): number;
96
105
  */
97
106
  declare function formatPx(px: number): string;
98
107
  //#endregion
99
- export { AUTO_PARAGRAPH_SPACING_PX, PIXELS_PER_INCH, TWIPS_PER_INCH, clamp, eighthsToPixels, emuToPixels, emuToTwips, formatPx, halfPointsToPixels, halfPointsToPoints, pixelsToEmu, pixelsToTwips, pointsToHalfPoints, pointsToPixels, roundPixels, twipsToEmu, twipsToPixels };
108
+ export { AUTO_PARAGRAPH_SPACING_PX, PIXELS_PER_INCH, TWIPS_PER_INCH, clamp, eighthsToPixels, emuToPixels, emuToStrokePixels, emuToTwips, formatPx, halfPointsToPixels, halfPointsToPoints, pixelsToEmu, pixelsToTwips, pointsToHalfPoints, pointsToPixels, roundPixels, twipsToEmu, twipsToPixels };
@@ -68,6 +68,17 @@ function pixelsToEmu(px) {
68
68
  return Math.round(px / 96 * EMUS_PER_INCH);
69
69
  }
70
70
  /**
71
+ * Convert EMUs to pixels for a stroke width.
72
+ *
73
+ * Strokes are sub-pixel, so unlike a box size they keep two decimals rather
74
+ * than rounding to whole pixels. The projection is still lossy: a consumer that
75
+ * has to write the document's own number back carries the authored EMU beside
76
+ * the pixels rather than converting these back.
77
+ */
78
+ function emuToStrokePixels(emu) {
79
+ return roundPixels(emu / EMUS_PER_INCH * 96);
80
+ }
81
+ /**
71
82
  * Convert EMUs to twips. Twips are integer-typed in OOXML; round here.
72
83
  */
73
84
  function emuToTwips(emu) {
@@ -136,4 +147,4 @@ function formatPx(px) {
136
147
  return `${roundPixels(px)}px`;
137
148
  }
138
149
  //#endregion
139
- export { AUTO_PARAGRAPH_SPACING_PX, PIXELS_PER_INCH, TWIPS_PER_INCH, clamp, eighthsToPixels, emuToPixels, emuToTwips, formatPx, halfPointsToPixels, halfPointsToPoints, pixelsToEmu, pixelsToTwips, pointsToHalfPoints, pointsToPixels, roundPixels, twipsToEmu, twipsToPixels };
150
+ export { AUTO_PARAGRAPH_SPACING_PX, PIXELS_PER_INCH, TWIPS_PER_INCH, clamp, eighthsToPixels, emuToPixels, emuToStrokePixels, emuToTwips, formatPx, halfPointsToPixels, halfPointsToPoints, pixelsToEmu, pixelsToTwips, pointsToHalfPoints, pointsToPixels, roundPixels, twipsToEmu, twipsToPixels };
@@ -2,6 +2,12 @@ import { sanitizeExternalUrl } from "@stll/docx-core";
2
2
  //#region src/utils/urlSecurity.d.ts
3
3
  declare function normalizeUserUrl(rawUrl: string): string;
4
4
  declare function isAllowedUserUrl(rawUrl: string): boolean;
5
- declare function sanitizeLinkTarget(target: string | undefined): string;
5
+ type AnchorTargetAttrs = {
6
+ target: string;
7
+ rel: string;
8
+ };
9
+ declare function anchorTargetAttrs(authoredFrame: string | undefined): AnchorTargetAttrs;
10
+ /** `window.open` features carrying the same guarantees as {@link ANCHOR_REL}. */
11
+ declare function windowFeaturesFor({ rel }: AnchorTargetAttrs): string;
6
12
  //#endregion
7
- export { isAllowedUserUrl, normalizeUserUrl, sanitizeExternalUrl, sanitizeLinkTarget };
13
+ export { AnchorTargetAttrs, anchorTargetAttrs, isAllowedUserUrl, normalizeUserUrl, sanitizeExternalUrl, windowFeaturesFor };
@@ -23,8 +23,26 @@ function normalizeUserUrl(rawUrl) {
23
23
  function isAllowedUserUrl(rawUrl) {
24
24
  return normalizeUserUrl(rawUrl) !== "";
25
25
  }
26
- function sanitizeLinkTarget(target) {
27
- return target && ALLOWED_TARGETS.has(target) ? target : "_blank";
26
+ /**
27
+ * The `target` and `rel` one authored frame may produce on a DOM anchor.
28
+ *
29
+ * A `w:tgtFrame` is a frame name, and a named frame addresses another browsing
30
+ * context: honouring an arbitrary one would let a document reach a frame it did
31
+ * not create. Every anchor and every navigation folio produces goes through
32
+ * here, so the clamp and the `rel` that must accompany `_blank` are decided
33
+ * once. The authored name itself stays in the model and is written back on
34
+ * save; clamping it at parse rewrote the document.
35
+ */
36
+ const ANCHOR_REL = "noopener noreferrer";
37
+ function anchorTargetAttrs(authoredFrame) {
38
+ return {
39
+ target: authoredFrame && ALLOWED_TARGETS.has(authoredFrame) ? authoredFrame : "_blank",
40
+ rel: ANCHOR_REL
41
+ };
42
+ }
43
+ /** `window.open` features carrying the same guarantees as {@link ANCHOR_REL}. */
44
+ function windowFeaturesFor({ rel }) {
45
+ return rel.replaceAll(" ", ",");
28
46
  }
29
47
  function findFirstPathSeparatorIndex(value) {
30
48
  return [
@@ -44,4 +62,4 @@ function startsWithPortSuffix(value) {
44
62
  return index > 0 && (index === value.length || "/?#".includes(value[index]));
45
63
  }
46
64
  //#endregion
47
- export { isAllowedUserUrl, normalizeUserUrl, sanitizeExternalUrl, sanitizeLinkTarget };
65
+ export { anchorTargetAttrs, isAllowedUserUrl, normalizeUserUrl, sanitizeExternalUrl, windowFeaturesFor };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stll/folio-core",
3
- "version": "0.43.0",
3
+ "version": "0.45.0",
4
4
  "description": "Headless, framework-neutral core of folio: the OOXML (.docx) parser, document model, ProseMirror integration, and page-layout engine. No React.",
5
5
  "keywords": [
6
6
  "document-model",
@@ -121,7 +121,7 @@
121
121
  "perf": "bun scripts/profile-editor.ts"
122
122
  },
123
123
  "dependencies": {
124
- "@stll/docx-core": "^0.21.0",
124
+ "@stll/docx-core": "^0.23.0",
125
125
  "@stll/docx-utils": "^0.1.0",
126
126
  "@stll/template-conditions": ">=0.4.0 <1.0.0",
127
127
  "better-result": "3.0.1",
@@ -1,4 +0,0 @@
1
- //#region src/docx/textWhitespace.d.ts
2
- declare const requiresXmlSpacePreserve: (text: string) => boolean;
3
- //#endregion
4
- export { requiresXmlSpacePreserve };
@@ -1,4 +0,0 @@
1
- //#region src/docx/textWhitespace.ts
2
- const requiresXmlSpacePreserve = (text) => text.startsWith(" ") || text.endsWith(" ") || text.includes(" ");
3
- //#endregion
4
- export { requiresXmlSpacePreserve };
@@ -1,6 +0,0 @@
1
- import { document_d_exports } from "../../types/document.js";
2
- //#region src/layout-bridge/engine/tableWidthUtils.d.ts
3
- declare function resolveTableWidthPx(width: number | undefined, widthType: document_d_exports.TableWidthType | undefined, containerWidth: number): number | undefined;
4
- declare function normalizeTableColumnWidths(widths: number[], columnCount: number, targetWidth: number): number[];
5
- //#endregion
6
- export { normalizeTableColumnWidths, resolveTableWidthPx };
@@ -1,25 +0,0 @@
1
- //#region src/layout-bridge/engine/tableWidthUtils.ts
2
- const TWIPS_PER_INCH = 1440;
3
- const PX_PER_INCH = 96;
4
- const PCT_DENOMINATOR = 5e3;
5
- const twipsToPixels = (twips) => twips / TWIPS_PER_INCH * PX_PER_INCH;
6
- function resolveTableWidthPx(width, widthType, containerWidth) {
7
- if (width === void 0 || width <= 0) return;
8
- if (widthType === "dxa") return twipsToPixels(width);
9
- if (widthType === "pct") return width / PCT_DENOMINATOR * containerWidth;
10
- }
11
- function normalizeTableColumnWidths(widths, columnCount, targetWidth) {
12
- if (columnCount <= 0) return [];
13
- if (widths.length === 0) return Array.from({ length: columnCount }, () => targetWidth / columnCount);
14
- const normalized = widths.slice(0, columnCount);
15
- const positives = normalized.filter((width) => width > 0);
16
- const fallback = positives.length > 0 ? positives.reduce((sum, width) => sum + width, 0) / positives.length : targetWidth / columnCount;
17
- while (normalized.length < columnCount) normalized.push(fallback);
18
- let fixedTotal = 0;
19
- for (const width of normalized) if (width > 0) fixedTotal += width;
20
- const missingCount = normalized.filter((width) => width <= 0).length;
21
- const missingWidth = missingCount > 0 ? Math.max(0, targetWidth - fixedTotal) / missingCount : 0;
22
- return normalized.map((width) => width > 0 ? width : missingWidth);
23
- }
24
- //#endregion
25
- export { normalizeTableColumnWidths, resolveTableWidthPx };
@@ -1,13 +0,0 @@
1
- //#region src/markdown/headings.d.ts
2
- /**
3
- * Heading-style detection from a paragraph style id. Ported from eigenpal
4
- * `agent/text-utils` (PR #595) so the markdown exporter stays self-contained
5
- * (folio has no `agent/text-utils` module). Word's built-in heading styles are
6
- * `Heading1`…`Heading9` (and localised aliases that still contain "heading").
7
- */
8
- /** True when the style id denotes a Word heading style. */
9
- declare function isHeadingStyle(styleId?: string): boolean;
10
- /** Extract the 1-based heading level from a style id, or undefined. */
11
- declare function parseHeadingLevel(styleId?: string): number | undefined;
12
- //#endregion
13
- export { isHeadingStyle, parseHeadingLevel };