@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
@@ -0,0 +1,64 @@
1
+ //#region src/prosemirror/authoredTransformAttrs.ts
2
+ /**
3
+ * The CSS the three authored values render as.
4
+ *
5
+ * Only what the browser has to draw: a rotation of zero and an explicit
6
+ * "not flipped" are the identity, and emitting them would put a no-op
7
+ * transform on every drawing that states one.
8
+ */
9
+ const cssTransform = (rotation, flipH, flipV) => {
10
+ const parts = [];
11
+ if (rotation !== null && rotation !== 0) parts.push(`rotate(${rotation}deg)`);
12
+ if (flipH === true) parts.push("scaleX(-1)");
13
+ if (flipV === true) parts.push("scaleY(-1)");
14
+ return parts.length > 0 ? parts.join(" ") : void 0;
15
+ };
16
+ /** Project a model transform onto a drawing node's attrs. */
17
+ const authoredTransformAttrs = (transform) => {
18
+ const docxRotation = transform?.rotation ?? null;
19
+ const docxFlipH = transform?.flipH ?? null;
20
+ const docxFlipV = transform?.flipV ?? null;
21
+ return {
22
+ docxFlipH,
23
+ docxFlipV,
24
+ docxRotation,
25
+ transform: cssTransform(docxRotation, docxFlipH, docxFlipV)
26
+ };
27
+ };
28
+ /**
29
+ * The transform a node persisted before these attrs existed carries.
30
+ *
31
+ * The CSS can state neither an authored zero rotation nor an authored "not
32
+ * flipped", which is why the attrs exist; such a node never carried them
33
+ * either, so reading it this way loses nothing.
34
+ */
35
+ const transformFromCss = (css) => {
36
+ if (!css) return;
37
+ const transform = {};
38
+ const rotateMatch = /rotate\((?<deg>[-\d.]+)deg\)/u.exec(css);
39
+ if (rotateMatch) {
40
+ const rotation = Number.parseFloat(rotateMatch.groups["deg"]);
41
+ if (Number.isFinite(rotation)) transform.rotation = rotation;
42
+ }
43
+ if (css.includes("scaleX(-1)")) transform.flipH = true;
44
+ if (css.includes("scaleY(-1)")) transform.flipV = true;
45
+ if (transform.rotation === void 0 && !transform.flipH && !transform.flipV) return;
46
+ return transform;
47
+ };
48
+ /**
49
+ * Read a drawing node's authored transform back.
50
+ *
51
+ * The attrs are the record; the CSS string answers only for a node that states
52
+ * none of them, which is how a node persisted before they existed arrives.
53
+ */
54
+ const readAuthoredTransform = (attrs) => {
55
+ const { docxFlipH, docxFlipV, docxRotation } = attrs;
56
+ if (docxRotation == null && docxFlipH == null && docxFlipV == null) return transformFromCss(attrs.transform);
57
+ return {
58
+ ...docxRotation == null ? {} : { rotation: docxRotation },
59
+ ...docxFlipH == null ? {} : { flipH: docxFlipH },
60
+ ...docxFlipV == null ? {} : { flipV: docxFlipV }
61
+ };
62
+ };
63
+ //#endregion
64
+ export { authoredTransformAttrs, readAuthoredTransform };
@@ -1,3 +1,4 @@
1
+ import { checkboxDisplayContent } from "../../content-controls/checkboxDisplay.js";
1
2
  import { ContentControlBoundError, ContentControlLockedError, ContentControlTypeError } from "../../content-controls/errors.js";
2
3
  import { formatDate } from "../../docx/fieldParser.js";
3
4
  import { expectBlockSdtAttrs } from "../attrs/index.js";
@@ -220,8 +221,15 @@ function setContentControlValueTr(state, filter, input, options = {}) {
220
221
  sdtType,
221
222
  reason: "kind=checkbox requires sdtType=checkbox"
222
223
  });
223
- const glyph = input.checked ? "☒" : "☐";
224
- return replaceBlockSdtChildren(state, match, [paragraphFromText(state.schema, glyph)], {
224
+ const display = checkboxDisplayContent(typeof match.node.attrs["rawPropertiesXml"] === "string" ? match.node.attrs["rawPropertiesXml"] : void 0, input.checked);
225
+ let content = display.type === "symbol" ? state.schema.node("symbol", {
226
+ font: display.font,
227
+ char: display.char
228
+ }) : state.schema.text(display.text);
229
+ const sourceParagraph = match.node.firstChild;
230
+ const sourceInline = sourceParagraph?.firstChild;
231
+ if (sourceInline && sourceInline.marks.length > 0) content = content.mark(sourceInline.marks);
232
+ return replaceBlockSdtChildren(state, match, [state.schema.node("paragraph", sourceParagraph?.type.name === "paragraph" ? sourceParagraph.attrs : {}, [content])], {
225
233
  checked: input.checked,
226
234
  ...bindingOverride
227
235
  });
@@ -1,3 +1,4 @@
1
+ import { document_d_exports } from "../../types/document.js";
1
2
  import { ImageAttrs, ImagePositionAttrs } from "../schema/nodes.js";
2
3
  import { EditorView } from "prosemirror-view";
3
4
  //#region src/prosemirror/commands/image.d.ts
@@ -31,8 +32,14 @@ type ResolvedImageWrap = {
31
32
  };
32
33
  /** Map a toolbar wrap selection to the image's wrapType/displayMode/cssFloat, or null when unknown. */
33
34
  declare const resolveImageWrap: (wrapType: string) => ResolvedImageWrap | null;
34
- /** The CSS transform after applying a rotate/flip action to the current transform string. */
35
- declare const computeImageTransform: (currentTransform: string, action: ImageTransformAction) => string | undefined;
35
+ /**
36
+ * The authored transform after applying a rotate/flip action.
37
+ *
38
+ * Every field the action decides is stated: rotating back to zero states zero,
39
+ * un-flipping states `false`. The editor is saying what the drawing is now, and
40
+ * leaving the field absent would hand the decision back to the file.
41
+ */
42
+ declare const computeImageTransform: (current: document_d_exports.ImageTransform | undefined, action: ImageTransformAction) => document_d_exports.ImageTransform;
36
43
  declare const normalizeImageHorizontalPosition: (data: ImagePositionInput["horizontal"]) => ImagePositionAttrs["horizontal"] | undefined;
37
44
  declare const normalizeImageVerticalPosition: (data: ImagePositionInput["vertical"]) => ImagePositionAttrs["vertical"] | undefined;
38
45
  /** Clamp an image's intrinsic size to the page text width, preserving aspect ratio. */
@@ -1,7 +1,9 @@
1
+ import { FOLIO_INSERTED_PICTURE_FRAME_LOCKS } from "../../docx/graphicFrameLocks.js";
1
2
  import { IMAGE_HORIZONTAL_ALIGNMENT_VALUES, IMAGE_HORIZONTAL_RELATIVE_TO_VALUES, IMAGE_VERTICAL_ALIGNMENT_VALUES, IMAGE_VERTICAL_RELATIVE_TO_VALUES } from "../../types/documentEnumValues.js";
2
3
  import { isSafeImageFile } from "../../utils/imageValidation.js";
3
4
  import { sanitizeImageSrc } from "../../utils/sanitizeImageSrc.js";
4
5
  import { expectImageAttrs, mergeImageAttrs } from "../attrs/index.js";
6
+ import { authoredTransformAttrs, readAuthoredTransform } from "../authoredTransformAttrs.js";
5
7
  //#region src/prosemirror/commands/image.ts
6
8
  /** Map a toolbar wrap selection to the image's wrapType/displayMode/cssFloat, or null when unknown. */
7
9
  const resolveImageWrap = (wrapType) => {
@@ -42,32 +44,44 @@ const resolveImageWrap = (wrapType) => {
42
44
  default: return null;
43
45
  }
44
46
  };
45
- /** The CSS transform after applying a rotate/flip action to the current transform string. */
46
- const computeImageTransform = (currentTransform, action) => {
47
- const rotateMatch = /rotate\((?<degrees>-?\d+(?:\.\d+)?)deg\)/u.exec(currentTransform);
48
- let rotation = rotateMatch ? Number.parseFloat(rotateMatch.groups["degrees"]) : 0;
49
- let hasFlipH = currentTransform.includes("scaleX(-1)");
50
- let hasFlipV = currentTransform.includes("scaleY(-1)");
47
+ const QUARTER_TURN = 90;
48
+ const FULL_TURN = 360;
49
+ /**
50
+ * The turn `degrees` names, in `[0, 360)`.
51
+ *
52
+ * `%` keeps the sign of its left operand in JavaScript, and an authored
53
+ * rotation may be negative, so a bare remainder answers `-270` where the
54
+ * drawing is at `90`.
55
+ */
56
+ const withinOneTurn = (degrees) => (degrees % FULL_TURN + FULL_TURN) % FULL_TURN;
57
+ /**
58
+ * The authored transform after applying a rotate/flip action.
59
+ *
60
+ * Every field the action decides is stated: rotating back to zero states zero,
61
+ * un-flipping states `false`. The editor is saying what the drawing is now, and
62
+ * leaving the field absent would hand the decision back to the file.
63
+ */
64
+ const computeImageTransform = (current, action) => {
65
+ const rotation = current?.rotation ?? 0;
51
66
  switch (action) {
52
- case "rotateCW":
53
- rotation = (rotation + 90) % 360;
54
- break;
55
- case "rotateCCW":
56
- rotation = (rotation - 90 + 360) % 360;
57
- break;
58
- case "flipH":
59
- hasFlipH = !hasFlipH;
60
- break;
61
- case "flipV":
62
- hasFlipV = !hasFlipV;
63
- break;
64
- default: break;
67
+ case "rotateCW": return {
68
+ ...current,
69
+ rotation: withinOneTurn(rotation + QUARTER_TURN)
70
+ };
71
+ case "rotateCCW": return {
72
+ ...current,
73
+ rotation: withinOneTurn(rotation - QUARTER_TURN)
74
+ };
75
+ case "flipH": return {
76
+ ...current,
77
+ flipH: current?.flipH !== true
78
+ };
79
+ case "flipV": return {
80
+ ...current,
81
+ flipV: current?.flipV !== true
82
+ };
83
+ default: return action;
65
84
  }
66
- const parts = [];
67
- if (rotation !== 0) parts.push(`rotate(${rotation}deg)`);
68
- if (hasFlipH) parts.push("scaleX(-1)");
69
- if (hasFlipV) parts.push("scaleY(-1)");
70
- return parts.length > 0 ? parts.join(" ") : void 0;
71
85
  };
72
86
  const isOneOf = (value, values) => value !== void 0 && values.some((allowed) => allowed === value);
73
87
  const normalizeImageHorizontalPosition = (data) => {
@@ -126,9 +140,8 @@ const applyImageWrapType = (view, pos, wrapType) => {
126
140
  const applyImageTransform = (view, pos, action) => {
127
141
  const node = imageNodeAt(view, pos);
128
142
  if (!node) return false;
129
- const currentTransform = expectImageAttrs(node).transform ?? "";
130
- const transform = computeImageTransform(currentTransform, action);
131
- const tr = view.state.tr.setNodeMarkup(pos, void 0, mergeImageAttrs(node, { transform }));
143
+ const transform = computeImageTransform(readAuthoredTransform(expectImageAttrs(node)), action);
144
+ const tr = view.state.tr.setNodeMarkup(pos, void 0, mergeImageAttrs(node, authoredTransformAttrs(transform)));
132
145
  view.dispatch(tr.scrollIntoView());
133
146
  return true;
134
147
  };
@@ -179,12 +192,14 @@ const insertImageFromFile = async (view, file, onInserted) => {
179
192
  if (!imageType) return;
180
193
  const imageNode = imageType.create({
181
194
  src: dataUrl,
195
+ docPrName: file.name,
182
196
  alt: file.name,
183
197
  width: constrained.width,
184
198
  height: constrained.height,
185
199
  rId: `rId_img_${Date.now()}`,
186
200
  wrapType: "inline",
187
- displayMode: "inline"
201
+ displayMode: "inline",
202
+ frameLocks: FOLIO_INSERTED_PICTURE_FRAME_LOCKS
188
203
  });
189
204
  const { from } = view.state.selection;
190
205
  const tr = view.state.tr.insert(from, imageNode);
@@ -29,7 +29,7 @@ const insertPageBreak = (state, dispatch) => {
29
29
  const { $from } = state.selection;
30
30
  if (!pageBreakRunType || !state.selection.empty || !$from.parent.isTextblock) return false;
31
31
  for (let depth = $from.depth; depth >= 0; depth--) if (UNSUPPORTED_PAGE_BREAK_RUN_ANCESTORS.has($from.node(depth).type.name)) return false;
32
- if ($from.parent.type.name !== "paragraph" || pageBreakRunParagraphProjectionDisposition($from.parent).status === "unsupported" || hasTextBoxAnchorAtOrAfter($from.parent, $from.start(), $from.pos)) return false;
32
+ if ($from.parent.type.name !== "paragraph" || pageBreakRunParagraphProjectionDisposition($from.parent).status === "approximate" || hasTextBoxAnchorAtOrAfter($from.parent, $from.start(), $from.pos)) return false;
33
33
  if (dispatch) {
34
34
  const pageBreak = pageBreakRunType.create();
35
35
  dispatch(state.tr.replaceSelectionWith(pageBreak).scrollIntoView());
@@ -0,0 +1,8 @@
1
+ import { CommentReferenceAttrs } from "./schema/nodes.js";
2
+ import { ReadProseMirrorAttrsResult } from "./attrs/index.js";
3
+ import { Node } from "prosemirror-model";
4
+ //#region src/prosemirror/commentReferenceAttrs.d.ts
5
+ declare const readCommentReferenceAttrs: (node: Node) => ReadProseMirrorAttrsResult<CommentReferenceAttrs>;
6
+ declare const expectCommentReferenceAttrs: (node: Node) => CommentReferenceAttrs;
7
+ //#endregion
8
+ export { expectCommentReferenceAttrs, readCommentReferenceAttrs };
@@ -0,0 +1,33 @@
1
+ import { panic } from "better-result";
2
+ //#region src/prosemirror/commentReferenceAttrs.ts
3
+ const attrsCache = /* @__PURE__ */ new WeakMap();
4
+ const readCommentReferenceAttrs = (node) => {
5
+ const issues = [];
6
+ if (node.type.name !== "commentReference") issues.push({
7
+ path: "commentReference.type.name",
8
+ message: `Expected commentReference, got ${node.type.name}.`
9
+ });
10
+ const commentId = node.attrs["commentId"];
11
+ if (typeof commentId !== "number" || !Number.isInteger(commentId) || commentId < 0) issues.push({
12
+ path: "commentReference.attrs.commentId",
13
+ message: "Expected a non-negative integer."
14
+ });
15
+ if (issues.length > 0 || typeof commentId !== "number") return {
16
+ ok: false,
17
+ issues
18
+ };
19
+ return {
20
+ ok: true,
21
+ value: { commentId }
22
+ };
23
+ };
24
+ const expectCommentReferenceAttrs = (node) => {
25
+ const cached = attrsCache.get(node);
26
+ if (cached) return cached;
27
+ const result = readCommentReferenceAttrs(node);
28
+ if (!result.ok) panic(`Invalid ProseMirror comment reference attrs:\n${result.issues.map((issue) => `${issue.path}: ${issue.message}`).join("\n")}`);
29
+ attrsCache.set(node, result.value);
30
+ return result.value;
31
+ };
32
+ //#endregion
33
+ export { expectCommentReferenceAttrs, readCommentReferenceAttrs };
@@ -0,0 +1,47 @@
1
+ //#region src/prosemirror/commentReferenceIntegrity.d.ts
2
+ /**
3
+ * What a document must hold for every comment: exactly one `commentReference`
4
+ * node, after the last position its `comment` mark covers.
5
+ *
6
+ * The reference is the run Word paints the visible comment mark with, so a
7
+ * comment without one is invisible in Word and a duplicate paints the mark
8
+ * twice. Editing cannot be trusted to keep that true — a paste duplicates a
9
+ * reference, deleting the commented text orphans one, and a command that adds
10
+ * a comment mark creates none — so the repair is computed here and applied by
11
+ * the extension's `appendTransaction`, rather than left to each call site.
12
+ */
13
+ type CommentReferenceOccurrence = {
14
+ commentId: number;
15
+ position: number;
16
+ /** Node size, so a caller can delete the node without re-reading it. */
17
+ size: number;
18
+ malformed: boolean;
19
+ };
20
+ /** Where a comment's mark last covers content, and how far that content runs. */
21
+ type CommentMarkExtent = {
22
+ commentId: number;
23
+ /** Document position just past the last inline node carrying the mark. */
24
+ end: number;
25
+ };
26
+ type CommentReferenceRepair = {
27
+ type: "delete";
28
+ position: number;
29
+ size: number;
30
+ } | {
31
+ type: "insert";
32
+ position: number;
33
+ commentId: number;
34
+ };
35
+ type CommentReferenceRepairInput = {
36
+ references: readonly CommentReferenceOccurrence[];
37
+ markExtents: readonly CommentMarkExtent[];
38
+ };
39
+ /**
40
+ * The repairs that make a document total, as positions in the document they
41
+ * were read from. Deletions come first, last-first, so they apply in sequence
42
+ * without mapping; the insertions that follow still carry pre-repair positions
43
+ * and the applier maps them through the transaction.
44
+ */
45
+ declare const planCommentReferenceRepairs: ({ references, markExtents }: CommentReferenceRepairInput) => readonly CommentReferenceRepair[];
46
+ //#endregion
47
+ export { CommentMarkExtent, CommentReferenceOccurrence, CommentReferenceRepair, planCommentReferenceRepairs };
@@ -0,0 +1,43 @@
1
+ //#region src/prosemirror/commentReferenceIntegrity.ts
2
+ /**
3
+ * The repairs that make a document total, as positions in the document they
4
+ * were read from. Deletions come first, last-first, so they apply in sequence
5
+ * without mapping; the insertions that follow still carry pre-repair positions
6
+ * and the applier maps them through the transaction.
7
+ */
8
+ const planCommentReferenceRepairs = ({ references, markExtents }) => {
9
+ const markedIds = new Set(markExtents.map(({ commentId }) => commentId));
10
+ const deletions = [];
11
+ const keptIds = /* @__PURE__ */ new Set();
12
+ for (const reference of references) {
13
+ if (reference.malformed || !markedIds.has(reference.commentId)) {
14
+ deletions.push({
15
+ type: "delete",
16
+ position: reference.position,
17
+ size: reference.size
18
+ });
19
+ continue;
20
+ }
21
+ if (keptIds.has(reference.commentId)) {
22
+ deletions.push({
23
+ type: "delete",
24
+ position: reference.position,
25
+ size: reference.size
26
+ });
27
+ continue;
28
+ }
29
+ keptIds.add(reference.commentId);
30
+ }
31
+ const insertions = [];
32
+ for (const { commentId, end } of markExtents) {
33
+ if (keptIds.has(commentId)) continue;
34
+ insertions.push({
35
+ type: "insert",
36
+ position: end,
37
+ commentId
38
+ });
39
+ }
40
+ return [...deletions.toSorted((first, second) => second.position - first.position), ...insertions.toSorted((first, second) => second.position - first.position)];
41
+ };
42
+ //#endregion
43
+ export { planCommentReferenceRepairs };
@@ -5,14 +5,6 @@ import { Mark, Node } from "prosemirror-model";
5
5
  //#region src/prosemirror/conversion/fromProseDoc.d.ts
6
6
  /** Convert a ProseMirror document to the document model. */
7
7
  declare function fromProseDoc(pmDoc: Node, baseDocument?: document_d_exports.Document): document_d_exports.Document;
8
- /**
9
- * What a field carrying no stored result reports.
10
- *
11
- * `serializerFallback` writes the visible page number a save has always given a
12
- * result-less PAGE/NUMPAGES field; `authored` reports the result the document
13
- * actually holds, so a text read of a story reads the same loaded and unloaded.
14
- */
15
- type EmptyFieldResultMode = "serializerFallback" | "authored";
16
8
  /**
17
9
  * Convert ProseMirror marks to TextFormatting
18
10
  */
@@ -36,9 +28,6 @@ declare function tableCellAttrsToFormatting(attrs: TableCellAttrs): document_d_e
36
28
  * Preserves all non-content parts of the original document
37
29
  */
38
30
  declare function updateDocumentContent(originalDocument: document_d_exports.Document, pmDoc: Node): document_d_exports.Document;
39
- type ProseDocToBlocksOptions = {
40
- emptyFieldResult?: EmptyFieldResultMode;
41
- };
42
31
  /**
43
32
  * Convert a ProseMirror document back to an array of `BlockContent` blocks
44
33
  * (paragraphs, tables, and block-level content controls).
@@ -46,6 +35,6 @@ type ProseDocToBlocksOptions = {
46
35
  * Used for converting edited header/footer PM content back to the document
47
36
  * model.
48
37
  */
49
- declare function proseDocToBlocks(pmDoc: Node, baseContent?: document_d_exports.BlockContent[], styles?: NonNullable<document_d_exports.Document["package"]>["styles"], options?: ProseDocToBlocksOptions): document_d_exports.BlockContent[];
38
+ declare function proseDocToBlocks(pmDoc: Node, baseContent?: document_d_exports.BlockContent[], styles?: NonNullable<document_d_exports.Document["package"]>["styles"]): document_d_exports.BlockContent[];
50
39
  //#endregion
51
- export { EmptyFieldResultMode, ProseDocToBlocksOptions, fromProseDoc, marksToTextFormatting, proseDocToBlocks, standaloneTableCellFromProseMirror, tableAttrsToFormatting, tableCellAttrsToFormatting, tableRowAttrsToFormatting, updateDocumentContent };
40
+ export { fromProseDoc, marksToTextFormatting, proseDocToBlocks, standaloneTableCellFromProseMirror, tableAttrsToFormatting, tableCellAttrsToFormatting, tableRowAttrsToFormatting, updateDocumentContent };