@stll/folio-core 0.45.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 (207) hide show
  1. package/dist/ai-edits/apply.js +59 -19
  2. package/dist/ai-edits/headless.js +1 -1
  3. package/dist/compare/compare.js +2 -5
  4. package/dist/compare/scenario.js +2 -5
  5. package/dist/compare/types.d.ts +9 -1
  6. package/dist/compare/types.js +12 -1
  7. package/dist/compat/eigenpal.d.ts +2 -1
  8. package/dist/compat/eigenpal.js +2 -1
  9. package/dist/content-controls/checkboxDisplay.d.ts +11 -0
  10. package/dist/content-controls/checkboxDisplay.js +40 -0
  11. package/dist/content-controls/findContentControls.js +3 -1
  12. package/dist/content-controls/mutateContentControls.js +17 -2
  13. package/dist/controller/contentControlWidgetController.d.ts +1 -0
  14. package/dist/controller/contentControlWidgetController.js +3 -0
  15. package/dist/controller/hiddenEditorApi.js +3 -1
  16. package/dist/controller/hiddenEditorManager.d.ts +1 -1
  17. package/dist/controller/hiddenEditorManager.js +6 -3
  18. package/dist/display-list/build/buildDisplayList.js +20 -1
  19. package/dist/display-list/build/imagePrimitives.d.ts +1 -1
  20. package/dist/display-list/build/imagePrimitives.js +3 -1
  21. package/dist/display-list/build/paragraphPrimitives.js +21 -2
  22. package/dist/display-list/dom/renderDisplayListToDom.js +10 -2
  23. package/dist/display-list/types.d.ts +17 -0
  24. package/dist/docx/attributeRemainder.d.ts +43 -0
  25. package/dist/docx/attributeRemainder.js +65 -0
  26. package/dist/docx/blockContentParser.d.ts +1 -1
  27. package/dist/docx/blockContentParser.js +87 -63
  28. package/dist/docx/blockPlainText.d.ts +3 -4
  29. package/dist/docx/blockPlainText.js +1 -0
  30. package/dist/docx/bookmarkPlacement.js +2 -0
  31. package/dist/docx/commentAnchorIndex.d.ts +30 -0
  32. package/dist/docx/commentAnchorIndex.js +50 -0
  33. package/dist/docx/commentParser.d.ts +1 -1
  34. package/dist/docx/commentParser.js +54 -37
  35. package/dist/docx/commentRangeIntegrity.d.ts +16 -1
  36. package/dist/docx/commentRangeIntegrity.js +42 -1
  37. package/dist/docx/commentRangeJoin.d.ts +9 -0
  38. package/dist/docx/commentRangeJoin.js +33 -0
  39. package/dist/docx/commentReferenceCompletion.d.ts +9 -0
  40. package/dist/docx/commentReferenceCompletion.js +47 -0
  41. package/dist/docx/commentReferenceNormalization.js +1 -0
  42. package/dist/docx/commentReplyMarkers.js +11 -19
  43. package/dist/docx/compatibility.js +1 -0
  44. package/dist/docx/containerChildren.d.ts +111 -0
  45. package/dist/docx/containerChildren.gen.d.ts +28 -0
  46. package/dist/docx/containerChildren.gen.js +246 -0
  47. package/dist/docx/containerChildren.js +103 -0
  48. package/dist/docx/documentParser.d.ts +1 -1
  49. package/dist/docx/documentParser.js +3 -3
  50. package/dist/docx/ensureParaIds.js +17 -7
  51. package/dist/docx/fieldParser.d.ts +1 -1
  52. package/dist/docx/fieldParser.js +4 -4
  53. package/dist/docx/fieldState.d.ts +26 -0
  54. package/dist/docx/fieldState.js +53 -0
  55. package/dist/docx/footnoteParser.d.ts +1 -1
  56. package/dist/docx/graphicFrameLocks.d.ts +16 -4
  57. package/dist/docx/graphicFrameLocks.js +19 -6
  58. package/dist/docx/headerFooterParser.js +1 -1
  59. package/dist/docx/headerFooterReferenceNormalization.js +1 -0
  60. package/dist/docx/hyperlinkParser.d.ts +27 -8
  61. package/dist/docx/hyperlinkParser.js +76 -18
  62. package/dist/docx/imageParser.js +33 -8
  63. package/dist/docx/inlineWrapperContent.d.ts +85 -0
  64. package/dist/docx/inlineWrapperContent.js +84 -0
  65. package/dist/docx/normalizeBaseDirection.js +10 -1
  66. package/dist/docx/paraIdAttribute.d.ts +21 -0
  67. package/dist/docx/paraIdAttribute.js +64 -0
  68. package/dist/docx/paragraphParser.d.ts +1 -1
  69. package/dist/docx/paragraphParser.js +277 -168
  70. package/dist/docx/paragraphPropertySource.js +5 -1
  71. package/dist/docx/paragraphTextBoxEnrichment.d.ts +1 -1
  72. package/dist/docx/paragraphTextBoxEnrichment.js +6 -52
  73. package/dist/docx/paragraphTraversal.js +7 -4
  74. package/dist/docx/parseWarningMessage.js +2 -1
  75. package/dist/docx/preservedRunContent.d.ts +32 -0
  76. package/dist/docx/preservedRunContent.js +86 -0
  77. package/dist/docx/renderedPageBreakNormalization.js +2 -4
  78. package/dist/docx/rezip.js +74 -18
  79. package/dist/docx/runParser.d.ts +1 -1
  80. package/dist/docx/runParser.js +16 -12
  81. package/dist/docx/sectionParser.js +8 -1
  82. package/dist/docx/selectiveXmlPatch.d.ts +46 -2
  83. package/dist/docx/selectiveXmlPatch.js +86 -39
  84. package/dist/docx/serializer/borderSerializer.js +2 -2
  85. package/dist/docx/serializer/commentSerializer.js +5 -7
  86. package/dist/docx/serializer/documentSerializer.js +8 -11
  87. package/dist/docx/serializer/headerFooterSerializer.js +7 -9
  88. package/dist/docx/serializer/noteSerializer.js +8 -8
  89. package/dist/docx/serializer/paragraphSerializer.js +76 -56
  90. package/dist/docx/serializer/runSerializer.js +25 -16
  91. package/dist/docx/serializer/sectionPropertiesSerializer.js +8 -4
  92. package/dist/docx/serializer/tableSerializer.js +18 -8
  93. package/dist/docx/server/createBilingualDocument.js +3 -1
  94. package/dist/docx/server/materializeYjsDocx.d.ts +1 -1
  95. package/dist/docx/server/materializeYjsDocx.js +9 -1
  96. package/dist/docx/server/migrateYjsAttrSchema.d.ts +55 -0
  97. package/dist/docx/server/migrateYjsAttrSchema.js +95 -0
  98. package/dist/docx/shapeParser.js +5 -5
  99. package/dist/docx/tableParser.d.ts +1 -1
  100. package/dist/docx/tableParser.js +206 -85
  101. package/dist/docx/textBoxParser.d.ts +25 -2
  102. package/dist/docx/textBoxParser.js +52 -2
  103. package/dist/docx/unzip.js +5 -4
  104. package/dist/docx/vmlImageParser.d.ts +17 -1
  105. package/dist/docx/vmlImageParser.js +17 -1
  106. package/dist/docx/xmlEncoding.d.ts +5 -0
  107. package/dist/docx/xmlEncoding.js +12 -0
  108. package/dist/docx/xmlParser.d.ts +10 -1
  109. package/dist/docx/xmlParser.js +14 -1
  110. package/dist/headless-layout.js +10 -1
  111. package/dist/index.d.ts +2 -1
  112. package/dist/index.js +2 -1
  113. package/dist/internal/pageBreakRunSourceDescendantIndex.js +5 -2
  114. package/dist/layout-bridge/convert/toFlowBlocks.js +102 -12
  115. package/dist/layout-engine/measure/tableCellFloating.d.ts +2 -0
  116. package/dist/layout-engine/measure/tableCellFloating.js +2 -0
  117. package/dist/layout-engine/types.d.ts +23 -1
  118. package/dist/layout-painter/renderImage.d.ts +5 -1
  119. package/dist/layout-painter/renderImage.js +10 -3
  120. package/dist/layout-painter/renderPage.d.ts +2 -0
  121. package/dist/layout-painter/renderPage.js +4 -0
  122. package/dist/layout-painter/renderParagraph.d.ts +13 -1
  123. package/dist/layout-painter/renderParagraph.js +22 -3
  124. package/dist/managers/autoSaveCodec.d.ts +9 -1
  125. package/dist/managers/autoSaveCodec.js +12 -4
  126. package/dist/markdown/renderBlock.js +1 -0
  127. package/dist/markdown/renderRuns.d.ts +1 -1
  128. package/dist/markdown/renderRuns.js +28 -5
  129. package/dist/markdown/renderTable.js +22 -5
  130. package/dist/markdown/trailers.js +4 -1
  131. package/dist/pdf/images.js +142 -6
  132. package/dist/prosemirror/attrs/index.d.ts +14 -3
  133. package/dist/prosemirror/attrs/index.js +155 -2
  134. package/dist/prosemirror/authoredTransformAttrs.d.ts +28 -0
  135. package/dist/prosemirror/authoredTransformAttrs.js +64 -0
  136. package/dist/prosemirror/commands/contentControls.js +10 -2
  137. package/dist/prosemirror/commands/image.d.ts +9 -2
  138. package/dist/prosemirror/commands/image.js +42 -28
  139. package/dist/prosemirror/commands/pageBreak.js +1 -1
  140. package/dist/prosemirror/commentReferenceAttrs.d.ts +8 -0
  141. package/dist/prosemirror/commentReferenceAttrs.js +33 -0
  142. package/dist/prosemirror/commentReferenceIntegrity.d.ts +47 -0
  143. package/dist/prosemirror/commentReferenceIntegrity.js +43 -0
  144. package/dist/prosemirror/conversion/fromProseDoc.d.ts +2 -13
  145. package/dist/prosemirror/conversion/fromProseDoc.js +269 -70
  146. package/dist/prosemirror/conversion/index.d.ts +2 -2
  147. package/dist/prosemirror/conversion/toProseDoc.d.ts +7 -9
  148. package/dist/prosemirror/conversion/toProseDoc.js +468 -308
  149. package/dist/prosemirror/extensions/StarterKit.js +8 -58
  150. package/dist/prosemirror/extensions/core/DocExtension.js +1 -1
  151. package/dist/prosemirror/extensions/core/ParagraphExtension.js +2 -1
  152. package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +45 -27
  153. package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.js +3 -1
  154. package/dist/prosemirror/extensions/features/ImagePasteExtension.js +5 -3
  155. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +1 -0
  156. package/dist/prosemirror/extensions/markRegistry.d.ts +41 -0
  157. package/dist/prosemirror/extensions/markRegistry.js +75 -0
  158. package/dist/prosemirror/extensions/marks/InlineWrapperExtension.d.ts +18 -0
  159. package/dist/prosemirror/extensions/marks/InlineWrapperExtension.js +63 -0
  160. package/dist/prosemirror/extensions/marks/markUtils.d.ts +2 -1
  161. package/dist/prosemirror/extensions/marks/markUtils.js +47 -4
  162. package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.d.ts +11 -0
  163. package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +87 -0
  164. package/dist/prosemirror/extensions/nodes/FieldExtension.js +9 -7
  165. package/dist/prosemirror/extensions/nodes/ImageExtension.js +16 -0
  166. package/dist/prosemirror/extensions/nodes/PreservedBlockExtension.d.ts +32 -0
  167. package/dist/prosemirror/extensions/nodes/PreservedBlockExtension.js +67 -0
  168. package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.d.ts +16 -0
  169. package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.js +60 -0
  170. package/dist/prosemirror/extensions/nodes/ShapeExtension.js +3 -0
  171. package/dist/prosemirror/extensions/nodes/TableExtension.js +3 -2
  172. package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +5 -1
  173. package/dist/prosemirror/inlineWrapperStack.d.ts +39 -0
  174. package/dist/prosemirror/inlineWrapperStack.js +75 -0
  175. package/dist/prosemirror/pageBreakRunProjection.d.ts +17 -7
  176. package/dist/prosemirror/pageBreakRunProjection.js +19 -9
  177. package/dist/prosemirror/replacedAnnotations.d.ts +59 -0
  178. package/dist/prosemirror/replacedAnnotations.js +165 -0
  179. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +3 -1
  180. package/dist/prosemirror/runFormattingInlineCarriers.js +5 -1
  181. package/dist/prosemirror/schema/index.d.ts +3 -3
  182. package/dist/prosemirror/schema/marks.d.ts +25 -1
  183. package/dist/prosemirror/schema/nodes.d.ts +90 -3
  184. package/dist/prosemirror/schema/nodes.js +16 -1
  185. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +2 -0
  186. package/dist/prosemirror/trackedRunInlineAtoms.js +2 -0
  187. package/dist/prosemirror/validation.js +16 -2
  188. package/dist/prosemirror/yjsDocumentMetadata.d.ts +73 -0
  189. package/dist/prosemirror/yjsDocumentMetadata.js +171 -0
  190. package/dist/prosemirror/zeroWidthAnchors.js +2 -0
  191. package/dist/render-dom/commentAnchorAttributes.d.ts +37 -0
  192. package/dist/render-dom/commentAnchorAttributes.js +54 -0
  193. package/dist/server.d.ts +3 -1
  194. package/dist/server.js +3 -1
  195. package/dist/types/content.d.ts +2 -2
  196. package/dist/utils/clipboard.d.ts +9 -1
  197. package/dist/utils/clipboard.js +27 -1
  198. package/dist/utils/findReplace.js +1 -1
  199. package/dist/utils/imageLuminance.d.ts +15 -0
  200. package/dist/utils/imageLuminance.js +32 -0
  201. package/dist/utils/mergeDocumentContent.js +7 -17
  202. package/dist/utils/replaceText.js +1 -0
  203. package/package.json +2 -2
  204. package/dist/docx/blockRangeMarkers.d.ts +0 -36
  205. package/dist/docx/blockRangeMarkers.js +0 -59
  206. package/dist/prosemirror/yjsParagraphSourceContract.d.ts +0 -9
  207. package/dist/prosemirror/yjsParagraphSourceContract.js +0 -26
@@ -76,6 +76,9 @@ function renderRunContent(ctx, pkg, content, paraId) {
76
76
  case "noBreakHyphen":
77
77
  out += "‑";
78
78
  break;
79
+ case "preservedXml":
80
+ out += escapeInline(item.text);
81
+ break;
79
82
  case "footnoteRef":
80
83
  case "endnoteRef": {
81
84
  if (ctx.opts.footnotes === "strip") break;
@@ -147,10 +150,23 @@ function renderHyperlink(ctx, pkg, link, paraId) {
147
150
  }
148
151
  function renderTrackedWrapper(ctx, pkg, wrapper, paraId) {
149
152
  const renderChild = (child) => {
150
- if (child.type === "run") return renderRun(ctx, pkg, child, paraId);
151
- if (child.type === "hyperlink") return renderHyperlink(ctx, pkg, child, paraId);
152
- if (child.type === "mathEquation") return child.plainText ? escapeInline(child.plainText) : "";
153
- return "";
153
+ switch (child.type) {
154
+ case "run": return renderRun(ctx, pkg, child, paraId);
155
+ case "hyperlink": return renderHyperlink(ctx, pkg, child, paraId);
156
+ case "mathEquation": return child.plainText ? escapeInline(child.plainText) : "";
157
+ case "inlineWrapper":
158
+ case "inlineSdt": return renderParagraphInline(ctx, pkg, child.content, paraId);
159
+ case "insertion":
160
+ case "deletion":
161
+ case "moveFrom":
162
+ case "moveTo": return renderTrackedWrapper(ctx, pkg, child, paraId);
163
+ case "simpleField":
164
+ case "complexField": return renderParagraphInline(ctx, pkg, [child], paraId);
165
+ case "bookmarkStart":
166
+ case "bookmarkEnd":
167
+ case "preservedInline": return "";
168
+ default: return child;
169
+ }
154
170
  };
155
171
  if (ctx.opts.trackedChanges === "clean") {
156
172
  if (wrapper.type === "insertion" || wrapper.type === "moveTo") return wrapper.content.map(renderChild).join("");
@@ -196,10 +212,17 @@ function renderParagraphInline(ctx, pkg, content, paraId) {
196
212
  case "simpleField":
197
213
  case "complexField": {
198
214
  const runs = item.type === "simpleField" ? item.content : item.fieldResult;
199
- for (const child of runs) out += child.type === "run" ? renderRun(ctx, pkg, child, paraId) : renderHyperlink(ctx, pkg, child, paraId);
215
+ for (const child of runs) {
216
+ if (child.type === "run") {
217
+ out += renderRun(ctx, pkg, child, paraId);
218
+ continue;
219
+ }
220
+ out += child.type === "hyperlink" ? renderHyperlink(ctx, pkg, child, paraId) : child.text;
221
+ }
200
222
  break;
201
223
  }
202
224
  case "inlineSdt":
225
+ case "inlineWrapper":
203
226
  out += renderParagraphInline(ctx, pkg, item.content, paraId);
204
227
  break;
205
228
  case "mathEquation":
@@ -113,7 +113,7 @@ function renderHtmlCell(ctx, pkg, cell) {
113
113
  for (const item of cell.content) if (item.type === "paragraph") {
114
114
  const inner = renderHtmlInline(ctx, pkg, item.content, item.paraId);
115
115
  if (inner) parts.push(inner);
116
- } else {
116
+ } else if (item.type === "table") {
117
117
  const nested = renderHtmlTable(ctx, pkg, item.rows, true);
118
118
  if (nested) parts.push(nested);
119
119
  }
@@ -148,6 +148,7 @@ function renderHtmlInline(ctx, pkg, content, paraId) {
148
148
  break;
149
149
  }
150
150
  case "inlineSdt":
151
+ case "inlineWrapper":
151
152
  out += renderHtmlInline(ctx, pkg, item.content, paraId);
152
153
  break;
153
154
  case "mathEquation":
@@ -159,10 +160,23 @@ function renderHtmlInline(ctx, pkg, content, paraId) {
159
160
  }
160
161
  function renderHtmlChildren(ctx, pkg, children, paraId) {
161
162
  return children.map((child) => {
162
- if (child.type === "run") return renderHtmlRun(ctx, pkg, child, paraId);
163
- if (child.type === "hyperlink") return renderHtmlHyperlink(ctx, pkg, child, paraId);
164
- if (child.type === "mathEquation") return child.plainText ? escapeHtml(child.plainText) : "";
165
- return "";
163
+ switch (child.type) {
164
+ case "run": return renderHtmlRun(ctx, pkg, child, paraId);
165
+ case "hyperlink": return renderHtmlHyperlink(ctx, pkg, child, paraId);
166
+ case "mathEquation": return child.plainText ? escapeHtml(child.plainText) : "";
167
+ case "inlineWrapper":
168
+ case "inlineSdt":
169
+ case "simpleField":
170
+ case "complexField":
171
+ case "insertion":
172
+ case "deletion":
173
+ case "moveFrom":
174
+ case "moveTo": return renderHtmlInline(ctx, pkg, [child], paraId);
175
+ case "bookmarkStart":
176
+ case "bookmarkEnd":
177
+ case "preservedInline": return "";
178
+ default: return child;
179
+ }
166
180
  }).join("");
167
181
  }
168
182
  function renderHtmlRun(ctx, pkg, run, paraId) {
@@ -184,6 +198,9 @@ function renderHtmlRun(ctx, pkg, run, paraId) {
184
198
  case "noBreakHyphen":
185
199
  text += "‑";
186
200
  break;
201
+ case "preservedXml":
202
+ text += escapeHtml(item.text);
203
+ break;
187
204
  case "softHyphen": break;
188
205
  case "drawing": {
189
206
  const ref = resolveRelationshipIdOfType(pkg?.relationships, item.image.rId, RELATIONSHIP_TYPES.image);
@@ -65,12 +65,15 @@ function inlineText(content) {
65
65
  case "moveFrom":
66
66
  case "moveTo":
67
67
  case "inlineSdt":
68
- case "bidiWrapper":
68
+ case "inlineWrapper":
69
69
  out += inlineText(item.content);
70
70
  break;
71
71
  case "mathEquation":
72
72
  out += item.plainText ?? "";
73
73
  break;
74
+ case "preservedInline":
75
+ out += item.text;
76
+ break;
74
77
  case "bookmarkStart":
75
78
  case "bookmarkEnd":
76
79
  case "commentRangeStart":
@@ -12,9 +12,10 @@ import { inflateSync } from "node:zlib";
12
12
  * so a 4-bit palette image stays 4-bit and an alpha channel becomes an
13
13
  * `/SMask` rather than being composited against a guess at the backdrop.
14
14
  *
15
- * A form this module cannot represent exactly (16-bit samples, interlacing)
16
- * is an error, never an approximation: painting the wrong pixels silently is
17
- * worse than refusing the page.
15
+ * A form this module cannot represent exactly (16-bit samples) is an error,
16
+ * never an approximation: painting the wrong pixels silently is worse than
17
+ * refusing the page. Adam7 interlacing is not such a form — it is seven
18
+ * ordinary rasters of the same samples — so it is decoded rather than refused.
18
19
  */
19
20
  var PdfImageError = class extends TaggedError("PdfImageError") {};
20
21
  const PNG_SIGNATURE = [
@@ -43,6 +44,8 @@ const CHANNELS_PER_COLOR_TYPE = {
43
44
  };
44
45
  const FULLY_OPAQUE = 255;
45
46
  const EIGHT_BIT = 8;
47
+ /** IHDR interlace method 1: the only one PNG defines besides "none". */
48
+ const ADAM7_INTERLACE = 1;
46
49
  const toHex = (bytes) => {
47
50
  let out = "";
48
51
  for (const byte of bytes) out += byte.toString(16).padStart(2, "0").toUpperCase();
@@ -138,6 +141,131 @@ const unfilterPng = ({ filtered, bytesPerRow, bytesPerPixel, height }) => {
138
141
  }
139
142
  return Result.ok(out);
140
143
  };
144
+ /**
145
+ * The seven Adam7 passes, in the order the IDAT stream carries them: the
146
+ * offset of the pass's first pixel and the stride between its pixels.
147
+ */
148
+ const ADAM7_PASSES = [
149
+ {
150
+ xOffset: 0,
151
+ yOffset: 0,
152
+ xStep: 8,
153
+ yStep: 8
154
+ },
155
+ {
156
+ xOffset: 4,
157
+ yOffset: 0,
158
+ xStep: 8,
159
+ yStep: 8
160
+ },
161
+ {
162
+ xOffset: 0,
163
+ yOffset: 4,
164
+ xStep: 4,
165
+ yStep: 8
166
+ },
167
+ {
168
+ xOffset: 2,
169
+ yOffset: 0,
170
+ xStep: 4,
171
+ yStep: 4
172
+ },
173
+ {
174
+ xOffset: 0,
175
+ yOffset: 2,
176
+ xStep: 2,
177
+ yStep: 4
178
+ },
179
+ {
180
+ xOffset: 1,
181
+ yOffset: 0,
182
+ xStep: 2,
183
+ yStep: 2
184
+ },
185
+ {
186
+ xOffset: 0,
187
+ yOffset: 1,
188
+ xStep: 1,
189
+ yStep: 2
190
+ }
191
+ ];
192
+ /**
193
+ * The passes that carry data, with their own geometry.
194
+ *
195
+ * A narrow or short image leaves later passes empty — a 1x1 image has only
196
+ * pass 1 — and an empty pass contributes no bytes at all, not even a filter
197
+ * byte, so it must be dropped rather than read as a zero-row raster.
198
+ */
199
+ const adam7Passes = (width, height, bitsPerPixel) => {
200
+ const passes = [];
201
+ for (const { xOffset, yOffset, xStep, yStep } of ADAM7_PASSES) {
202
+ const passWidth = Math.ceil(Math.max(0, width - xOffset) / xStep);
203
+ const passHeight = Math.ceil(Math.max(0, height - yOffset) / yStep);
204
+ if (passWidth === 0 || passHeight === 0) continue;
205
+ passes.push({
206
+ xOffset,
207
+ yOffset,
208
+ xStep,
209
+ yStep,
210
+ width: passWidth,
211
+ height: passHeight,
212
+ bytesPerRow: Math.ceil(bitsPerPixel * passWidth / EIGHT_BIT)
213
+ });
214
+ }
215
+ return passes;
216
+ };
217
+ /** One filter byte per row of every pass: the whole inflated size Adam7 needs. */
218
+ const adam7FilteredBytes = (passes) => passes.reduce((sum, pass) => sum + pass.height * (pass.bytesPerRow + 1), 0);
219
+ /** Write one unfiltered pass into the pixels of the full raster it owns. */
220
+ const scatterPass = ({ pass, rows, out, bytesPerRow, bitDepth, bytesPerPixel }) => {
221
+ if (bitDepth >= EIGHT_BIT) {
222
+ for (let row = 0; row < pass.height; row += 1) {
223
+ const targetRow = pass.yOffset + row * pass.yStep;
224
+ for (let column = 0; column < pass.width; column += 1) {
225
+ const source = row * pass.bytesPerRow + column * bytesPerPixel;
226
+ const target = targetRow * bytesPerRow + (pass.xOffset + column * pass.xStep) * bytesPerPixel;
227
+ for (let byte = 0; byte < bytesPerPixel; byte += 1) out[target + byte] = rows[source + byte] ?? 0;
228
+ }
229
+ }
230
+ return;
231
+ }
232
+ const perByte = EIGHT_BIT / bitDepth;
233
+ const mask = (1 << bitDepth) - 1;
234
+ for (let row = 0; row < pass.height; row += 1) {
235
+ const targetRow = pass.yOffset + row * pass.yStep;
236
+ for (let column = 0; column < pass.width; column += 1) {
237
+ const value = (rows[row * pass.bytesPerRow + Math.floor(column / perByte)] ?? 0) >> EIGHT_BIT - bitDepth * (column % perByte + 1) & mask;
238
+ const targetColumn = pass.xOffset + column * pass.xStep;
239
+ const targetIndex = targetRow * bytesPerRow + Math.floor(targetColumn / perByte);
240
+ const targetShift = EIGHT_BIT - bitDepth * (targetColumn % perByte + 1);
241
+ out[targetIndex] = (out[targetIndex] ?? 0) & ~(mask << targetShift) | value << targetShift;
242
+ }
243
+ }
244
+ };
245
+ /** Unfilter each Adam7 pass and scatter it into the raster it describes. */
246
+ const deinterlacePng = ({ filtered, passes, height, bytesPerRow, bytesPerPixel, bitDepth }) => {
247
+ const out = new Uint8Array(height * bytesPerRow);
248
+ let cursor = 0;
249
+ for (const pass of passes) {
250
+ const unfiltered = unfilterPng({
251
+ filtered: filtered.subarray(cursor),
252
+ bytesPerRow: pass.bytesPerRow,
253
+ bytesPerPixel,
254
+ height: pass.height
255
+ });
256
+ if (unfiltered.isErr()) return Result.err(unfiltered.error);
257
+ scatterPass({
258
+ pass,
259
+ rows: unfiltered.value,
260
+ out,
261
+ bytesPerRow,
262
+ bitDepth,
263
+ bytesPerPixel
264
+ });
265
+ cursor += pass.height * (pass.bytesPerRow + 1);
266
+ }
267
+ return Result.ok(out);
268
+ };
141
269
  /** One byte per pixel index, for sub-byte palette and greyscale depths. */
142
270
  const expandIndices = ({ rows, bytesPerRow, width, height, bitDepth }) => {
143
271
  if (bitDepth === EIGHT_BIT) return rows;
@@ -162,7 +290,7 @@ const decodePng = (bytes) => {
162
290
  const colorType = header[9] ?? 0;
163
291
  const interlace = header[12] ?? 0;
164
292
  if (width === 0 || height === 0) return Result.err(new PdfImageError({ message: "PNG has a zero dimension" }));
165
- if (interlace !== 0) return Result.err(new PdfImageError({ message: "interlaced PNG is not supported" }));
293
+ if (interlace !== 0 && interlace !== ADAM7_INTERLACE) return Result.err(new PdfImageError({ message: `unknown PNG interlace method ${String(interlace)}` }));
166
294
  const channels = CHANNELS_PER_COLOR_TYPE[colorType];
167
295
  if (channels === void 0) return Result.err(new PdfImageError({ message: `unknown PNG colour type ${String(colorType)}` }));
168
296
  if (!(colorType === PNG_COLOR_TYPE.greyscale || colorType === PNG_COLOR_TYPE.palette ? [
@@ -174,18 +302,26 @@ const decodePng = (bytes) => {
174
302
  const bitsPerPixel = bitDepth * channels;
175
303
  const bytesPerRow = Math.ceil(bitsPerPixel * width / EIGHT_BIT);
176
304
  const bytesPerPixel = Math.max(1, Math.ceil(bitsPerPixel / EIGHT_BIT));
177
- const inflatedBytesExpected = height * (bytesPerRow + 1);
305
+ const passes = interlace === ADAM7_INTERLACE ? adam7Passes(width, height, bitsPerPixel) : null;
306
+ const inflatedBytesExpected = passes === null ? height * (bytesPerRow + 1) : adam7FilteredBytes(passes);
178
307
  const inflated = Result.try({
179
308
  try: () => inflateSync(pixels, { maxOutputLength: inflatedBytesExpected }),
180
309
  catch: (cause) => new PdfImageError({ message: `PNG IDAT does not inflate to the ${String(inflatedBytesExpected)} bytes its IHDR declares: ${cause instanceof Error ? cause.message : String(cause)}` })
181
310
  });
182
311
  if (inflated.isErr()) return Result.err(inflated.error);
183
312
  const filtered = new Uint8Array(inflated.value.buffer, inflated.value.byteOffset, inflated.value.byteLength);
184
- const unfiltered = unfilterPng({
313
+ const unfiltered = passes === null ? unfilterPng({
185
314
  filtered,
186
315
  bytesPerRow,
187
316
  bytesPerPixel,
188
317
  height
318
+ }) : deinterlacePng({
319
+ filtered,
320
+ passes,
321
+ height,
322
+ bytesPerRow,
323
+ bytesPerPixel,
324
+ bitDepth
189
325
  });
190
326
  if (unfiltered.isErr()) return Result.err(unfiltered.error);
191
327
  const rows = unfiltered.value;
@@ -1,5 +1,5 @@
1
- import { CharacterSpacingAttrs, CharacterStyleAttrs, CommentAttrs, EmphasisMarkAttrs, FontFamilyAttrs, FontSizeAttrs, FootnoteRefAttrs, HighlightAttrs, HyperlinkAttrs, LanguageAttrs, PageBreakRunOwnerMarkAttrs, RunFormattingOverrideAttrs, RunPropertyChangeMarkAttrs, RunShadingAttrs, StrikeAttrs, TextColorAttrs, TextEffectAttrs, TrackedChangeMarkAttrs, UnderlineAttrs } from "../schema/marks.js";
2
- import { BlockSdtAttrs, FieldAttrs, HardBreakAttrs, ImageAttrs, MathAttrs, PageBreakRunAttrs, ParagraphAttrs, SdtAttrs, ShapeAttrs, SymbolAttrs, TabAttrs, TableAttrs, TableCellAttrs, TableRowAttrs, TextBoxAttrs } from "../schema/nodes.js";
1
+ import { CharacterSpacingAttrs, CharacterStyleAttrs, CommentAttrs, EmphasisMarkAttrs, FontFamilyAttrs, FontSizeAttrs, FootnoteRefAttrs, HighlightAttrs, HyperlinkAttrs, InlineWrapperAttrs, InlineWrapperLayer, LanguageAttrs, PageBreakRunOwnerMarkAttrs, RunFormattingOverrideAttrs, RunPropertyChangeMarkAttrs, RunShadingAttrs, StrikeAttrs, TextColorAttrs, TextEffectAttrs, TrackedChangeMarkAttrs, UnderlineAttrs } from "../schema/marks.js";
2
+ import { BlockSdtAttrs, FieldAttrs, HardBreakAttrs, ImageAttrs, MathAttrs, PageBreakRunAttrs, ParagraphAttrs, PreservedBlockAttrs, PreservedXmlAttrs, SdtAttrs, ShapeAttrs, SymbolAttrs, TabAttrs, TableAttrs, TableCellAttrs, TableRowAttrs, TextBoxAttrs } from "../schema/nodes.js";
3
3
  import "../schema/index.js";
4
4
  import { Mark, Node } from "prosemirror-model";
5
5
  //#region src/prosemirror/attrs/index.d.ts
@@ -24,6 +24,10 @@ declare const readTabAttrs: (node: Node) => ReadProseMirrorAttrsResult<TabAttrs>
24
24
  declare const expectTabAttrs: (node: Node) => TabAttrs;
25
25
  declare const readSymbolAttrs: (node: Node) => ReadProseMirrorAttrsResult<SymbolAttrs>;
26
26
  declare const expectSymbolAttrs: (node: Node) => SymbolAttrs;
27
+ declare const readPreservedXmlAttrs: (node: Node) => ReadProseMirrorAttrsResult<PreservedXmlAttrs>;
28
+ declare const expectPreservedXmlAttrs: (node: Node) => PreservedXmlAttrs;
29
+ declare const readPreservedBlockAttrs: (node: Node) => ReadProseMirrorAttrsResult<PreservedBlockAttrs>;
30
+ declare const expectPreservedBlockAttrs: (node: Node) => PreservedBlockAttrs;
27
31
  declare const readTableAttrs: (node: Node) => ReadProseMirrorAttrsResult<TableAttrs>;
28
32
  declare const expectTableAttrs: (node: Node) => TableAttrs;
29
33
  declare const readTableRowAttrs: (node: Node) => ReadProseMirrorAttrsResult<TableRowAttrs>;
@@ -78,6 +82,13 @@ declare const readRunPropertyChangeMarkAttrs: (mark: Mark) => ReadProseMirrorAtt
78
82
  declare const expectRunPropertyChangeMarkAttrs: (mark: Mark) => RunPropertyChangeMarkAttrs;
79
83
  declare const readPageBreakRunOwnerMarkAttrs: (mark: Mark) => ReadProseMirrorAttrsResult<PageBreakRunOwnerMarkAttrs>;
80
84
  declare const expectPageBreakRunOwnerMarkAttrs: (mark: Mark) => PageBreakRunOwnerMarkAttrs;
85
+ /**
86
+ * A wrapper stack read from outside the editor — the DOM on paste, a stored
87
+ * snapshot — validated layer by layer.
88
+ */
89
+ declare const readInlineWrapperStack: (value: unknown, path?: string) => ReadProseMirrorAttrsResult<readonly InlineWrapperLayer[]>;
90
+ declare const readInlineWrapperMarkAttrs: (mark: Mark) => ReadProseMirrorAttrsResult<InlineWrapperAttrs>;
91
+ declare const expectInlineWrapperMarkAttrs: (mark: Mark) => InlineWrapperAttrs;
81
92
  declare const readRunFormattingOverrideMarkAttrs: (mark: Mark) => ReadProseMirrorAttrsResult<RunFormattingOverrideAttrs>;
82
93
  declare const expectRunFormattingOverrideMarkAttrs: (mark: Mark) => RunFormattingOverrideAttrs;
83
94
  declare const readHyperlinkMarkAttrs: (mark: Mark) => ReadProseMirrorAttrsResult<HyperlinkAttrs>;
@@ -89,4 +100,4 @@ declare const mergeTableAttrs: (node: Node, patch: NodeAttrPatch<TableAttrs>) =>
89
100
  declare const mergeTableRowAttrs: (node: Node, patch: NodeAttrPatch<TableRowAttrs>) => TableRowAttrs;
90
101
  declare const mergeTableCellAttrs: (node: Node, patch: NodeAttrPatch<TableCellAttrs>) => TableCellAttrs;
91
102
  //#endregion
92
- export { ProseMirrorAttrIssue, ReadProseMirrorAttrsResult, expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectPageBreakRunAttrs, expectPageBreakRunOwnerMarkAttrs, expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs, expectRunPropertyChangeMarkAttrs, expectRunShadingMarkAttrs, expectSdtAttrs, expectShapeAttrs, expectStrikeMarkAttrs, expectSymbolAttrs, expectTabAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs, mergeImageAttrs, mergeParagraphAttrs, mergeTableAttrs, mergeTableCellAttrs, mergeTableRowAttrs, readBlockSdtAttrs, readCharacterSpacingMarkAttrs, readCharacterStyleMarkAttrs, readCommentMarkAttrs, readEmphasisMarkAttrs, readFieldAttrs, readFontFamilyMarkAttrs, readFontSizeMarkAttrs, readFootnoteRefMarkAttrs, readHardBreakAttrs, readHighlightMarkAttrs, readHyperlinkMarkAttrs, readImageAttrs, readLanguageMarkAttrs, readMathAttrs, readPageBreakRunAttrs, readPageBreakRunOwnerMarkAttrs, readParagraphAttrs, readRunFormattingOverrideMarkAttrs, readRunPropertyChangeMarkAttrs, readRunShadingMarkAttrs, readSdtAttrs, readShapeAttrs, readStrikeMarkAttrs, readSymbolAttrs, readTabAttrs, readTableAttrs, readTableCellAttrs, readTableRowAttrs, readTextBoxAttrs, readTextColorMarkAttrs, readTextEffectMarkAttrs, readTrackedChangeMarkAttrs, readUnderlineMarkAttrs };
103
+ export { ProseMirrorAttrIssue, ReadProseMirrorAttrsResult, expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectInlineWrapperMarkAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectPageBreakRunAttrs, expectPageBreakRunOwnerMarkAttrs, expectParagraphAttrs, expectPreservedBlockAttrs, expectPreservedXmlAttrs, expectRunFormattingOverrideMarkAttrs, expectRunPropertyChangeMarkAttrs, expectRunShadingMarkAttrs, expectSdtAttrs, expectShapeAttrs, expectStrikeMarkAttrs, expectSymbolAttrs, expectTabAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs, mergeImageAttrs, mergeParagraphAttrs, mergeTableAttrs, mergeTableCellAttrs, mergeTableRowAttrs, readBlockSdtAttrs, readCharacterSpacingMarkAttrs, readCharacterStyleMarkAttrs, readCommentMarkAttrs, readEmphasisMarkAttrs, readFieldAttrs, readFontFamilyMarkAttrs, readFontSizeMarkAttrs, readFootnoteRefMarkAttrs, readHardBreakAttrs, readHighlightMarkAttrs, readHyperlinkMarkAttrs, readImageAttrs, readInlineWrapperMarkAttrs, readInlineWrapperStack, readLanguageMarkAttrs, readMathAttrs, readPageBreakRunAttrs, readPageBreakRunOwnerMarkAttrs, readParagraphAttrs, readPreservedBlockAttrs, readPreservedXmlAttrs, readRunFormattingOverrideMarkAttrs, readRunPropertyChangeMarkAttrs, readRunShadingMarkAttrs, readSdtAttrs, readShapeAttrs, readStrikeMarkAttrs, readSymbolAttrs, readTabAttrs, readTableAttrs, readTableCellAttrs, readTableRowAttrs, readTextBoxAttrs, readTextColorMarkAttrs, readTextEffectMarkAttrs, readTrackedChangeMarkAttrs, readUnderlineMarkAttrs };
@@ -5,10 +5,11 @@ import { canonicalJson } from "../../utils/canonicalJson.js";
5
5
  import { normalizeHorizontalScalePercent } from "../../utils/horizontalScale.js";
6
6
  import { isParagraphDirection } from "../paragraphDirection.js";
7
7
  import { COMPLEX_SCRIPT_RUN_PROPERTY_KEYS, RUN_FORMATTING_BOOLEAN_PROPERTIES, RUN_FORMATTING_VALUE_PROPERTIES, TRACKED_CHANGE_PROVENANCE_VALUES } from "../schema/marks.js";
8
- import { TEXT_BOX_TEXT_BODY_CONTENT_STATE_TYPES } from "../schema/nodes.js";
8
+ import { PRESERVED_XML_LEVELS, TEXT_BOX_TEXT_BODY_CONTENT_STATE_TYPES } from "../schema/nodes.js";
9
9
  import { panic } from "better-result";
10
10
  import { DRAWING_RAW_XML_MODES, isOoxmlSymbolCharacter } from "@stll/docx-core/model";
11
11
  //#region src/prosemirror/attrs/index.ts
12
+ const PRESERVED_XML_LEVEL_VALUES = new Set(Object.values(PRESERVED_XML_LEVELS));
12
13
  const SECTION_BREAK_TYPES = [
13
14
  "nextPage",
14
15
  "continuous",
@@ -146,6 +147,8 @@ const hardBreakAttrsCache = /* @__PURE__ */ new WeakMap();
146
147
  const pageBreakRunAttrsCache = /* @__PURE__ */ new WeakMap();
147
148
  const tabAttrsCache = /* @__PURE__ */ new WeakMap();
148
149
  const symbolAttrsCache = /* @__PURE__ */ new WeakMap();
150
+ const preservedXmlAttrsCache = /* @__PURE__ */ new WeakMap();
151
+ const preservedBlockAttrsCache = /* @__PURE__ */ new WeakMap();
149
152
  const tableAttrsCache = /* @__PURE__ */ new WeakMap();
150
153
  const tableRowAttrsCache = /* @__PURE__ */ new WeakMap();
151
154
  const tableCellAttrsCache = /* @__PURE__ */ new WeakMap();
@@ -172,6 +175,7 @@ const commentAttrsCache = /* @__PURE__ */ new WeakMap();
172
175
  const trackedChangeAttrsCache = /* @__PURE__ */ new WeakMap();
173
176
  const runPropertyChangeAttrsCache = /* @__PURE__ */ new WeakMap();
174
177
  const pageBreakRunOwnerAttrsCache = /* @__PURE__ */ new WeakMap();
178
+ const inlineWrapperAttrsCache = /* @__PURE__ */ new WeakMap();
175
179
  const runFormattingOverrideAttrsCache = /* @__PURE__ */ new WeakMap();
176
180
  const hyperlinkAttrsCache = /* @__PURE__ */ new WeakMap();
177
181
  const readParagraphAttrs = (node) => {
@@ -257,6 +261,7 @@ const readParagraphAttrs = (node) => {
257
261
  optionalAutospacingBase(attrs, "paragraph.attrs._autospacingBase", issues);
258
262
  optionalSectionProperties(attrs, "_sectionProperties", "paragraph.attrs._sectionProperties", issues);
259
263
  optionalPropertyChanges(attrs, "_propertyChanges", "paragraph.attrs._propertyChanges", issues, ["paragraphPropertyChange"]);
264
+ optionalPreservedAttributes(attrs, "paragraph.attrs._preservedAttributes", issues);
260
265
  return attrsResult(attrs, issues);
261
266
  };
262
267
  const expectParagraphAttrs = (node) => expectCachedNodeAttrs(node, paragraphAttrsCache, readParagraphAttrs, "paragraph attrs");
@@ -304,6 +309,27 @@ const readSymbolAttrs = (node) => {
304
309
  return attrsResult(attrs, issues);
305
310
  };
306
311
  const expectSymbolAttrs = (node) => expectCachedNodeAttrs(node, symbolAttrsCache, readSymbolAttrs, "symbol attrs");
312
+ const readPreservedXmlAttrs = (node) => {
313
+ const attrs = attrsRecord(node.attrs);
314
+ const issues = [];
315
+ expectNodeType(node, "preservedXml", issues);
316
+ requiredString(attrs, "xml", "preservedXml.attrs.xml", issues);
317
+ requiredString(attrs, "text", "preservedXml.attrs.text", issues);
318
+ if (!PRESERVED_XML_LEVEL_VALUES.has(attrs["level"])) issues.push({
319
+ path: "preservedXml.attrs.level",
320
+ message: `Expected one of ${[...PRESERVED_XML_LEVEL_VALUES].join(", ")}.`
321
+ });
322
+ return attrsResult(attrs, issues);
323
+ };
324
+ const expectPreservedXmlAttrs = (node) => expectCachedNodeAttrs(node, preservedXmlAttrsCache, readPreservedXmlAttrs, "preservedXml attrs");
325
+ const readPreservedBlockAttrs = (node) => {
326
+ const attrs = attrsRecord(node.attrs);
327
+ const issues = [];
328
+ expectNodeType(node, "preservedBlock", issues);
329
+ requiredString(attrs, "xml", "preservedBlock.attrs.xml", issues);
330
+ return attrsResult(attrs, issues);
331
+ };
332
+ const expectPreservedBlockAttrs = (node) => expectCachedNodeAttrs(node, preservedBlockAttrsCache, readPreservedBlockAttrs, "preservedBlock attrs");
307
333
  const readTableAttrs = (node) => {
308
334
  const attrs = attrsRecord(node.attrs);
309
335
  const issues = [];
@@ -346,6 +372,7 @@ const readTableRowAttrs = (node) => {
346
372
  path: "tableRow.attrs",
347
373
  message: "Expected at most one structural revision marker."
348
374
  });
375
+ optionalPreservedAttributes(attrs, "tableRow.attrs._preservedAttributes", issues);
349
376
  return attrsResult(attrs, issues);
350
377
  };
351
378
  const expectTableRowAttrs = (node) => expectCachedNodeAttrs(node, tableRowAttrsCache, readTableRowAttrs, "table row attrs");
@@ -394,11 +421,16 @@ const readImageAttrs = (node) => {
394
421
  optionalOneOf(attrs, "displayMode", "image.attrs.displayMode", issues, IMAGE_DISPLAY_MODES);
395
422
  optionalOneOf(attrs, "cssFloat", "image.attrs.cssFloat", issues, IMAGE_CSS_FLOATS);
396
423
  optionalString(attrs, "transform", "image.attrs.transform", issues);
424
+ optionalNumber(attrs, "docxRotation", "image.attrs.docxRotation", issues);
425
+ optionalBoolean(attrs, "docxFlipH", "image.attrs.docxFlipH", issues);
426
+ optionalBoolean(attrs, "docxFlipV", "image.attrs.docxFlipV", issues);
397
427
  optionalNumber(attrs, "distTop", "image.attrs.distTop", issues);
398
428
  optionalNumber(attrs, "distBottom", "image.attrs.distBottom", issues);
399
429
  optionalNumber(attrs, "distLeft", "image.attrs.distLeft", issues);
400
430
  optionalNumber(attrs, "distRight", "image.attrs.distRight", issues);
401
431
  optionalNumber(attrs, "opacity", "image.attrs.opacity", issues);
432
+ optionalNumber(attrs, "brightness", "image.attrs.brightness", issues);
433
+ optionalNumber(attrs, "contrast", "image.attrs.contrast", issues);
402
434
  optionalNumber(attrs, "cropTop", "image.attrs.cropTop", issues);
403
435
  optionalNumber(attrs, "cropRight", "image.attrs.cropRight", issues);
404
436
  optionalNumber(attrs, "cropBottom", "image.attrs.cropBottom", issues);
@@ -517,6 +549,9 @@ const readShapeAttrs = (node) => {
517
549
  optionalShapeLineEnd(attrs, "outlineHeadEnd", "shape.attrs.outlineHeadEnd", issues);
518
550
  optionalShapeLineEnd(attrs, "outlineTailEnd", "shape.attrs.outlineTailEnd", issues);
519
551
  optionalString(attrs, "transform", "shape.attrs.transform", issues);
552
+ optionalNumber(attrs, "docxRotation", "shape.attrs.docxRotation", issues);
553
+ optionalBoolean(attrs, "docxFlipH", "shape.attrs.docxFlipH", issues);
554
+ optionalBoolean(attrs, "docxFlipV", "shape.attrs.docxFlipV", issues);
520
555
  optionalOneOf(attrs, "displayMode", "shape.attrs.displayMode", issues, IMAGE_DISPLAY_MODES);
521
556
  optionalOneOf(attrs, "cssFloat", "shape.attrs.cssFloat", issues, IMAGE_CSS_FLOATS);
522
557
  optionalOneOf(attrs, "wrapType", "shape.attrs.wrapType", issues, IMAGE_WRAP_TYPE_VALUES);
@@ -554,6 +589,9 @@ const readTextBoxAttrs = (node) => {
554
589
  optionalString(attrs, "outlineColor", "textBox.attrs.outlineColor", issues);
555
590
  optionalOneOf(attrs, "outlineStyle", "textBox.attrs.outlineStyle", issues, OUTLINE_STYLE_ATTR_VALUES);
556
591
  optionalTextBoxTransform(attrs, "transform", "textBox.attrs.transform", issues);
592
+ optionalNumber(attrs, "docxRotation", "textBox.attrs.docxRotation", issues);
593
+ optionalBoolean(attrs, "docxFlipH", "textBox.attrs.docxFlipH", issues);
594
+ optionalBoolean(attrs, "docxFlipV", "textBox.attrs.docxFlipV", issues);
557
595
  optionalNumber(attrs, "marginTop", "textBox.attrs.marginTop", issues);
558
596
  optionalNumber(attrs, "marginBottom", "textBox.attrs.marginBottom", issues);
559
597
  optionalNumber(attrs, "marginLeft", "textBox.attrs.marginLeft", issues);
@@ -574,6 +612,7 @@ const readTextBoxAttrs = (node) => {
574
612
  requiredTextBoxBodyContentState(attrs, issues);
575
613
  optionalTextBoxTrackedChange(attrs, issues);
576
614
  optionalTextBoxInlineSdts(attrs, issues);
615
+ optionalPreservedAttributes(attrs, "textBox.attrs._preservedAttributes", issues);
577
616
  return attrsResult(attrs, issues);
578
617
  };
579
618
  const expectTextBoxAttrs = (node) => expectCachedNodeAttrs(node, textBoxAttrsCache, readTextBoxAttrs, "text box attrs");
@@ -752,6 +791,89 @@ const readPageBreakRunOwnerMarkAttrs = (mark) => {
752
791
  return attrsResult(attrs, issues);
753
792
  };
754
793
  const expectPageBreakRunOwnerMarkAttrs = (mark) => expectCachedMarkAttrs(mark, pageBreakRunOwnerAttrsCache, readPageBreakRunOwnerMarkAttrs, "page break run owner attrs");
794
+ const BIDI_LAYER_CONTROLS = ["embedding", "override"];
795
+ const BIDI_LAYER_DIRECTIONS = ["ltr", "rtl"];
796
+ const BIDI_LAYER_KEYS = /* @__PURE__ */ new Set([
797
+ "kind",
798
+ "control",
799
+ "direction"
800
+ ]);
801
+ /**
802
+ * One validator per wrapper kind, total over the kinds the model declares: a
803
+ * kind added without a field-by-field check does not compile, and a layer that
804
+ * states a field its kind does not carry (a smart tag with a bidi `control`)
805
+ * is rejected rather than stored and written back.
806
+ */
807
+ const INLINE_WRAPPER_LAYER_VALIDATORS = { bidi: (layer, path, issues) => {
808
+ requiredOneOf(layer, "control", `${path}.control`, issues, BIDI_LAYER_CONTROLS);
809
+ optionalOneOf(layer, "direction", `${path}.direction`, issues, BIDI_LAYER_DIRECTIONS);
810
+ for (const key of Object.keys(layer)) if (!BIDI_LAYER_KEYS.has(key)) issues.push({
811
+ path: `${path}.${key}`,
812
+ message: "Unexpected bidi wrapper property."
813
+ });
814
+ } };
815
+ const inlineWrapperLayerValidator = (kind) => {
816
+ return typeof kind === "string" ? INLINE_WRAPPER_LAYER_VALIDATORS[kind] : void 0;
817
+ };
818
+ const validateInlineWrapperStack = (value, path, issues) => {
819
+ if (!Array.isArray(value)) {
820
+ issues.push({
821
+ path,
822
+ message: "Expected an array of inline wrapper layers."
823
+ });
824
+ return;
825
+ }
826
+ if (value.length === 0) {
827
+ issues.push({
828
+ path,
829
+ message: "Expected at least one inline wrapper layer."
830
+ });
831
+ return;
832
+ }
833
+ for (const [index, layer] of value.entries()) {
834
+ const layerPath = `${path}[${index}]`;
835
+ if (!isRecord(layer)) {
836
+ issues.push({
837
+ path: layerPath,
838
+ message: "Expected an inline wrapper layer object."
839
+ });
840
+ continue;
841
+ }
842
+ const validator = inlineWrapperLayerValidator(layer["kind"]);
843
+ if (!validator) {
844
+ issues.push({
845
+ path: `${layerPath}.kind`,
846
+ message: `Expected one of ${Object.keys(INLINE_WRAPPER_LAYER_VALIDATORS).join(", ")}.`
847
+ });
848
+ continue;
849
+ }
850
+ validator(layer, layerPath, issues);
851
+ }
852
+ };
853
+ /**
854
+ * A wrapper stack read from outside the editor — the DOM on paste, a stored
855
+ * snapshot — validated layer by layer.
856
+ */
857
+ const readInlineWrapperStack = (value, path = "inlineWrapper.attrs.stack") => {
858
+ const issues = [];
859
+ validateInlineWrapperStack(value, path, issues);
860
+ if (issues.length > 0) return {
861
+ ok: false,
862
+ issues
863
+ };
864
+ return {
865
+ ok: true,
866
+ value
867
+ };
868
+ };
869
+ const readInlineWrapperMarkAttrs = (mark) => {
870
+ const attrs = attrsRecord(mark.attrs);
871
+ const issues = [];
872
+ expectMarkType(mark, "inlineWrapper", issues);
873
+ validateInlineWrapperStack(attrs["stack"], "inlineWrapper.attrs.stack", issues);
874
+ return attrsResult(attrs, issues);
875
+ };
876
+ const expectInlineWrapperMarkAttrs = (mark) => expectCachedMarkAttrs(mark, inlineWrapperAttrsCache, readInlineWrapperMarkAttrs, "inline wrapper attrs");
755
877
  const readRunFormattingOverrideMarkAttrs = (mark) => {
756
878
  const attrs = attrsRecord(mark.attrs);
757
879
  const issues = [];
@@ -1306,6 +1428,37 @@ const validateSdtAttrsRecord = (attrs, path, issues) => {
1306
1428
  optionalString(attrs, "rawPropertiesXml", `${path}.rawPropertiesXml`, issues);
1307
1429
  optionalString(attrs, "rawEndPropertiesXml", `${path}.rawEndPropertiesXml`, issues);
1308
1430
  };
1431
+ /**
1432
+ * The attribute remainder an authored element's record carries.
1433
+ *
1434
+ * Every entry is a resolved name and a string value; nothing here is a
1435
+ * spelling, which is why the namespace is a URI and optional rather than a
1436
+ * prefix. See `docx/attributeRemainder.ts`.
1437
+ */
1438
+ const optionalPreservedAttributes = (attrs, path, issues) => {
1439
+ const value = attrs["_preservedAttributes"];
1440
+ if (value === void 0 || value === null) return;
1441
+ if (!Array.isArray(value)) {
1442
+ issues.push({
1443
+ path,
1444
+ message: "Expected an array."
1445
+ });
1446
+ return;
1447
+ }
1448
+ for (const [index, entry] of value.entries()) {
1449
+ const entryPath = `${path}[${index}]`;
1450
+ if (!isRecord(entry)) {
1451
+ issues.push({
1452
+ path: entryPath,
1453
+ message: "Expected an object."
1454
+ });
1455
+ continue;
1456
+ }
1457
+ requiredString(entry, "name", `${entryPath}.name`, issues);
1458
+ requiredString(entry, "value", `${entryPath}.value`, issues);
1459
+ optionalString(entry, "namespace", `${entryPath}.namespace`, issues);
1460
+ }
1461
+ };
1309
1462
  const optionalAutospacingBase = (attrs, path, issues) => {
1310
1463
  const value = attrs["_autospacingBase"];
1311
1464
  if (value === void 0 || value === null) return;
@@ -2024,4 +2177,4 @@ const optionalEmptyHyperlinkArray = (value, issues) => {
2024
2177
  }
2025
2178
  };
2026
2179
  //#endregion
2027
- export { expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectPageBreakRunAttrs, expectPageBreakRunOwnerMarkAttrs, expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs, expectRunPropertyChangeMarkAttrs, expectRunShadingMarkAttrs, expectSdtAttrs, expectShapeAttrs, expectStrikeMarkAttrs, expectSymbolAttrs, expectTabAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs, mergeImageAttrs, mergeParagraphAttrs, mergeTableAttrs, mergeTableCellAttrs, mergeTableRowAttrs, readBlockSdtAttrs, readCharacterSpacingMarkAttrs, readCharacterStyleMarkAttrs, readCommentMarkAttrs, readEmphasisMarkAttrs, readFieldAttrs, readFontFamilyMarkAttrs, readFontSizeMarkAttrs, readFootnoteRefMarkAttrs, readHardBreakAttrs, readHighlightMarkAttrs, readHyperlinkMarkAttrs, readImageAttrs, readLanguageMarkAttrs, readMathAttrs, readPageBreakRunAttrs, readPageBreakRunOwnerMarkAttrs, readParagraphAttrs, readRunFormattingOverrideMarkAttrs, readRunPropertyChangeMarkAttrs, readRunShadingMarkAttrs, readSdtAttrs, readShapeAttrs, readStrikeMarkAttrs, readSymbolAttrs, readTabAttrs, readTableAttrs, readTableCellAttrs, readTableRowAttrs, readTextBoxAttrs, readTextColorMarkAttrs, readTextEffectMarkAttrs, readTrackedChangeMarkAttrs, readUnderlineMarkAttrs };
2180
+ export { expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectInlineWrapperMarkAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectPageBreakRunAttrs, expectPageBreakRunOwnerMarkAttrs, expectParagraphAttrs, expectPreservedBlockAttrs, expectPreservedXmlAttrs, expectRunFormattingOverrideMarkAttrs, expectRunPropertyChangeMarkAttrs, expectRunShadingMarkAttrs, expectSdtAttrs, expectShapeAttrs, expectStrikeMarkAttrs, expectSymbolAttrs, expectTabAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs, mergeImageAttrs, mergeParagraphAttrs, mergeTableAttrs, mergeTableCellAttrs, mergeTableRowAttrs, readBlockSdtAttrs, readCharacterSpacingMarkAttrs, readCharacterStyleMarkAttrs, readCommentMarkAttrs, readEmphasisMarkAttrs, readFieldAttrs, readFontFamilyMarkAttrs, readFontSizeMarkAttrs, readFootnoteRefMarkAttrs, readHardBreakAttrs, readHighlightMarkAttrs, readHyperlinkMarkAttrs, readImageAttrs, readInlineWrapperMarkAttrs, readInlineWrapperStack, readLanguageMarkAttrs, readMathAttrs, readPageBreakRunAttrs, readPageBreakRunOwnerMarkAttrs, readParagraphAttrs, readPreservedBlockAttrs, readPreservedXmlAttrs, readRunFormattingOverrideMarkAttrs, readRunPropertyChangeMarkAttrs, readRunShadingMarkAttrs, readSdtAttrs, readShapeAttrs, readStrikeMarkAttrs, readSymbolAttrs, readTabAttrs, readTableAttrs, readTableCellAttrs, readTableRowAttrs, readTextBoxAttrs, readTextColorMarkAttrs, readTextEffectMarkAttrs, readTrackedChangeMarkAttrs, readUnderlineMarkAttrs };
@@ -0,0 +1,28 @@
1
+ import { document_d_exports } from "../types/document.js";
2
+ //#region src/prosemirror/authoredTransformAttrs.d.ts
3
+ /** The transform attrs a drawing node (`image`, `shape`, `textBox`) carries. */
4
+ type AuthoredTransformAttrs = {
5
+ docxFlipH: boolean | null;
6
+ docxFlipV: boolean | null;
7
+ docxRotation: number | null;
8
+ /** The rendered CSS, derived from the three above. */
9
+ transform: string | undefined;
10
+ };
11
+ /** What a drawing node's attrs say, as they arrive from a persisted document. */
12
+ type ReadableTransformAttrs = {
13
+ docxFlipH?: boolean | null;
14
+ docxFlipV?: boolean | null;
15
+ docxRotation?: number | null;
16
+ transform?: string;
17
+ };
18
+ /** Project a model transform onto a drawing node's attrs. */
19
+ declare const authoredTransformAttrs: (transform: document_d_exports.ImageTransform | undefined) => AuthoredTransformAttrs;
20
+ /**
21
+ * Read a drawing node's authored transform back.
22
+ *
23
+ * The attrs are the record; the CSS string answers only for a node that states
24
+ * none of them, which is how a node persisted before they existed arrives.
25
+ */
26
+ declare const readAuthoredTransform: (attrs: ReadableTransformAttrs) => document_d_exports.ImageTransform | undefined;
27
+ //#endregion
28
+ export { authoredTransformAttrs, readAuthoredTransform };