@stll/folio-core 0.37.5 → 0.39.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 (144) hide show
  1. package/dist/ai-edits/apply.js +275 -88
  2. package/dist/ai-edits/clean-text.js +12 -1
  3. package/dist/ai-edits/headless.d.ts +110 -0
  4. package/dist/ai-edits/headless.js +569 -40
  5. package/dist/ai-edits/snapshot.d.ts +24 -1
  6. package/dist/ai-edits/snapshot.js +206 -9
  7. package/dist/ai-edits/table-geometry.d.ts +7 -7
  8. package/dist/ai-edits/table-geometry.js +43 -27
  9. package/dist/ai-edits/table-template.d.ts +2 -1
  10. package/dist/ai-edits/table-template.js +9 -3
  11. package/dist/ai-edits/types.d.ts +37 -15
  12. package/dist/compare/__fixtures__/body-sequence.d.ts +4 -0
  13. package/dist/compare/__fixtures__/body-sequence.js +5 -3
  14. package/dist/compare/compare.d.ts +26 -2
  15. package/dist/compare/compare.js +444 -16
  16. package/dist/compare/content-alignment.js +3 -2
  17. package/dist/compare/content-types.d.ts +34 -2
  18. package/dist/compare/content.d.ts +13 -10
  19. package/dist/compare/content.js +69 -23
  20. package/dist/compare/formatting.d.ts +4 -22
  21. package/dist/compare/formatting.js +8 -112
  22. package/dist/compare/inline-atom-resources.d.ts +6 -0
  23. package/dist/compare/inline-atom-resources.js +26 -0
  24. package/dist/compare/inline-atoms.d.ts +35 -0
  25. package/dist/compare/inline-atoms.js +383 -0
  26. package/dist/compare/inline-provenance.d.ts +36 -0
  27. package/dist/compare/inline-provenance.js +334 -0
  28. package/dist/compare/plan.d.ts +4 -1
  29. package/dist/compare/plan.js +32 -4
  30. package/dist/compare/scenario.d.ts +4 -6
  31. package/dist/compare/section-boundary-properties.d.ts +63 -0
  32. package/dist/compare/section-boundary-properties.js +235 -0
  33. package/dist/compare/style-resources.d.ts +30 -0
  34. package/dist/compare/style-resources.js +404 -0
  35. package/dist/compare/types.d.ts +50 -11
  36. package/dist/compare/types.js +3 -1
  37. package/dist/compare/verification.d.ts +3 -5
  38. package/dist/compare/verification.js +8 -39
  39. package/dist/compat/eigenpal.d.ts +4 -4
  40. package/dist/compat/eigenpal.js +3 -3
  41. package/dist/controller/layoutPipeline.js +4 -0
  42. package/dist/display-list/build/buildContext.d.ts +3 -1
  43. package/dist/display-list/build/buildDisplayList.d.ts +4 -1
  44. package/dist/display-list/build/buildDisplayList.js +38 -4
  45. package/dist/display-list/build/commentAnnotations.d.ts +10 -0
  46. package/dist/display-list/build/commentAnnotations.js +17 -0
  47. package/dist/display-list/build/paragraphPrimitives.js +39 -1
  48. package/dist/display-list/primitives.d.ts +1 -1
  49. package/dist/display-list/types.d.ts +16 -1
  50. package/dist/document-operations.d.ts +5 -3
  51. package/dist/document-operations.js +112 -5
  52. package/dist/docx/blockContentParser.js +14 -2
  53. package/dist/docx/diagramPreview.d.ts +7 -0
  54. package/dist/docx/diagramPreview.js +191 -0
  55. package/dist/docx/drawingIdNormalization.js +43 -2
  56. package/dist/docx/drawingRelationships.d.ts +10 -0
  57. package/dist/docx/drawingRelationships.js +28 -0
  58. package/dist/docx/fieldParser.js +1 -1
  59. package/dist/docx/hyperlinkParser.js +3 -5
  60. package/dist/docx/imageRawXml.d.ts +8 -0
  61. package/dist/docx/imageRawXml.js +13 -0
  62. package/dist/docx/newImage.d.ts +2 -2
  63. package/dist/docx/newImage.js +3 -3
  64. package/dist/docx/numberingParser.js +30 -27
  65. package/dist/docx/paragraphParser.js +11 -4
  66. package/dist/docx/paragraphTextBoxEnrichment.js +2 -1
  67. package/dist/docx/parser.js +13 -0
  68. package/dist/docx/removeHeaderFooterParts.d.ts +14 -0
  69. package/dist/docx/removeHeaderFooterParts.js +87 -0
  70. package/dist/docx/rezip.d.ts +3 -1
  71. package/dist/docx/rezip.js +143 -41
  72. package/dist/docx/runParser.js +24 -5
  73. package/dist/docx/sectionParser.js +3 -0
  74. package/dist/docx/sectionReferenceHistory.d.ts +17 -0
  75. package/dist/docx/sectionReferenceHistory.js +59 -0
  76. package/dist/docx/selectiveSave.js +11 -31
  77. package/dist/docx/selectiveXmlPatch.d.ts +8 -1
  78. package/dist/docx/selectiveXmlPatch.js +62 -2
  79. package/dist/docx/serializer/paragraphSerializer.js +2 -0
  80. package/dist/docx/serializer/partNamespaces.d.ts +1 -1
  81. package/dist/docx/serializer/partNamespaces.js +4 -0
  82. package/dist/docx/serializer/runSerializer.js +5 -2
  83. package/dist/docx/serializer/sectionPropertiesSerializer.js +5 -2
  84. package/dist/docx/serializer/textFormattingSerializer.d.ts +1 -1
  85. package/dist/docx/serializer/textFormattingSerializer.js +3 -1
  86. package/dist/docx/tableParser.js +21 -11
  87. package/dist/docx/textBoxParser.js +25 -5
  88. package/dist/docx/xmlParser.d.ts +10 -1
  89. package/dist/docx/xmlParser.js +23 -1
  90. package/dist/export-pdf.js +2 -0
  91. package/dist/headless-layout.js +1 -0
  92. package/dist/index.d.ts +4 -4
  93. package/dist/index.js +3 -3
  94. package/dist/internal/compare/inline-presentation.d.ts +20 -0
  95. package/dist/internal/compare/inline-presentation.js +222 -0
  96. package/dist/internal/paragraphFormattingSerialization.d.ts +3 -1
  97. package/dist/internal/paragraphFormattingSerialization.js +8 -1
  98. package/dist/internal/sectionReferenceResolution.d.ts +21 -0
  99. package/dist/internal/sectionReferenceResolution.js +72 -0
  100. package/dist/layout-bridge/convert/toFlowBlocks.js +1 -0
  101. package/dist/layout-engine/index.js +5 -5
  102. package/dist/layout-engine/sectionVerticalAlignment.d.ts +7 -0
  103. package/dist/layout-engine/sectionVerticalAlignment.js +52 -0
  104. package/dist/layout-engine/types.d.ts +3 -1
  105. package/dist/markdown/renderRuns.js +1 -0
  106. package/dist/markdown/renderTable.js +1 -0
  107. package/dist/pdf/writePdf.js +37 -2
  108. package/dist/prosemirror/attrs/index.js +55 -1
  109. package/dist/prosemirror/commands/comments.d.ts +11 -1
  110. package/dist/prosemirror/commands/comments.js +68 -6
  111. package/dist/prosemirror/commands/propertyChangeScope.d.ts +9 -3
  112. package/dist/prosemirror/commands/propertyChangeScope.js +4 -10
  113. package/dist/prosemirror/conversion/fromProseDoc.js +17 -8
  114. package/dist/prosemirror/conversion/toProseDoc.js +18 -57
  115. package/dist/prosemirror/extensions/core/ParagraphExtension.js +2 -0
  116. package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.js +3 -0
  117. package/dist/prosemirror/extensions/nodes/TextBoxExtension.d.ts +2 -1
  118. package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +39 -1
  119. package/dist/prosemirror/imageCommit.js +7 -9
  120. package/dist/prosemirror/paragraphIndentation.d.ts +21 -0
  121. package/dist/prosemirror/paragraphIndentation.js +72 -0
  122. package/dist/prosemirror/plugins/documentNumbering.d.ts +3 -1
  123. package/dist/prosemirror/plugins/documentNumbering.js +7 -1
  124. package/dist/prosemirror/plugins/documentStyles.d.ts +3 -1
  125. package/dist/prosemirror/plugins/documentStyles.js +7 -1
  126. package/dist/prosemirror/rebaseParagraphRunFormatting.d.ts +3 -1
  127. package/dist/prosemirror/rebaseParagraphRunFormatting.js +2 -1
  128. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +15 -2
  129. package/dist/prosemirror/runFormattingInlineCarriers.js +33 -3
  130. package/dist/prosemirror/runStyleFormatting.d.ts +15 -2
  131. package/dist/prosemirror/runStyleFormatting.js +76 -2
  132. package/dist/prosemirror/schema/marks.d.ts +3 -1
  133. package/dist/prosemirror/schema/marks.js +2 -0
  134. package/dist/prosemirror/schema/nodes.d.ts +5 -0
  135. package/dist/prosemirror/tableCellRevisionVisibility.d.ts +6 -0
  136. package/dist/prosemirror/tableCellRevisionVisibility.js +14 -0
  137. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +1 -1
  138. package/dist/prosemirror/trackedRunInlineAtoms.js +1 -1
  139. package/dist/redline.js +15 -2
  140. package/dist/server.d.ts +2 -2
  141. package/dist/server.js +2 -2
  142. package/dist/version-comparison.d.ts +2 -0
  143. package/dist/version-comparison.js +7 -2
  144. package/package.json +2 -2
@@ -1,4 +1,5 @@
1
1
  import { Command, EditorState } from "prosemirror-state";
2
+ import { Mapping } from "prosemirror-transform";
2
3
  //#region src/prosemirror/commands/comments.d.ts
3
4
  /**
4
5
  * Add a comment mark to the current selection.
@@ -46,6 +47,15 @@ declare function rejectAllChanges(): Command;
46
47
  * mapped through concurrent edits.
47
48
  */
48
49
  declare function resolveAllChangesInHeadlessState(state: EditorState, mode: ResolveMode): EditorState;
50
+ /**
51
+ * Resolve through the editor command path when a caller must map a position in
52
+ * the reviewed document back to the tracked source. The bulk resolver is
53
+ * faster, but deliberately replaces inline content without retaining mapping.
54
+ */
55
+ declare const resolveAllChangesInHeadlessStateWithMapping: (state: EditorState, mode: ResolveMode) => {
56
+ state: EditorState;
57
+ mapping: Mapping;
58
+ };
49
59
  /**
50
60
  * Find the document range covered by all revision carriers with any of the
51
61
  * given ids. Returns null when none are present (already accepted/rejected, or
@@ -174,4 +184,4 @@ declare function findNextChange(state: EditorState, startPos: number): ChangeRan
174
184
  */
175
185
  declare function findPreviousChange(state: EditorState, startPos: number): ChangeRange | null;
176
186
  //#endregion
177
- export { AcceptSuggestionOptions, FolioSuggestion, ParagraphBoundaryChange, SuggestionAppliedAs, SuggestionKind, acceptAIEditRevision, acceptAllChanges, acceptAllSuggestions, acceptChange, acceptSuggestion, addCommentMark, findAIEditRevisionRange, findChangeAtPosition, findNextChange, findParagraphBoundaryChangeAtPosition, findPreviousChange, findSuggestionRange, getSuggestions, rejectAIEditRevision, rejectAllChanges, rejectAllSuggestions, rejectChange, rejectSuggestion, removeCommentMark, resolveAllChangesInHeadlessState };
187
+ export { AcceptSuggestionOptions, FolioSuggestion, ParagraphBoundaryChange, SuggestionAppliedAs, SuggestionKind, acceptAIEditRevision, acceptAllChanges, acceptAllSuggestions, acceptChange, acceptSuggestion, addCommentMark, findAIEditRevisionRange, findChangeAtPosition, findNextChange, findParagraphBoundaryChangeAtPosition, findPreviousChange, findSuggestionRange, getSuggestions, rejectAIEditRevision, rejectAllChanges, rejectAllSuggestions, rejectChange, rejectSuggestion, removeCommentMark, resolveAllChangesInHeadlessState, resolveAllChangesInHeadlessStateWithMapping };
@@ -12,12 +12,14 @@ import { RUN_FORMATTING_MARK_NAMES } from "../runFormattingMarkNames.js";
12
12
  import { reconstructRejectedRunFormattingMarks } from "../runPropertyChangeResolution.js";
13
13
  import { paragraphRunStyleContextAt } from "../runStyleFormatting.js";
14
14
  import { getTableCellMergeChange } from "../tableCellMergeRevision.js";
15
+ import { isTableCellRetainedInReviewView } from "../tableCellRevisionVisibility.js";
15
16
  import { reconcileTableGridAfterColumnRemoval } from "../tableGridMutation.js";
16
17
  import { holdsNoContent } from "../zeroWidthAnchors.js";
17
18
  import { hasSerializableParagraphPropertyChange, paragraphPropertiesSnapshot, paragraphRejectAttrPatch, paragraphRejectOriginalFormatting, removeParagraphPropertyChanges, sectionRejectProperties, tableCellRejectAttrPatch, tableRejectAttrPatch, tableRowRejectAttrPatch } from "./propertyChangeScope.js";
18
19
  import { hasMatchingCollapsedTableCellMerge, resolveCollapsedTableCellMerge, resolveVisibleTableCellMerge } from "./tableCellMergeResolution.js";
19
20
  import { TableMap, removeRow } from "prosemirror-tables";
20
- import { PARAGRAPH_MARK_CHANGE_KINDS } from "@stll/docx-core/model";
21
+ import { Mapping } from "prosemirror-transform";
22
+ import { PARAGRAPH_MARK_CHANGE_KINDS, REVIEW_CARRIERS } from "@stll/docx-core/model";
21
23
  //#region src/prosemirror/commands/comments.ts
22
24
  /**
23
25
  * Add a comment mark to the current selection.
@@ -120,7 +122,11 @@ function resolveChange(from, to, mode, revisionIds, execution = "legacy") {
120
122
  if (matches.length > 0) {
121
123
  const remaining = sectionChanges.filter((c) => revisionSet !== null && (!c.info || !revisionSet.has(c.info.id)));
122
124
  let restored = { ...sectionProperties };
123
- if (mode === "reject") for (const change of matches.toReversed()) restored = sectionRejectProperties(restored, change.previousProperties);
125
+ if (mode === "reject") for (const change of matches.toReversed()) restored = sectionRejectProperties({
126
+ live: restored,
127
+ previousProperties: change.previousProperties,
128
+ previousReferences: change.previousReferences
129
+ });
124
130
  delete restored.propertyChanges;
125
131
  if (remaining.length > 0) restored.propertyChanges = remaining;
126
132
  nextAttrs = nextAttrs ?? { ...node.attrs };
@@ -132,7 +138,12 @@ function resolveChange(from, to, mode, revisionIds, execution = "legacy") {
132
138
  nextAttrs,
133
139
  paragraphPosition: pos,
134
140
  styleResolver,
135
- tr
141
+ tr,
142
+ ...mode === "reject" && { shouldRebase: (inline) => {
143
+ const deleted = inline.marks.some(({ type }) => type.name === "deletion");
144
+ const direct = inline.marks.some(({ type }) => type.name === "runFormattingOverride");
145
+ return !deleted || !direct;
146
+ } }
136
147
  });
137
148
  else tr.setNodeMarkup(pos, void 0, nextAttrs);
138
149
  return true;
@@ -309,11 +320,45 @@ function resolveChange(from, to, mode, revisionIds, execution = "legacy") {
309
320
  removedEndpointCount: removedSectionEndpointCount,
310
321
  removedReferences: removedSectionReferences
311
322
  });
323
+ if (!terminalTableDeletionIsPending(tr)) resolveTerminalTableReviewCarrier(tr, mode);
312
324
  if (tr.steps.length > 0) dispatch(tr);
313
325
  }
314
326
  return true;
315
327
  };
316
328
  }
329
+ /**
330
+ * The receiver belongs to the deleted terminal table, not every revision in
331
+ * the document. Keep it through independently resolved changes, then resolve
332
+ * it as soon as that table's deletion has been decided.
333
+ */
334
+ const terminalTableDeletionIsPending = (tr) => {
335
+ let terminalTable = null;
336
+ for (let index = tr.doc.childCount - 1; index >= 0; index--) {
337
+ const node = tr.doc.child(index);
338
+ if (node.type.name === "table") {
339
+ terminalTable = node;
340
+ break;
341
+ }
342
+ }
343
+ if (terminalTable === null) return false;
344
+ let pending = false;
345
+ terminalTable.descendants((node) => {
346
+ pending ||= node.type.name === "tableRow" && isTableRowRevisionAttr(node.attrs["trDel"]) || node.type.name !== "tableRow" && node.marks.some((mark) => mark.type.name === "deletion");
347
+ return !pending;
348
+ });
349
+ return pending;
350
+ };
351
+ /** Resolve the Folio-only receiver Word needs after a terminal deleted table. */
352
+ const resolveTerminalTableReviewCarrier = (tr, mode) => {
353
+ const carrier = tr.doc.lastChild;
354
+ if (carrier?.type.name !== "paragraph" || carrier.attrs["reviewCarrier"] !== REVIEW_CARRIERS.TERMINAL_TABLE) return;
355
+ const position = tr.doc.content.size - carrier.nodeSize;
356
+ if (mode === "accept") {
357
+ tr.setNodeAttribute(position, "reviewCarrier", void 0);
358
+ return;
359
+ }
360
+ tr.delete(position, position + carrier.nodeSize);
361
+ };
317
362
  const resolveRunPropertyChange = ({ tr, node, from, to, mark, mode, revisionSet, styleResolver }) => {
318
363
  const { changes } = expectRunPropertyChangeMarkAttrs(mark);
319
364
  const matches = changes.filter((change) => revisionSet === null || revisionSet.has(change.info.id));
@@ -401,11 +446,11 @@ function collectTableCellStructuralOps(node, cellPos, mode, revisionSet) {
401
446
  revisionSet
402
447
  });
403
448
  else {
404
- const keepsCell = marker.kind === "ins" === (mode === "accept");
449
+ const view = mode === "accept" ? "final" : "original";
405
450
  operations.push({
406
451
  type: "membership",
407
452
  cellPos,
408
- action: keepsCell ? "clear" : "remove"
453
+ action: isTableCellRetainedInReviewView(marker.kind, view) ? "clear" : "remove"
409
454
  });
410
455
  }
411
456
  if (hasMatchingCollapsedTableCellMerge(node, revisionSet)) operations.push({
@@ -671,6 +716,23 @@ function resolveAllChangesInHeadlessState(state, mode) {
671
716
  return resolvedState;
672
717
  }
673
718
  /**
719
+ * Resolve through the editor command path when a caller must map a position in
720
+ * the reviewed document back to the tracked source. The bulk resolver is
721
+ * faster, but deliberately replaces inline content without retaining mapping.
722
+ */
723
+ const resolveAllChangesInHeadlessStateWithMapping = (state, mode) => {
724
+ let resolvedState = state;
725
+ let mapping = new Mapping();
726
+ resolveChange(0, state.doc.content.size, mode)(state, (transaction) => {
727
+ resolvedState = state.apply(transaction);
728
+ mapping = transaction.mapping;
729
+ });
730
+ return {
731
+ state: resolvedState,
732
+ mapping
733
+ };
734
+ };
735
+ /**
674
736
  * Find the document range covered by all revision carriers with any of the
675
737
  * given ids. Returns null when none are present (already accepted/rejected, or
676
738
  * never existed). A replace operation typically passes two ids; standalone
@@ -1664,4 +1726,4 @@ function findPreviousChange(state, startPos) {
1664
1726
  return result.value;
1665
1727
  }
1666
1728
  //#endregion
1667
- export { acceptAIEditRevision, acceptAllChanges, acceptAllSuggestions, acceptChange, acceptSuggestion, addCommentMark, findAIEditRevisionRange, findChangeAtPosition, findNextChange, findParagraphBoundaryChangeAtPosition, findPreviousChange, findSuggestionRange, getSuggestions, rejectAIEditRevision, rejectAllChanges, rejectAllSuggestions, rejectChange, rejectSuggestion, removeCommentMark, resolveAllChangesInHeadlessState };
1729
+ export { acceptAIEditRevision, acceptAllChanges, acceptAllSuggestions, acceptChange, acceptSuggestion, addCommentMark, findAIEditRevisionRange, findChangeAtPosition, findNextChange, findParagraphBoundaryChangeAtPosition, findPreviousChange, findSuggestionRange, getSuggestions, rejectAIEditRevision, rejectAllChanges, rejectAllSuggestions, rejectChange, rejectSuggestion, removeCommentMark, resolveAllChangesInHeadlessState, resolveAllChangesInHeadlessStateWithMapping };
@@ -66,10 +66,16 @@ declare function paragraphRejectOriginalFormatting(previousFormatting: Paragraph
66
66
  * Rejected section properties: the stored old sectPr wholesale, preserving
67
67
  * the live header/footer references — `EG_HdrFtrReferences` is not part of
68
68
  * the `CT_SectPrBase` payload a `w:sectPrChange` stores (ECMA-376
69
- * §17.13.5.32), so those children survive a reject. The caller re-attaches
70
- * whatever `propertyChanges` remain unresolved.
69
+ * §17.13.5.32), so those children survive a native reject. An explicit Folio reference
70
+ * history replaces that selection, including restoring its absence. The
71
+ * caller re-attaches whatever `propertyChanges` remain unresolved.
71
72
  */
72
- declare function sectionRejectProperties(live: document_d_exports.SectionProperties, previousProperties: document_d_exports.SectionProperties | undefined): document_d_exports.SectionProperties;
73
+ type SectionRejectPropertiesOptions = {
74
+ live: document_d_exports.SectionProperties;
75
+ previousProperties: document_d_exports.SectionProperties | undefined;
76
+ previousReferences?: document_d_exports.SectionPropertyChange["previousReferences"];
77
+ };
78
+ declare function sectionRejectProperties({ live, previousProperties, previousReferences }: SectionRejectPropertiesOptions): document_d_exports.SectionProperties;
73
79
  /**
74
80
  * Attr patch for rejecting a `w:tblPrChange`: the stored old tblPr wholesale
75
81
  * (`w:tblPrChange` stores the complete previous tblPr, so every tblPr-derived
@@ -220,19 +220,13 @@ function paragraphRejectOriginalFormatting(previousFormatting, liveOriginal) {
220
220
  if (Object.keys(result).length === 0) return null;
221
221
  return result;
222
222
  }
223
- /**
224
- * Rejected section properties: the stored old sectPr wholesale, preserving
225
- * the live header/footer references — `EG_HdrFtrReferences` is not part of
226
- * the `CT_SectPrBase` payload a `w:sectPrChange` stores (ECMA-376
227
- * §17.13.5.32), so those children survive a reject. The caller re-attaches
228
- * whatever `propertyChanges` remain unresolved.
229
- */
230
- function sectionRejectProperties(live, previousProperties) {
223
+ function sectionRejectProperties({ live, previousProperties, previousReferences }) {
231
224
  const restored = { ...previousProperties };
232
225
  delete restored.propertyChanges;
233
- if (live.headerReferences) restored.headerReferences = live.headerReferences;
226
+ const references = previousReferences ?? live;
227
+ if (references.headerReferences) restored.headerReferences = references.headerReferences;
234
228
  else delete restored.headerReferences;
235
- if (live.footerReferences) restored.footerReferences = live.footerReferences;
229
+ if (references.footerReferences) restored.footerReferences = references.footerReferences;
236
230
  else delete restored.footerReferences;
237
231
  return restored;
238
232
  }
@@ -1,8 +1,9 @@
1
+ import { imageRawXmlFingerprint } from "../../docx/imageRawXml.js";
1
2
  import { PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, ParagraphPropertySourceValidationError, copyDocumentParagraphPropertySourceContract, copyDocumentParagraphPropertySources, copyParagraphPropertyCapture, copyParagraphPropertySource, decodeTableCellParagraphSourcePayload, getDocumentParagraphPropertySourceContract, getParagraphPropertySource, getParagraphPropertySourceCandidate, getParagraphPropertySourceToken, getParagraphPropertySourceTransferId, getProseDocumentParagraphPropertySourceContract, getProseParagraphPropertySourceToken, isParagraphPropertySourceToken, linkParagraphPropertySourceCandidate, paragraphPropertySourceBelongsToDocument, paragraphPropertySourceTokenMatchesContract, recreateProseNodeWithParagraphPropertySource, restoreTableCellsWithParagraphPropertySources, visitDocumentStoryParagraphs, visitTableCellParagraphPropertySourceBindings } from "../../docx/paragraphPropertySource.js";
2
3
  import { visitDocxParagraphs } from "../../docx/paragraphTraversal.js";
3
4
  import { ShapeOutlineStyleSchema, narrowEnum } from "../../docx/parserEnums.js";
4
5
  import { DATE_UTC_ATTRIBUTE } from "../../docx/trackedChangeInfo.js";
5
- import { isStyleSourcedParagraphNumbering, modelParagraphFormattingEmission, paragraphNumberingReferencesEqual } from "../../internal/paragraphFormattingSerialization.js";
6
+ import { isStyleSourcedParagraphNumbering, modelParagraphFormattingEmission, sameAuthoredParagraphNumberingReference } from "../../internal/paragraphFormattingSerialization.js";
6
7
  import { createStyleEngine } from "../../style-engine/styleEngine.js";
7
8
  import { OUTLINE_STYLE_CSS_ALIASES, normalizeShapeTextAnchor } from "../../types/documentEnumValues.js";
8
9
  import { canonicalJson } from "../../utils/canonicalJson.js";
@@ -742,6 +743,7 @@ function convertPMParagraph(node, documentCounts, textBoxAnchorMarkers, styleRes
742
743
  };
743
744
  if (attrs.paraId) paragraph.paraId = attrs.paraId;
744
745
  if (attrs.textId) paragraph.textId = attrs.textId;
746
+ if (attrs.reviewCarrier) paragraph.reviewCarrier = attrs.reviewCarrier;
745
747
  const pFormatting = paragraphAttrsToFormatting(attrs);
746
748
  if (pFormatting) paragraph.formatting = pFormatting;
747
749
  const listRendering = listRenderingFromAttrs(attrs);
@@ -829,7 +831,7 @@ function paragraphAttrsToFormatting(attrs) {
829
831
  if (isStyleSourcedParagraphNumbering(attrs.numPr, attrs.numPrFromStyle)) {
830
832
  delete result.numPr;
831
833
  delete result.numPrFromStyle;
832
- } else if (attrs.numPr !== orig.numPr && !paragraphNumberingReferencesEqual(attrs.numPr, orig.numPr)) {
834
+ } else if (attrs.numPr !== orig.numPr && !sameAuthoredParagraphNumberingReference(attrs.numPr, orig.numPr)) {
833
835
  if (attrs.numPr) result.numPr = attrs.numPr;
834
836
  else delete result.numPr;
835
837
  delete result.numPrFromStyle;
@@ -1137,6 +1139,10 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
1137
1139
  }));
1138
1140
  return;
1139
1141
  }
1142
+ if (node.type.name === "math") {
1143
+ currentTrackedChange.wrapper.content.push(createMathFromNode(node));
1144
+ return;
1145
+ }
1140
1146
  const run = createTrackedChangeRun({
1141
1147
  ...formattingContext,
1142
1148
  marks: otherMarks,
@@ -1710,9 +1716,6 @@ function createFieldFromNode(node, { baseParagraphFormatting, inheritedFormattin
1710
1716
  case "NUMPAGES":
1711
1717
  displayText = "1";
1712
1718
  break;
1713
- default:
1714
- displayText = " ";
1715
- break;
1716
1719
  }
1717
1720
  const displayRun = {
1718
1721
  type: "run",
@@ -1724,13 +1727,14 @@ function createFieldFromNode(node, { baseParagraphFormatting, inheritedFormattin
1724
1727
  };
1725
1728
  if (marks && node.type.name === "field") restoreRunPropertyChanges(displayRun, marks);
1726
1729
  const fieldContent = extractedContent.length > 0 ? synchronizeFieldDisplayText(extractedContent, displayText, displayRun) : [];
1730
+ const fallbackFieldContent = displayText ? [displayRun] : [];
1727
1731
  if (attrs.fieldKind === "complex") {
1728
1732
  const complex = {
1729
1733
  type: "complexField",
1730
1734
  instruction: attrs.instruction,
1731
1735
  fieldType: attrs.fieldType,
1732
1736
  fieldCode: [],
1733
- fieldResult: fieldContent.length > 0 ? fieldContent.filter((content) => content.type === "run") : [displayRun]
1737
+ fieldResult: fieldContent.length > 0 ? fieldContent.filter((content) => content.type === "run") : fallbackFieldContent
1734
1738
  };
1735
1739
  if (attrs.fldLock) complex.fldLock = true;
1736
1740
  if (attrs.dirty) complex.dirty = true;
@@ -1740,7 +1744,7 @@ function createFieldFromNode(node, { baseParagraphFormatting, inheritedFormattin
1740
1744
  type: "simpleField",
1741
1745
  instruction: attrs.instruction,
1742
1746
  fieldType: attrs.fieldType,
1743
- content: fieldContent.length > 0 ? fieldContent : [displayRun]
1747
+ content: fieldContent.length > 0 ? fieldContent : fallbackFieldContent
1744
1748
  };
1745
1749
  if (attrs.fldLock) simple.fldLock = true;
1746
1750
  if (attrs.dirty) simple.dirty = true;
@@ -1873,7 +1877,8 @@ function createImageRun(node) {
1873
1877
  } : {
1874
1878
  type: "drawing",
1875
1879
  image,
1876
- ...attrs._docxRawXml ? { rawXml: attrs._docxRawXml } : {}
1880
+ ...attrs._docxRawXml ? { rawXml: attrs._docxRawXml } : {},
1881
+ ...attrs._docxRawXml ? { rawImageFingerprint: imageRawXmlFingerprint(image) } : {}
1877
1882
  }]
1878
1883
  };
1879
1884
  }
@@ -1959,6 +1964,7 @@ const RUN_FORMATTING_VISUAL_GROUPS = {
1959
1964
  smallCaps: "smallCaps",
1960
1965
  allCaps: "allCaps",
1961
1966
  hidden: "hidden",
1967
+ noProof: null,
1962
1968
  color: "color",
1963
1969
  highlight: "highlight",
1964
1970
  shading: "shading",
@@ -1992,6 +1998,7 @@ const RUN_FORMATTING_FAST_PATH_DISPOSITION = {
1992
1998
  smallCaps: "visual",
1993
1999
  allCaps: "visual",
1994
2000
  hidden: "visual",
2001
+ noProof: "structural",
1995
2002
  color: "visual",
1996
2003
  highlight: "visual",
1997
2004
  shading: "visual",
@@ -2181,6 +2188,7 @@ const DIRECT_OVERRIDE_FORMATTING_PROPERTIES = [
2181
2188
  "emboss",
2182
2189
  "fontSizeCs",
2183
2190
  "hidden",
2191
+ "noProof",
2184
2192
  "imprint",
2185
2193
  "italic",
2186
2194
  "italicCs",
@@ -2894,6 +2902,7 @@ function convertPMTextBox(node, styleResolver = null) {
2894
2902
  },
2895
2903
  textBody: {
2896
2904
  content: textBodyContent.type === "source-empty" ? [] : textBodyContent.content,
2905
+ ...attrs.wordArt !== void 0 ? { wordArt: attrs.wordArt } : {},
2897
2906
  ...attrs.autoFit !== void 0 ? { autoFit: attrs.autoFit } : {},
2898
2907
  ...attrs.textWrap !== void 0 ? { textWrap: attrs.textWrap } : {},
2899
2908
  ...verticalAlign !== void 0 ? { anchor: verticalAlign } : {},
@@ -13,7 +13,7 @@ import { stampNumberedRefFieldBaselines } from "../numberedRefFields.js";
13
13
  import { pageBreakRunParagraphProjectionDispositionForFeatures } from "../pageBreakRunProjection.js";
14
14
  import { directionFromBidi } from "../paragraphDirection.js";
15
15
  import { lineSpacingProvenanceFromSpacing } from "../paragraphSpacing.js";
16
- import { getParagraphMarkSuppressionOverrides, hasDirectRunFormatting, stripParagraphMarkFormattingForBodyRuns, stripParagraphMarkOnlyFormatting, suppressParagraphMarkFormatting } from "../runStyleFormatting.js";
16
+ import { getParagraphMarkSuppressionOverrides, hasDirectRunFormatting, resolveParagraphBodyRunFormatting, stripParagraphMarkFormattingForBodyRuns, stripParagraphMarkOnlyFormatting, suppressParagraphMarkFormatting } from "../runStyleFormatting.js";
17
17
  import { schema } from "../schema/index.js";
18
18
  import { COMPLEX_SCRIPT_RUN_PROPERTY_KEYS } from "../schema/marks.js";
19
19
  import { cascadeStyleTextFormatting } from "../styles/styleToggleCascade.js";
@@ -202,45 +202,14 @@ function convertParagraph(paragraph, styleResolver, context, activeCommentIds, e
202
202
  if (!node) return;
203
203
  emitInlineNodes([node]);
204
204
  };
205
- let styleRunFormatting;
206
- let paragraphStyleRunFormatting;
207
- let paragraphStyleFontFamily;
208
- if (styleResolver) {
209
- const resolved = styleResolver.resolveParagraphStyle(paragraph.formatting?.styleId);
210
- styleRunFormatting = extraRunFormatting === void 0 ? resolved.runFormatting : withoutFontFamily(resolved.runFormatting);
211
- const paragraphStyle = paragraph.formatting?.styleId ? styleResolver.getStyle(paragraph.formatting.styleId) ?? styleResolver.getDefaultParagraphStyle() : styleResolver.getDefaultParagraphStyle();
212
- paragraphStyleRunFormatting = paragraphStyle?.type === "paragraph" ? paragraphStyle.rPr : void 0;
213
- paragraphStyleFontFamily = resolveParagraphStyleFontFamily(paragraph.formatting?.styleId, styleResolver);
214
- }
215
205
  const paragraphRunFormatting = resolveRunFormattingWithoutDefaults(paragraph.formatting?.runProperties, styleResolver);
216
206
  let inheritableParagraphRunFormatting;
217
207
  if (paragraphRunFormatting && !isTocParagraph && paragraph.formatting?.styleId === void 0) inheritableParagraphRunFormatting = stripParagraphMarkFormattingForBodyRuns(paragraphRunFormatting);
218
- const ordinaryStyleFormatting = paragraph.formatting?.styleId === void 0 ? mergeTextFormatting(styleRunFormatting, extraRunFormatting) : mergeTextFormatting(extraRunFormatting, styleRunFormatting);
219
- const orderedToggleFormatting = cascadeStyleTextFormatting([
220
- {
221
- formatting: styleResolver?.getDocDefaults()?.rPr,
222
- type: "defaults"
223
- },
224
- {
225
- formatting: extraRunFormatting,
226
- type: "style"
227
- },
228
- {
229
- formatting: paragraphStyleRunFormatting,
230
- type: "style"
231
- }
232
- ], { ordinaryFormatting: ordinaryStyleFormatting });
233
- let baseRunFormatting = orderedToggleFormatting.formatting;
234
- if (paragraphStyleFontFamily) baseRunFormatting = mergeTextFormatting(baseRunFormatting, { fontFamily: paragraphStyleFontFamily });
235
- const defaultCharacterFormatting = styleResolver?.getDefaultCharacterStyle()?.rPr;
236
- const ordinaryBaseWithDefaultCharacter = mergeTextFormatting(defaultCharacterFormatting, baseRunFormatting);
237
- const defaultCharacterStyleCascade = cascadeStyleTextFormatting([{
238
- cascade: orderedToggleFormatting,
239
- type: "carried"
240
- }, {
241
- formatting: defaultCharacterFormatting,
242
- type: "style"
243
- }], { ordinaryFormatting: ordinaryBaseWithDefaultCharacter });
208
+ const { baseFormatting: baseRunFormatting, baseToggleCascade: orderedToggleFormatting, defaultFormatting: ordinaryBaseWithDefaultCharacter, defaultToggleCascade: defaultCharacterStyleCascade } = resolveParagraphBodyRunFormatting({
209
+ styleId: paragraph.formatting?.styleId,
210
+ tableRunFormatting: extraRunFormatting,
211
+ styleResolver
212
+ });
244
213
  const ordinaryDefaultRunFormatting = mergeTextFormatting(ordinaryBaseWithDefaultCharacter, inheritableParagraphRunFormatting);
245
214
  const defaultToggleCascade = cascadeStyleTextFormatting([{
246
215
  cascade: defaultCharacterStyleCascade,
@@ -250,8 +219,11 @@ function convertParagraph(paragraph, styleResolver, context, activeCommentIds, e
250
219
  type: "direct"
251
220
  }], { ordinaryFormatting: ordinaryDefaultRunFormatting });
252
221
  const defaultRunFormatting = defaultToggleCascade.formatting;
253
- if (extraRunFormatting !== void 0) if (defaultRunFormatting) attrs.defaultTextFormatting = defaultRunFormatting;
254
- else delete attrs.defaultTextFormatting;
222
+ if (extraRunFormatting !== void 0) {
223
+ attrs._tableRunFormatting = extraRunFormatting;
224
+ if (defaultRunFormatting) attrs.defaultTextFormatting = defaultRunFormatting;
225
+ else delete attrs.defaultTextFormatting;
226
+ }
255
227
  const getInheritedRunFormatting = (formatting, fieldType) => {
256
228
  const hasCharacterStyle = formatting?.styleId !== void 0;
257
229
  const inheritedBaseFormatting = hasCharacterStyle ? baseRunFormatting : ordinaryBaseWithDefaultCharacter;
@@ -350,24 +322,6 @@ function convertParagraph(paragraph, styleResolver, context, activeCommentIds, e
350
322
  content: inlineNodes
351
323
  });
352
324
  }
353
- const withoutFontFamily = (formatting) => {
354
- if (!formatting?.fontFamily) return formatting;
355
- const { fontFamily: _fontFamily, ...withoutFont } = formatting;
356
- return Object.keys(withoutFont).length > 0 ? withoutFont : void 0;
357
- };
358
- const resolveParagraphStyleFontFamily = (styleId, styleResolver) => {
359
- let style = styleId ? styleResolver.getStyle(styleId) : styleResolver.getDefaultParagraphStyle();
360
- const visited = /* @__PURE__ */ new Set();
361
- const styleChain = [];
362
- while (style?.type === "paragraph" && !visited.has(style.styleId)) {
363
- visited.add(style.styleId);
364
- if (style.rPr?.fontFamily) styleChain.push({ fontFamily: style.rPr.fontFamily });
365
- style = style.basedOn ? styleResolver.getStyle(style.basedOn) : void 0;
366
- }
367
- let formatting;
368
- for (const styleFormatting of styleChain.toReversed()) formatting = mergeTextFormatting(formatting, styleFormatting);
369
- return formatting?.fontFamily;
370
- };
371
325
  /**
372
326
  * Apply comment marks to PM nodes within a comment range.
373
327
  */
@@ -418,6 +372,9 @@ function convertTrackedChange(change, markType, nextHyperlinkInstanceIndex, next
418
372
  textBoxAnchors
419
373
  });
420
374
  if (fieldNode) nodes.push(fieldNode);
375
+ } else if (item.type === "mathEquation") {
376
+ const mathNode = convertMathEquation(item);
377
+ if (mathNode) nodes.push(mathNode);
421
378
  } else if (item.type === "insertion" || item.type === "deletion" || item.type === "moveFrom" || item.type === "moveTo") {
422
379
  const nestedMarkType = item.type === "insertion" || item.type === "moveTo" ? "insertion" : "deletion";
423
380
  const nestedMoveKind = item.type === "moveFrom" || item.type === "moveTo" ? item.type : null;
@@ -460,6 +417,7 @@ function paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOver
460
417
  const attrs = {};
461
418
  if (paragraph.paraId) attrs.paraId = paragraph.paraId;
462
419
  if (paragraph.textId) attrs.textId = paragraph.textId;
420
+ if (paragraph.reviewCarrier) attrs.reviewCarrier = paragraph.reviewCarrier;
463
421
  if (styleId) attrs.styleId = styleId;
464
422
  if (tableOfContentsLevel !== void 0) attrs._tableOfContentsLevel = tableOfContentsLevel;
465
423
  if (formatting?.numPr) attrs.numPr = formatting.numPr;
@@ -1415,6 +1373,7 @@ const RUN_FORMATTING_INFERENCE = {
1415
1373
  smallCaps: "visible-boolean",
1416
1374
  allCaps: "visible-boolean",
1417
1375
  hidden: "visible-boolean",
1376
+ noProof: "structural",
1418
1377
  color: "color",
1419
1378
  highlight: "visible-value",
1420
1379
  shading: "preserve",
@@ -2152,6 +2111,7 @@ function textBoxFromShape(shape, textBody) {
2152
2111
  if (textBody.autoFit) textBox.autoFit = textBody.autoFit;
2153
2112
  if (textBody.textWrap) textBox.textWrap = textBody.textWrap;
2154
2113
  if (textBody.anchor) textBox.verticalAlign = textBody.anchor;
2114
+ if (textBody.wordArt) textBox.wordArt = textBody.wordArt;
2155
2115
  return textBox;
2156
2116
  }
2157
2117
  /**
@@ -2235,6 +2195,7 @@ function convertTextBox(textBox, styleResolver, options) {
2235
2195
  width: widthPx,
2236
2196
  height: heightPx,
2237
2197
  autoFit: textBox.autoFit,
2198
+ wordArt: textBox.wordArt,
2238
2199
  textWrap: textBox.textWrap,
2239
2200
  verticalAlign: textBox.verticalAlign,
2240
2201
  textBoxId: textBox.id,
@@ -188,6 +188,7 @@ const paragraphNodeSpec = {
188
188
  [PROSE_PARAGRAPH_SOURCE_TOKEN_ATTR]: { default: null },
189
189
  idStability: { default: void 0 },
190
190
  textId: { default: null },
191
+ reviewCarrier: { default: void 0 },
191
192
  alignment: { default: null },
192
193
  alignmentFromStyle: { default: void 0 },
193
194
  kinsoku: { default: null },
@@ -240,6 +241,7 @@ const paragraphNodeSpec = {
240
241
  contextualSpacing: { default: null },
241
242
  runInWithNext: { default: null },
242
243
  defaultTextFormatting: { default: null },
244
+ _tableRunFormatting: { default: void 0 },
243
245
  sectionBreakType: { default: null },
244
246
  direction: { default: null },
245
247
  outlineLevel: { default: null },
@@ -19,6 +19,7 @@ function buildRunFormattingOverrideAttrs(formatting, options) {
19
19
  if (formatting?.allCaps !== void 0) attrs.allCaps = formatting.allCaps;
20
20
  if (formatting?.smallCaps !== void 0) attrs.smallCaps = formatting.smallCaps;
21
21
  if (formatting?.hidden !== void 0) attrs.hidden = formatting.hidden;
22
+ if (formatting?.noProof !== void 0) attrs.noProof = formatting.noProof;
22
23
  if (formatting?.emboss !== void 0) attrs.emboss = formatting.emboss;
23
24
  if (formatting?.imprint !== void 0) attrs.imprint = formatting.imprint;
24
25
  if (formatting?.shadow !== void 0) attrs.shadow = formatting.shadow;
@@ -58,6 +59,7 @@ function applyRunFormattingOverrideAttrs(formatting, attrs) {
58
59
  if (attrs.allCaps !== void 0) formatting.allCaps = attrs.allCaps;
59
60
  if (attrs.smallCaps !== void 0) formatting.smallCaps = attrs.smallCaps;
60
61
  if (attrs.hidden !== void 0) formatting.hidden = attrs.hidden;
62
+ if (attrs.noProof !== void 0) formatting.noProof = attrs.noProof;
61
63
  if (attrs.emboss !== void 0) formatting.emboss = attrs.emboss;
62
64
  if (attrs.imprint !== void 0) formatting.imprint = attrs.imprint;
63
65
  if (attrs.shadow !== void 0) formatting.shadow = attrs.shadow;
@@ -101,6 +103,7 @@ const RunFormattingOverrideExtension = createMarkExtension({
101
103
  allCaps: { default: null },
102
104
  smallCaps: { default: null },
103
105
  hidden: { default: null },
106
+ noProof: { default: null },
104
107
  emboss: { default: null },
105
108
  imprint: { default: null },
106
109
  shadow: { default: null },
@@ -2,6 +2,7 @@ import { TextBoxAttrs as TextBoxAttrs$1 } from "../../schema/nodes.js";
2
2
  import { NodeExtension } from "../types.js";
3
3
  //#region src/prosemirror/extensions/nodes/TextBoxExtension.d.ts
4
4
  type TextBoxAttrs = TextBoxAttrs$1;
5
+ declare function parseTextBoxWordArt(raw: string): TextBoxAttrs["wordArt"];
5
6
  declare const TextBoxExtension: (options?: Partial<Record<string, unknown>> | undefined) => NodeExtension;
6
7
  //#endregion
7
- export { TextBoxAttrs, TextBoxExtension };
8
+ export { TextBoxAttrs, TextBoxExtension, parseTextBoxWordArt };
@@ -31,6 +31,41 @@ function parseTextBoxTextWrap(raw) {
31
31
  function parseTextBoxVerticalAlign(raw) {
32
32
  return normalizeShapeTextAnchor(raw);
33
33
  }
34
+ function parseTextBoxWordArt(raw) {
35
+ try {
36
+ const parsed = JSON.parse(raw);
37
+ if (typeof parsed !== "object" || parsed === null) return;
38
+ const wordArt = {};
39
+ const fromWordArt = Reflect.get(parsed, "fromWordArt");
40
+ if (fromWordArt !== void 0) {
41
+ if (typeof fromWordArt !== "boolean") return void 0;
42
+ wordArt.fromWordArt = fromWordArt;
43
+ }
44
+ const preset = Reflect.get(parsed, "preset");
45
+ if (preset !== void 0) {
46
+ if (typeof preset !== "string") return void 0;
47
+ wordArt.preset = preset;
48
+ }
49
+ const adjustments = Reflect.get(parsed, "adjustments");
50
+ if (adjustments !== void 0) {
51
+ if (!Array.isArray(adjustments)) return void 0;
52
+ const validAdjustments = [];
53
+ for (const adjustment of adjustments) {
54
+ if (typeof adjustment !== "object" || adjustment === null) continue;
55
+ const name = Reflect.get(adjustment, "name");
56
+ const formula = Reflect.get(adjustment, "formula");
57
+ if (typeof name === "string" && typeof formula === "string") validAdjustments.push({
58
+ name,
59
+ formula
60
+ });
61
+ }
62
+ if (validAdjustments.length > 0) wordArt.adjustments = validAdjustments;
63
+ }
64
+ return wordArt.fromWordArt !== void 0 || wordArt.preset !== void 0 || wordArt.adjustments !== void 0 ? wordArt : void 0;
65
+ } catch {
66
+ return;
67
+ }
68
+ }
34
69
  const TextBoxExtension = createNodeExtension({
35
70
  name: "textBox",
36
71
  schemaNodeName: "textBox",
@@ -43,6 +78,7 @@ const TextBoxExtension = createNodeExtension({
43
78
  width: { default: 200 },
44
79
  height: { default: null },
45
80
  autoFit: { default: null },
81
+ wordArt: { default: null },
46
82
  textWrap: { default: null },
47
83
  textBoxId: { default: null },
48
84
  fillColor: { default: null },
@@ -86,6 +122,7 @@ const TextBoxExtension = createNodeExtension({
86
122
  ...d["width"] ? { width: Number(d["width"]) } : {},
87
123
  ...d["height"] ? { height: Number(d["height"]) } : {},
88
124
  ...autoFit ? { autoFit } : {},
125
+ ...d["wordArt"] ? { wordArt: parseTextBoxWordArt(d["wordArt"]) } : {},
89
126
  ...textWrap ? { textWrap } : {},
90
127
  ...d["textboxId"] ? { textBoxId: d["textboxId"] } : {},
91
128
  ...d["fillColor"] ? { fillColor: d["fillColor"] } : {},
@@ -113,6 +150,7 @@ const TextBoxExtension = createNodeExtension({
113
150
  toDOM(node) {
114
151
  const attrs = expectTextBoxAttrs(node);
115
152
  const domAttrs = { class: "docx-textbox" };
153
+ if (attrs.wordArt) domAttrs["data-word-art"] = JSON.stringify(attrs.wordArt);
116
154
  if (attrs.width) domAttrs["data-width"] = String(attrs.width);
117
155
  if (attrs.height) domAttrs["data-height"] = String(attrs.height);
118
156
  if (attrs.autoFit) domAttrs["data-auto-fit"] = attrs.autoFit;
@@ -184,4 +222,4 @@ const TextBoxExtension = createNodeExtension({
184
222
  }
185
223
  });
186
224
  //#endregion
187
- export { TextBoxExtension };
225
+ export { TextBoxExtension, parseTextBoxWordArt };
@@ -1,3 +1,5 @@
1
+ import { expectImageAttrs, mergeImageAttrs } from "./attrs/index.js";
2
+ import { DRAWING_RAW_XML_MODES } from "@stll/docx-core/model";
1
3
  //#region src/prosemirror/imageCommit.ts
2
4
  const MIN_IMAGE_PX = 20;
3
5
  const MAX_IMAGE_PX = 2e3;
@@ -40,6 +42,7 @@ function isFloatingImage(node) {
40
42
  function imageNodeAt(view, pmPos) {
41
43
  const node = view.state.doc.nodeAt(pmPos);
42
44
  if (!node || node.type.name !== "image") return null;
45
+ if (expectImageAttrs(node)._docxRawXmlMode === DRAWING_RAW_XML_MODES.PRESERVE_ONLY) return null;
43
46
  return node;
44
47
  }
45
48
  /**
@@ -50,11 +53,10 @@ function commitImageResize(view, pmPos, newWidth, newHeight) {
50
53
  try {
51
54
  const node = imageNodeAt(view, pmPos);
52
55
  if (!node) return null;
53
- view.dispatch(view.state.tr.setNodeMarkup(pmPos, void 0, {
54
- ...node.attrs,
56
+ view.dispatch(view.state.tr.setNodeMarkup(pmPos, void 0, mergeImageAttrs(node, {
55
57
  width: newWidth,
56
58
  height: newHeight
57
- }));
59
+ })));
58
60
  return pmPos;
59
61
  } catch {
60
62
  return null;
@@ -69,7 +71,7 @@ function commitImageFloatMove(view, pmPos, hOffsetEmu, vOffsetEmu) {
69
71
  try {
70
72
  const node = imageNodeAt(view, pmPos);
71
73
  if (!node) return null;
72
- const newPosition = {
74
+ view.dispatch(view.state.tr.setNodeMarkup(pmPos, void 0, mergeImageAttrs(node, { position: {
73
75
  horizontal: {
74
76
  posOffset: hOffsetEmu,
75
77
  relativeTo: "margin"
@@ -78,11 +80,7 @@ function commitImageFloatMove(view, pmPos, hOffsetEmu, vOffsetEmu) {
78
80
  posOffset: vOffsetEmu,
79
81
  relativeTo: "margin"
80
82
  }
81
- };
82
- view.dispatch(view.state.tr.setNodeMarkup(pmPos, void 0, {
83
- ...node.attrs,
84
- position: newPosition
85
- }));
83
+ } })));
86
84
  return pmPos;
87
85
  } catch {
88
86
  return null;
@@ -0,0 +1,21 @@
1
+ import { document_d_exports } from "../types/document.js";
2
+ import { FolioContentParagraphIndentation } from "../compare/content-types.js";
3
+ import { ParagraphAttrs } from "./schema/nodes.js";
4
+ //#region src/prosemirror/paragraphIndentation.d.ts
5
+ /** The authored `w:ind` attribute cluster. */
6
+ type DirectParagraphIndentation = FolioContentParagraphIndentation;
7
+ /** Project only authored `w:ind` attributes, preserving zero and false. */
8
+ declare const paragraphIndentationFromFormatting: (formatting: document_d_exports.ParagraphFormatting | null | undefined) => DirectParagraphIndentation | undefined;
9
+ /** Read direct indentation without materializing values inherited from a style. */
10
+ declare const directParagraphIndentation: (attrs: ParagraphAttrs) => DirectParagraphIndentation | undefined;
11
+ declare const paragraphIndentationEqual: (left: DirectParagraphIndentation | null | undefined, right: DirectParagraphIndentation | null | undefined) => boolean;
12
+ /** Replace the complete direct `w:ind` cluster in canonical formatting. */
13
+ declare const withDirectParagraphIndentation: (formatting: document_d_exports.ParagraphFormatting | null | undefined, indentation: DirectParagraphIndentation | null | undefined) => document_d_exports.ParagraphFormatting | undefined;
14
+ type ParagraphIndentationAttrPatchOptions = {
15
+ direct: DirectParagraphIndentation | null | undefined;
16
+ inherited: DirectParagraphIndentation | null | undefined;
17
+ };
18
+ /** Project direct-over-inherited indentation into paragraph attrs. */
19
+ declare const paragraphIndentationAttrPatch: ({ direct, inherited }: ParagraphIndentationAttrPatchOptions) => Record<string, unknown>;
20
+ //#endregion
21
+ export { DirectParagraphIndentation, directParagraphIndentation, paragraphIndentationAttrPatch, paragraphIndentationEqual, paragraphIndentationFromFormatting, withDirectParagraphIndentation };