@stll/folio-core 0.52.0 → 0.53.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 (307) hide show
  1. package/README.md +23 -0
  2. package/dist/ai-edits/apply.d.ts +26 -1
  3. package/dist/ai-edits/apply.js +1519 -105
  4. package/dist/ai-edits/batch-claims.d.ts +130 -0
  5. package/dist/ai-edits/batch-claims.js +244 -0
  6. package/dist/ai-edits/blockRange.js +9 -3
  7. package/dist/ai-edits/character-boundaries.d.ts +43 -0
  8. package/dist/ai-edits/character-boundaries.js +95 -0
  9. package/dist/ai-edits/clean-text.d.ts +33 -3
  10. package/dist/ai-edits/clean-text.js +52 -6
  11. package/dist/ai-edits/comment-lifecycle.d.ts +18 -0
  12. package/dist/ai-edits/comment-lifecycle.js +52 -0
  13. package/dist/ai-edits/headless.d.ts +71 -7
  14. package/dist/ai-edits/headless.js +381 -41
  15. package/dist/ai-edits/index.d.ts +2 -1
  16. package/dist/ai-edits/index.js +2 -1
  17. package/dist/ai-edits/minimal-replacement.d.ts +21 -6
  18. package/dist/ai-edits/minimal-replacement.js +134 -15
  19. package/dist/ai-edits/newListNumbering.d.ts +23 -0
  20. package/dist/ai-edits/newListNumbering.js +94 -0
  21. package/dist/ai-edits/note-references.d.ts +96 -0
  22. package/dist/ai-edits/note-references.js +139 -0
  23. package/dist/ai-edits/pending-suggestions.d.ts +79 -0
  24. package/dist/ai-edits/pending-suggestions.js +306 -0
  25. package/dist/ai-edits/read.d.ts +1 -1
  26. package/dist/ai-edits/read.js +56 -43
  27. package/dist/ai-edits/result-validation.d.ts +29 -0
  28. package/dist/ai-edits/result-validation.js +164 -0
  29. package/dist/ai-edits/snapshot.d.ts +36 -3
  30. package/dist/ai-edits/snapshot.js +177 -23
  31. package/dist/ai-edits/table-cell-mutations.d.ts +1 -1
  32. package/dist/ai-edits/table-cell-mutations.js +4 -1
  33. package/dist/ai-edits/table-geometry.d.ts +1 -1
  34. package/dist/ai-edits/table-row-column-mutations.d.ts +38 -16
  35. package/dist/ai-edits/table-row-column-mutations.js +61 -26
  36. package/dist/ai-edits/types.d.ts +155 -16
  37. package/dist/compare/compare.d.ts +1 -1
  38. package/dist/compare/compare.js +65 -16
  39. package/dist/compare/content-alignment.js +13 -2
  40. package/dist/compare/content-types.d.ts +7 -0
  41. package/dist/compare/content.d.ts +4 -1
  42. package/dist/compare/content.js +6 -1
  43. package/dist/compare/formatting.js +2 -1
  44. package/dist/compare/inline-atoms.d.ts +21 -4
  45. package/dist/compare/inline-atoms.js +138 -16
  46. package/dist/compare/plan.js +10 -5
  47. package/dist/compare/scenario.js +14 -3
  48. package/dist/compare/section-boundary-properties.js +1 -1
  49. package/dist/compare/types.d.ts +4 -2
  50. package/dist/compare/types.js +2 -1
  51. package/dist/compare/verification.d.ts +1 -1
  52. package/dist/compare/verification.js +15 -3
  53. package/dist/controller/committedLayoutDiff.d.ts +25 -0
  54. package/dist/controller/committedLayoutDiff.js +71 -0
  55. package/dist/controller/contentControlWidgetController.d.ts +1 -1
  56. package/dist/controller/folioEditor.d.ts +1 -1
  57. package/dist/controller/fontReadiness.d.ts +70 -3
  58. package/dist/controller/fontReadiness.js +100 -10
  59. package/dist/controller/headerFooterEditorManager.js +6 -1
  60. package/dist/controller/layoutPipeline.d.ts +12 -10
  61. package/dist/controller/layoutPipeline.js +62 -9
  62. package/dist/controller/layoutRunOptions.d.ts +24 -0
  63. package/dist/controller/layoutRunOptions.js +17 -0
  64. package/dist/controller/layoutScheduler.d.ts +19 -14
  65. package/dist/controller/layoutScheduler.js +15 -12
  66. package/dist/controller/layoutSession.d.ts +26 -2
  67. package/dist/controller/layoutSession.js +1 -1
  68. package/dist/controller/noteEditorManager.js +8 -3
  69. package/dist/document-operations.d.ts +11 -2
  70. package/dist/document-operations.js +230 -21
  71. package/dist/docx/altChunk.d.ts +8 -0
  72. package/dist/docx/altChunk.js +17 -0
  73. package/dist/docx/attributeRemainder.d.ts +1 -1
  74. package/dist/docx/blockContentParser.d.ts +64 -1
  75. package/dist/docx/blockContentParser.js +17 -4
  76. package/dist/docx/blockCustomXmlShell.d.ts +7 -0
  77. package/dist/docx/blockCustomXmlShell.js +14 -0
  78. package/dist/docx/blockPlainText.js +7 -0
  79. package/dist/docx/commentAnchorIndex.js +1 -1
  80. package/dist/docx/commentRangeIntegrity.js +8 -3
  81. package/dist/docx/commentReferenceNormalization.js +1 -1
  82. package/dist/docx/commentReplyMarkers.js +20 -1
  83. package/dist/docx/compatibility.d.ts +1 -1
  84. package/dist/docx/compatibility.js +34 -13
  85. package/dist/docx/containerChildren.gen.d.ts +1 -1
  86. package/dist/docx/containerChildren.gen.js +1 -0
  87. package/dist/docx/documentParser.js +12 -12
  88. package/dist/docx/drawingIdNormalization.d.ts +3 -1
  89. package/dist/docx/drawingIdNormalization.js +6 -1
  90. package/dist/docx/ensureParaIds.js +119 -97
  91. package/dist/docx/footnoteParser.js +8 -4
  92. package/dist/docx/headerFooterParser.js +3 -3
  93. package/dist/docx/headerFooterReferenceNormalization.d.ts +20 -1
  94. package/dist/docx/headerFooterReferenceNormalization.js +52 -27
  95. package/dist/docx/hyperlinkParser.d.ts +1 -1
  96. package/dist/docx/index.d.ts +1 -1
  97. package/dist/docx/listNumberingInstances.d.ts +59 -0
  98. package/dist/docx/listNumberingInstances.js +249 -0
  99. package/dist/docx/normalizeBaseDirection.js +2 -1
  100. package/dist/docx/opaqueCarrier.d.ts +7 -0
  101. package/dist/docx/opaqueCarrier.js +38 -0
  102. package/dist/docx/packageParts.js +4 -1
  103. package/dist/docx/paragraphParser.js +91 -24
  104. package/dist/docx/paragraphPropertySource.d.ts +4 -2
  105. package/dist/docx/paragraphPropertySource.js +7 -1
  106. package/dist/docx/paragraphTraversal.js +1 -0
  107. package/dist/docx/parseWarningMessage.js +4 -1
  108. package/dist/docx/parser.js +173 -20
  109. package/dist/docx/rezip.js +27 -5
  110. package/dist/docx/sdtProperties.js +1 -1
  111. package/dist/docx/sdtPropertiesPatch.js +3 -0
  112. package/dist/docx/selectiveSave.js +16 -9
  113. package/dist/docx/selectiveXmlPatch.js +106 -37
  114. package/dist/docx/serializer/blockCustomXmlSerializer.d.ts +5 -0
  115. package/dist/docx/serializer/blockCustomXmlSerializer.js +4 -0
  116. package/dist/docx/serializer/documentSerializer.js +2 -0
  117. package/dist/docx/serializer/headerFooterSerializer.js +2 -0
  118. package/dist/docx/serializer/noteSerializer.js +3 -1
  119. package/dist/docx/serializer/paragraphSerializer.js +33 -9
  120. package/dist/docx/serializer/tableSerializer.js +25 -38
  121. package/dist/docx/server/createBilingualDocument.js +3 -3
  122. package/dist/docx/tableParser.d.ts +157 -1
  123. package/dist/docx/tableParser.js +89 -10
  124. package/dist/docx/textBoxParser.js +1 -1
  125. package/dist/docx/unzip.d.ts +2 -1
  126. package/dist/docx/unzip.js +1 -1
  127. package/dist/docx/wordprocessingPrefixes.d.ts +78 -0
  128. package/dist/docx/wordprocessingPrefixes.js +286 -0
  129. package/dist/i18n/messages/catalogs.gen.d.ts +136 -0
  130. package/dist/i18n/messages/catalogs.gen.js +153 -17
  131. package/dist/i18n/messages/messages.gen.d.ts +8 -0
  132. package/dist/internal/compare/inline-presentation.d.ts +2 -1
  133. package/dist/internal/compare/inline-presentation.js +11 -10
  134. package/dist/internal/headlessRevisionResolutionGuard.d.ts +2 -8
  135. package/dist/internal/headlessRevisionResolutionGuard.js +2 -11
  136. package/dist/internal/indexedPositionMap.d.ts +11 -0
  137. package/dist/internal/indexedPositionMap.js +42 -0
  138. package/dist/internal/pageBreakRunSourceDescendantIndex.js +2 -1
  139. package/dist/internal/revisionResolutionEdits.d.ts +13 -0
  140. package/dist/internal/revisionResolutionEdits.js +19 -0
  141. package/dist/internal/revisionResolutionInline.d.ts +24 -0
  142. package/dist/internal/{headlessRevisionResolution.js → revisionResolutionInline.js} +61 -43
  143. package/dist/internal/revisionResolutionStep.d.ts +34 -0
  144. package/dist/internal/revisionResolutionStep.js +282 -0
  145. package/dist/internal/revisionResolutionTracking.d.ts +11 -0
  146. package/dist/internal/revisionResolutionTracking.js +124 -0
  147. package/dist/internal/wholeStoryRevisionResolution.d.ts +56 -0
  148. package/dist/internal/wholeStoryRevisionResolution.js +530 -0
  149. package/dist/layout-bridge/convert/markupViewFlow.d.ts +20 -0
  150. package/dist/layout-bridge/convert/markupViewFlow.js +123 -0
  151. package/dist/layout-bridge/convert/tableConversion.js +1 -1
  152. package/dist/layout-bridge/convert/toFlowBlocks.js +10 -1
  153. package/dist/layout-engine/layoutInstrumentation.d.ts +9 -1
  154. package/dist/layout-engine/layoutInstrumentation.js +4 -1
  155. package/dist/layout-engine/measure/cache.d.ts +18 -1
  156. package/dist/layout-engine/measure/cache.js +31 -1
  157. package/dist/layout-engine/measure/font-metrics.worker.js +3 -7
  158. package/dist/layout-engine/measure/measureContainer.js +7 -47
  159. package/dist/layout-engine/measure/measureHelpers.d.ts +6 -1
  160. package/dist/layout-engine/measure/measureHelpers.js +22 -2
  161. package/dist/layout-engine/measure/measureWorker.js +2 -3
  162. package/dist/layout-engine/measure/measureWorkerProtocol.d.ts +6 -7
  163. package/dist/layout-engine/measure/measureWorkerProtocol.js +1 -2
  164. package/dist/layout-engine/types.d.ts +6 -0
  165. package/dist/layout-painter/renderPage.js +1 -0
  166. package/dist/layout-painter/renderParagraph.js +1 -1
  167. package/dist/managers/ContextMenuManager.js +5 -2
  168. package/dist/managers/types.d.ts +3 -0
  169. package/dist/markdown/fromMarkdown.js +2 -1
  170. package/dist/markdown/internals.d.ts +11 -1
  171. package/dist/markdown/internals.js +24 -3
  172. package/dist/markdown/renderBlock.js +39 -9
  173. package/dist/markdown/renderParagraph.d.ts +13 -1
  174. package/dist/markdown/renderParagraph.js +85 -38
  175. package/dist/markdown/renderRuns.js +3 -10
  176. package/dist/markdown/renderTable.js +24 -12
  177. package/dist/markdown/trailers.js +2 -2
  178. package/dist/markdown/types.d.ts +29 -7
  179. package/dist/paged-layout/incrementalMeasure.d.ts +1 -2
  180. package/dist/paged-layout/incrementalMeasure.js +1 -9
  181. package/dist/paged-layout/transactionDirtyRange.d.ts +1 -3
  182. package/dist/paged-layout/transactionDirtyRange.js +29 -41
  183. package/dist/panel-layout.d.ts +83 -0
  184. package/dist/panel-layout.js +96 -0
  185. package/dist/prosemirror/anchoredTextBoxes.d.ts +37 -0
  186. package/dist/prosemirror/anchoredTextBoxes.js +156 -0
  187. package/dist/prosemirror/attrs/index.d.ts +6 -2
  188. package/dist/prosemirror/attrs/index.js +172 -1
  189. package/dist/prosemirror/commands/comments.d.ts +7 -8
  190. package/dist/prosemirror/commands/comments.js +241 -207
  191. package/dist/prosemirror/commands/contentControls.d.ts +1 -1
  192. package/dist/prosemirror/commands/formatPainter.d.ts +1 -1
  193. package/dist/prosemirror/commands/formatting.d.ts +1 -1
  194. package/dist/prosemirror/commands/index.d.ts +2 -2
  195. package/dist/prosemirror/commands/index.js +2 -2
  196. package/dist/prosemirror/commands/paragraph.d.ts +7 -1
  197. package/dist/prosemirror/commands/paragraph.js +9 -1
  198. package/dist/prosemirror/commands/paragraphBookmarkJoin.d.ts +13 -0
  199. package/dist/prosemirror/commands/paragraphBookmarkJoin.js +22 -0
  200. package/dist/prosemirror/commands/pastePlainText.d.ts +1 -1
  201. package/dist/prosemirror/commands/resolveAllTableChanges.d.ts +40 -0
  202. package/dist/prosemirror/commands/resolveAllTableChanges.js +615 -0
  203. package/dist/prosemirror/commands/resolveNodePropertyChangeAttrs.d.ts +15 -0
  204. package/dist/prosemirror/commands/resolveNodePropertyChangeAttrs.js +46 -0
  205. package/dist/prosemirror/commands/resolveParagraphProperties.d.ts +16 -0
  206. package/dist/prosemirror/commands/resolveParagraphProperties.js +59 -0
  207. package/dist/prosemirror/commands/sectionBreak.js +2 -1
  208. package/dist/prosemirror/commands/tableCellMergeResolution.d.ts +8 -2
  209. package/dist/prosemirror/commands/tableCellMergeResolution.js +1 -1
  210. package/dist/prosemirror/contentControlRevisions.d.ts +1 -1
  211. package/dist/prosemirror/conversion/fromProseDoc.js +181 -31
  212. package/dist/prosemirror/conversion/toProseDoc.js +39 -4
  213. package/dist/prosemirror/emptyFieldResultRuns.d.ts +18 -0
  214. package/dist/prosemirror/emptyFieldResultRuns.js +33 -0
  215. package/dist/prosemirror/extensions/ExtensionManager.d.ts +1 -1
  216. package/dist/prosemirror/extensions/ExtensionManager.js +3 -1
  217. package/dist/prosemirror/extensions/StarterKit.js +3 -1
  218. package/dist/prosemirror/extensions/core/DocExtension.js +1 -1
  219. package/dist/prosemirror/extensions/core/ParagraphExtension.js +12 -0
  220. package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +3 -0
  221. package/dist/prosemirror/extensions/features/ListExtension.js +161 -123
  222. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.d.ts +19 -2
  223. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +33 -20
  224. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +31 -2
  225. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +270 -99
  226. package/dist/prosemirror/extensions/features/PasteCleanupExtension.js +3 -2
  227. package/dist/prosemirror/extensions/features/pasteCleanup.js +2 -1
  228. package/dist/prosemirror/extensions/features/pastedHtmlLists.d.ts +12 -0
  229. package/dist/prosemirror/extensions/features/pastedHtmlLists.js +126 -0
  230. package/dist/prosemirror/extensions/marks/FootnoteRefExtension.js +21 -5
  231. package/dist/prosemirror/extensions/marks/RunIdentityExtension.d.ts +21 -18
  232. package/dist/prosemirror/extensions/marks/RunIdentityExtension.js +37 -17
  233. package/dist/prosemirror/extensions/marks/markUtils.d.ts +7 -2
  234. package/dist/prosemirror/extensions/marks/markUtils.js +8 -2
  235. package/dist/prosemirror/extensions/marks/noteReferenceDeletion.d.ts +10 -0
  236. package/dist/prosemirror/extensions/marks/noteReferenceDeletion.js +35 -0
  237. package/dist/prosemirror/extensions/nodes/BlockCustomXmlExtension.d.ts +6 -0
  238. package/dist/prosemirror/extensions/nodes/BlockCustomXmlExtension.js +52 -0
  239. package/dist/prosemirror/extensions/nodes/FieldExtension.d.ts +3 -3
  240. package/dist/prosemirror/extensions/nodes/FieldExtension.js +50 -15
  241. package/dist/prosemirror/extensions/nodes/PreservedBlockExtension.js +4 -1
  242. package/dist/prosemirror/extensions/nodes/TableExtension.d.ts +1 -1
  243. package/dist/prosemirror/extensions/nodes/TableExtension.js +19 -18
  244. package/dist/prosemirror/extensions/types.d.ts +4 -1
  245. package/dist/prosemirror/findReplaceSelection.js +1 -1
  246. package/dist/prosemirror/index.d.ts +3 -2
  247. package/dist/prosemirror/index.js +3 -2
  248. package/dist/prosemirror/indexedNodeLookup.d.ts +17 -0
  249. package/dist/prosemirror/indexedNodeLookup.js +103 -0
  250. package/dist/prosemirror/listAutoformatMarkers.d.ts +19 -0
  251. package/dist/prosemirror/listAutoformatMarkers.js +98 -0
  252. package/dist/prosemirror/listInstanceReferences.d.ts +12 -0
  253. package/dist/prosemirror/listInstanceReferences.js +72 -0
  254. package/dist/prosemirror/listLabels.d.ts +24 -0
  255. package/dist/prosemirror/listLabels.js +111 -0
  256. package/dist/prosemirror/listNumbering.d.ts +110 -0
  257. package/dist/prosemirror/listNumbering.js +345 -0
  258. package/dist/prosemirror/listRenderingAttrs.d.ts +11 -2
  259. package/dist/prosemirror/listRenderingAttrs.js +8 -1
  260. package/dist/prosemirror/markupViewProjection.d.ts +95 -0
  261. package/dist/prosemirror/markupViewProjection.js +83 -0
  262. package/dist/prosemirror/numberingAttr.d.ts +9 -1
  263. package/dist/prosemirror/numberingAttr.js +9 -1
  264. package/dist/prosemirror/outlineLevelAttr.js +1 -1
  265. package/dist/prosemirror/paragraphIndentation.d.ts +10 -1
  266. package/dist/prosemirror/paragraphIndentation.js +29 -7
  267. package/dist/prosemirror/paragraphMarkJoin.d.ts +19 -0
  268. package/dist/prosemirror/paragraphMarkJoin.js +24 -0
  269. package/dist/prosemirror/plugins/createDocScanPlugin.d.ts +1 -1
  270. package/dist/prosemirror/plugins/documentNumbering.d.ts +27 -1
  271. package/dist/prosemirror/plugins/documentNumbering.js +97 -11
  272. package/dist/prosemirror/plugins/documentStyles.d.ts +10 -1
  273. package/dist/prosemirror/plugins/documentStyles.js +14 -1
  274. package/dist/prosemirror/plugins/suggestionMode.d.ts +16 -2
  275. package/dist/prosemirror/plugins/suggestionMode.js +116 -52
  276. package/dist/prosemirror/plugins/templateDirectives.d.ts +1 -1
  277. package/dist/prosemirror/plugins/transactionInvariants.d.ts +32 -0
  278. package/dist/prosemirror/plugins/transactionInvariants.js +86 -0
  279. package/dist/prosemirror/positionSweep.d.ts +24 -0
  280. package/dist/prosemirror/positionSweep.js +222 -0
  281. package/dist/prosemirror/rebaseParagraphRunFormatting.d.ts +1 -1
  282. package/dist/prosemirror/rejoinRunCarriers.d.ts +1 -1
  283. package/dist/prosemirror/replacedAnnotations.d.ts +33 -1
  284. package/dist/prosemirror/replacedAnnotations.js +170 -1
  285. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +1 -1
  286. package/dist/prosemirror/schema/index.d.ts +2 -2
  287. package/dist/prosemirror/schema/index.js +3 -0
  288. package/dist/prosemirror/schema/nodes.d.ts +42 -11
  289. package/dist/prosemirror/sectionMarkEdits.d.ts +20 -0
  290. package/dist/prosemirror/sectionMarkEdits.js +59 -0
  291. package/dist/prosemirror/storyListNumbering.d.ts +17 -0
  292. package/dist/prosemirror/storyListNumbering.js +102 -0
  293. package/dist/prosemirror/tableGridMutation.d.ts +48 -2
  294. package/dist/prosemirror/tableGridMutation.js +106 -1
  295. package/dist/prosemirror/validation.js +5 -1
  296. package/dist/redline.js +93 -9
  297. package/dist/render-dom/BodySelectionOverlay.d.ts +4 -1
  298. package/dist/render-dom/BodySelectionOverlay.js +3 -2
  299. package/dist/utils/findReplace.js +2 -2
  300. package/dist/utils/mergeDocumentContent.js +1 -1
  301. package/dist/utils/noteReferenceLabels.d.ts +36 -0
  302. package/dist/utils/noteReferenceLabels.js +32 -0
  303. package/dist/utils/replaceText.js +1 -1
  304. package/dist/version-comparison.d.ts +1 -0
  305. package/dist/version-comparison.js +1 -0
  306. package/package.json +3 -2
  307. package/dist/internal/headlessRevisionResolution.d.ts +0 -23
@@ -1,29 +1,36 @@
1
1
  import { sameStatedParagraphNumbering as sameStatedParagraphNumbering$1 } from "../../docx/numberingReference.js";
2
- import { joinProseParagraphsWithRightPropertySource } from "../../docx/paragraphPropertySource.js";
3
- import { appendHeadlessInlineResolution } from "../../internal/headlessRevisionResolution.js";
4
- import { stateAllowsHeadlessRevisionResolution } from "../../internal/headlessRevisionResolutionGuard.js";
5
- import { expectParagraphAttrs, expectRunPropertyChangeMarkAttrs, expectTrackedChangeMarkAttrs } from "../attrs/index.js";
2
+ import { getProseParagraphPropertySourceToken, markParagraphPropertySourceTransfers } from "../../docx/paragraphPropertySource.js";
3
+ import { RevisionResolutionStep } from "../../internal/revisionResolutionStep.js";
4
+ import { finalRevisionParagraphRanges } from "../../internal/revisionResolutionTracking.js";
5
+ import { deleteTextBoxesAnchoredAt, droppedTextBoxAnchorIds, moveTextBoxesPastNextParagraph } from "../anchoredTextBoxes.js";
6
+ import { expectFieldAttrs, expectParagraphAttrs, expectRunPropertyChangeMarkAttrs, expectTrackedChangeMarkAttrs } from "../attrs/index.js";
6
7
  import { addedBreakCarrierBefore, finalParagraphsOf, paragraphEndsItsContainer } from "../containerFinalParagraph.js";
7
8
  import { enclosingRevisionIds, resolutionRemovesControl, withoutResolvedEnclosures } from "../contentControlRevisions.js";
8
- import { resolveParagraphDefaultTextFormatting } from "../conversion/toProseDoc.js";
9
+ import { resolveEmptyFieldResultRuns } from "../emptyFieldResultRuns.js";
9
10
  import { markChangedParagraphRanges, markStructuralChange, markTrackedSectionEndpointRemoval } from "../extensions/features/ParagraphChangeTrackerExtension.js";
10
11
  import "../extensions/nodes/SdtExtension.js";
12
+ import { resolveStateStory } from "../markupViewProjection.js";
13
+ import { joinAtParagraphMark } from "../paragraphMarkJoin.js";
14
+ import { getDocumentNumbering } from "../plugins/documentNumbering.js";
11
15
  import { getDocumentStyleResolver } from "../plugins/documentStyles.js";
12
16
  import { setParagraphAttrsWithRebasedRunFormatting } from "../rebaseParagraphRunFormatting.js";
13
17
  import { rejoinRunsAt } from "../rejoinRunCarriers.js";
14
- import { getFolioNodeRevisionCarriers, nodePropertyRevisionSites, propertyRevisionMetadata, propertyRevisionRecords } from "../revisionCarriers.js";
18
+ import { getFolioNodeRevisionCarriers, nodePropertyRevisionSites } from "../revisionCarriers.js";
15
19
  import { RUN_FORMATTING_MARK_NAMES } from "../runFormattingMarkNames.js";
16
20
  import { reconstructRejectedRunFormattingMarks } from "../runPropertyChangeResolution.js";
17
21
  import { paragraphRunStyleContextAt } from "../runStyleFormatting.js";
18
22
  import { getTableCellMergeChange } from "../tableCellMergeRevision.js";
19
23
  import { isTableCellRetainedInReviewView } from "../tableCellRevisionVisibility.js";
20
- import { reconcileTableGridAfterColumnRemoval } from "../tableGridMutation.js";
24
+ import { reconcileTableGridAfterColumnRemoval, removeRowsWithoutCells, removeTableRow } from "../tableGridMutation.js";
21
25
  import { holdsNoContent } from "../zeroWidthAnchors.js";
22
- import { hasSerializableParagraphPropertyChange, paragraphPropertiesSnapshot, paragraphRejectAttrPatch, paragraphRejectOriginalFormatting, removeParagraphPropertyChanges, sectionRejectProperties, tableCellRejectAttrPatch, tablePropertyExceptionsRejectAttrPatch, tableRejectAttrPatch, tableRowRejectAttrPatch } from "./propertyChangeScope.js";
26
+ import { inlineBookmarksForParagraphJoin } from "./paragraphBookmarkJoin.js";
27
+ import { hasSerializableParagraphPropertyChange, paragraphPropertiesSnapshot } from "./propertyChangeScope.js";
28
+ import { resolveNodePropertyChangeAttrs } from "./resolveNodePropertyChangeAttrs.js";
29
+ import { resolveParagraphChangeAttrs } from "./resolveParagraphProperties.js";
23
30
  import { hasMatchingCollapsedTableCellMerge, resolveCollapsedTableCellMerge, resolveVisibleTableCellMerge } from "./tableCellMergeResolution.js";
24
31
  import { panic } from "better-result";
25
32
  import { PARAGRAPH_MARK_CHANGE_KINDS, REVIEW_CARRIERS } from "@stll/docx-core/model";
26
- import { TableMap, removeRow } from "prosemirror-tables";
33
+ import { TableMap } from "prosemirror-tables";
27
34
  import { Mapping } from "prosemirror-transform";
28
35
  //#region src/prosemirror/commands/comments.ts
29
36
  /**
@@ -74,17 +81,6 @@ const revisionLayerOf = (mark) => {
74
81
  };
75
82
  };
76
83
  const revisionLayerRemovesContent = (layer, mode) => mode === "accept" ? layer.type === "deletion" || layer.type === "moveFrom" : layer.type === "insertion" || layer.type === "moveTo";
77
- const containsNestedRevision = (doc) => {
78
- let found = false;
79
- doc.descendants((node) => {
80
- if (found) return false;
81
- for (const mark of node.marks) if ((mark.type.name === "insertion" || mark.type.name === "deletion") && (expectTrackedChangeMarkAttrs(mark)._docxRevisionAncestors?.length ?? 0) > 0) {
82
- found = true;
83
- return false;
84
- }
85
- });
86
- return found;
87
- };
88
84
  /**
89
85
  * Resolve a tracked change: accept or reject.
90
86
  * - Accept: keep insertions (remove mark), delete deletions (remove text)
@@ -97,16 +93,16 @@ const containsNestedRevision = (doc) => {
97
93
  * the operation matches every revision mark or property-change entry in the
98
94
  * range (the bulk accept-all/reject-all path).
99
95
  */
100
- function resolveChange(from, to, mode, revisionIds, execution = "legacy") {
96
+ function resolveChange(from, to, mode, revisionIds) {
101
97
  return (state, dispatch) => {
102
98
  const insertionType = state.schema.marks["insertion"];
103
99
  const deletionType = state.schema.marks["deletion"];
104
100
  const styleResolver = getDocumentStyleResolver(state);
101
+ const numbering = getDocumentNumbering(state);
105
102
  const keepType = mode === "accept" ? insertionType : deletionType;
106
103
  const removeType = mode === "accept" ? deletionType : insertionType;
107
104
  const revisionSet = revisionIds === void 0 ? null : new Set(revisionIds);
108
105
  const removeKeptMarksInBulk = revisionSet === null && keepType !== void 0;
109
- const canBulkInlineResolution = execution === "headless-bulk-inline" && revisionSet === null && from === 0 && to === state.doc.content.size && stateAllowsHeadlessRevisionResolution(state) && !containsNestedRevision(state.doc);
110
106
  const matchesRevision = (mark) => revisionSet === null || typeof mark.attrs["revisionId"] === "number" && revisionSet.has(mark.attrs["revisionId"]);
111
107
  if (dispatch) {
112
108
  const tr = state.tr;
@@ -122,51 +118,14 @@ function resolveChange(from, to, mode, revisionIds, execution = "legacy") {
122
118
  if (node.type.name === "paragraph") {
123
119
  const op = collectPPrMarkOp(node, pos, from, to, mode, revisionSet);
124
120
  if (op) pPrMarkOps.push(op);
125
- const boundaryCovered = rangeCoversParagraphBoundary(from, to, pos, node);
126
- let nextAttrs = null;
127
- const propertyChanges = expectParagraphAttrs(node)._propertyChanges;
128
- if (Array.isArray(propertyChanges) && propertyChanges.length > 0 && boundaryCovered) {
129
- const matchesPropertyChange = (change) => revisionSet === null || revisionSet.has(change.info.id);
130
- if (propertyChanges.some(matchesPropertyChange)) {
131
- const rejection = mode === "reject" ? removeParagraphPropertyChanges(propertyChanges, matchesPropertyChange) : null;
132
- let remaining;
133
- if (rejection === null) remaining = propertyChanges.filter((change) => !matchesPropertyChange(change));
134
- else if (rejection.type === "unchanged") remaining = propertyChanges;
135
- else remaining = rejection.remaining;
136
- nextAttrs = {
137
- ...node.attrs,
138
- _propertyChanges: remaining.length > 0 ? remaining : null
139
- };
140
- if (rejection?.type === "restore-previous") {
141
- const inheritedAlignment = expectParagraphAttrs(node).alignmentFromStyle;
142
- let previousFormattingFromStyle;
143
- if (styleResolver) previousFormattingFromStyle = styleResolver.resolveParagraphStyle(rejection.previousFormatting?.styleId).paragraphFormatting;
144
- else if (inheritedAlignment !== void 0) previousFormattingFromStyle = { alignment: inheritedAlignment };
145
- Object.assign(nextAttrs, paragraphRejectAttrPatch(rejection.previousFormatting, previousFormattingFromStyle));
146
- const restoredFormatting = paragraphRejectOriginalFormatting(rejection.previousFormatting, node.attrs["_originalFormatting"]);
147
- nextAttrs["_originalFormatting"] = restoredFormatting;
148
- if (styleResolver) nextAttrs["defaultTextFormatting"] = resolveParagraphDefaultTextFormatting(rejection.previousFormatting?.styleId, restoredFormatting ?? void 0, styleResolver) ?? null;
149
- }
150
- }
151
- }
152
- const sectionProperties = node.attrs["_sectionProperties"];
153
- const sectionChanges = sectionProperties?.propertyChanges;
154
- if (sectionProperties && Array.isArray(sectionChanges) && sectionChanges.length > 0 && boundaryCovered) {
155
- const matches = sectionChanges.filter((c) => revisionSet === null || c.info && revisionSet.has(c.info.id));
156
- if (matches.length > 0) {
157
- const remaining = sectionChanges.filter((c) => revisionSet !== null && (!c.info || !revisionSet.has(c.info.id)));
158
- let restored = { ...sectionProperties };
159
- if (mode === "reject") for (const change of matches.toReversed()) restored = sectionRejectProperties({
160
- live: restored,
161
- previousProperties: change.previousProperties,
162
- previousReferences: change.previousReferences
163
- });
164
- delete restored.propertyChanges;
165
- if (remaining.length > 0) restored.propertyChanges = remaining;
166
- nextAttrs = nextAttrs ?? { ...node.attrs };
167
- nextAttrs["_sectionProperties"] = restored;
168
- }
169
- }
121
+ const nextAttrs = resolveParagraphChangeAttrs({
122
+ node,
123
+ boundaryCovered: rangeCoversParagraphBoundary(from, to, pos, node),
124
+ mode,
125
+ revisionSet,
126
+ styleResolver,
127
+ numbering
128
+ });
170
129
  if (nextAttrs) if (nextAttrs["styleId"] !== node.attrs["styleId"] && styleResolver) setParagraphAttrsWithRebasedRunFormatting({
171
130
  nextAttrs,
172
131
  paragraphPosition: pos,
@@ -189,7 +148,12 @@ function resolveChange(from, to, mode, revisionIds, execution = "legacy") {
189
148
  const nodeAttrSites = nodePropertyRevisionSites(node.type.name).filter((site) => site.resolution === "node-attrs");
190
149
  if (nodeAttrSites.length > 0) {
191
150
  if (rangeCoversNode(from, to, pos, node)) for (const site of nodeAttrSites) {
192
- const nextAttrs = resolveNodePropertyChangeAttrs(tr.doc.nodeAt(pos) ?? node, site, mode, revisionSet);
151
+ const nextAttrs = resolveNodePropertyChangeAttrs({
152
+ node: tr.doc.nodeAt(pos) ?? node,
153
+ site,
154
+ mode,
155
+ revisionSet
156
+ });
193
157
  if (nextAttrs) {
194
158
  tr.setNodeMarkup(pos, void 0, nextAttrs);
195
159
  markStructuralChange(tr);
@@ -198,7 +162,6 @@ function resolveChange(from, to, mode, revisionIds, execution = "legacy") {
198
162
  return true;
199
163
  }
200
164
  if (!node.isInline) return true;
201
- if (canBulkInlineResolution) return true;
202
165
  const nodeEnd = pos + node.nodeSize;
203
166
  const rangeFrom = Math.max(from, pos);
204
167
  const rangeTo = Math.min(to, nodeEnd);
@@ -272,82 +235,25 @@ function resolveChange(from, to, mode, revisionIds, execution = "legacy") {
272
235
  }
273
236
  return true;
274
237
  });
275
- let bulkInlineChangeTracking = null;
276
- if (canBulkInlineResolution) bulkInlineChangeTracking = appendHeadlessInlineResolution({
277
- tr,
278
- mode,
279
- keepType,
280
- removeType,
281
- styleResolver
282
- });
283
- else {
284
- if (removeKeptMarksInBulk) tr.removeMark(from, to, keepType);
285
- let rangesToDelete = deleteRanges;
286
- if (revisionSet === null) {
287
- const coalescedDeleteRanges = [];
288
- for (const range of deleteRanges) {
289
- const previous = coalescedDeleteRanges.at(-1);
290
- if (previous && range.from <= previous.to) {
291
- previous.to = Math.max(previous.to, range.to);
292
- continue;
293
- }
294
- coalescedDeleteRanges.push({
295
- from: range.from,
296
- to: range.to
297
- });
298
- }
299
- rangesToDelete = coalescedDeleteRanges;
300
- }
301
- for (const range of rangesToDelete.toReversed()) tr.delete(range.from, range.to);
302
- }
303
- pPrMarkOps.sort((a, b) => b.paragraphPos - a.paragraphPos);
304
- for (const op of pPrMarkOps) {
305
- const mappedPos = tr.mapping.map(op.paragraphPos);
306
- const paragraph = tr.doc.nodeAt(mappedPos);
307
- if (!paragraph || paragraph.type.name !== "paragraph") continue;
308
- if (op.action === "clear") {
309
- tr.setNodeAttribute(mappedPos, "pPrMark", null);
310
- continue;
311
- }
312
- const joinPos = mappedPos + paragraph.nodeSize;
313
- const nextNode = joinPos < tr.doc.content.size ? tr.doc.nodeAt(joinPos) : null;
314
- if (!(nextNode?.type.name === paragraph.type.name)) {
315
- const resolved = tr.doc.resolve(mappedPos);
316
- const endsItsContainer = paragraphEndsItsContainer(resolved, paragraph.type.name);
317
- const canGo = op.markWasAdded || !endsItsContainer;
318
- if (holdsNoContent(paragraph) && canGo && resolved.parent.childCount > 1) {
319
- if (ownsSectionEndpoint(paragraph)) {
320
- removedSectionEndpointCount++;
321
- removedSectionReferences.push(...sectionReferencesOf(paragraph));
322
- }
323
- tr.delete(mappedPos, mappedPos + paragraph.nodeSize);
238
+ if (removeKeptMarksInBulk) tr.removeMark(from, to, keepType);
239
+ let rangesToDelete = deleteRanges;
240
+ if (revisionSet === null) {
241
+ const coalescedDeleteRanges = [];
242
+ for (const range of deleteRanges) {
243
+ const previous = coalescedDeleteRanges.at(-1);
244
+ if (previous && range.from <= previous.to) {
245
+ previous.to = Math.max(previous.to, range.to);
324
246
  continue;
325
247
  }
326
- tr.setNodeAttribute(mappedPos, "pPrMark", null);
327
- continue;
328
- }
329
- const emptyFirstParagraph = holdsNoContent(paragraph);
330
- const joinedAttrs = {
331
- ...(emptyFirstParagraph ? nextNode : paragraph).attrs,
332
- pPrMark: nextNode.attrs["pPrMark"],
333
- _sectionProperties: nextNode.attrs["_sectionProperties"]
334
- };
335
- try {
336
- if (emptyFirstParagraph) joinProseParagraphsWithRightPropertySource({
337
- attrs: joinedAttrs,
338
- pos: joinPos,
339
- transaction: tr
248
+ coalescedDeleteRanges.push({
249
+ from: range.from,
250
+ to: range.to
340
251
  });
341
- else {
342
- tr.join(joinPos);
343
- tr.setNodeMarkup(mappedPos, void 0, joinedAttrs);
344
- }
345
- if (ownsSectionEndpoint(paragraph)) {
346
- removedSectionEndpointCount++;
347
- removedSectionReferences.push(...sectionReferencesOf(paragraph));
348
- }
349
- } catch {}
252
+ }
253
+ rangesToDelete = coalescedDeleteRanges;
350
254
  }
255
+ for (const range of rangesToDelete.toReversed()) tr.delete(range.from, range.to);
256
+ if (deleteTextBoxesAnchoredAt(tr, droppedTextBoxAnchorIds(state.doc, tr.doc))) markStructuralChange(tr);
351
257
  tableRowStructuralOps.sort((left, right) => right.rowPos - left.rowPos);
352
258
  let resolvedTableRowStructure = false;
353
259
  for (const op of tableRowStructuralOps) {
@@ -372,6 +278,7 @@ function resolveChange(from, to, mode, revisionIds, execution = "legacy") {
372
278
  tableCellStructuralOps.sort((left, right) => right.cellPos - left.cellPos);
373
279
  let resolvedTableCellStructure = false;
374
280
  let failedTableCellMergeResolution = false;
281
+ const emptiedTables = [];
375
282
  for (const op of tableCellStructuralOps) {
376
283
  const mappedPos = tr.mapping.map(op.cellPos);
377
284
  const cell = tr.doc.nodeAt(mappedPos);
@@ -390,12 +297,81 @@ function resolveChange(from, to, mode, revisionIds, execution = "legacy") {
390
297
  resolvedTableCellStructure = true;
391
298
  continue;
392
299
  }
393
- deleteTableCellAt(tr, mappedPos);
300
+ deleteTableCellAt(tr, mappedPos, emptiedTables);
394
301
  resolvedTableCellStructure = true;
395
302
  }
396
303
  if (failedTableCellMergeResolution) return false;
304
+ for (const { position, mapFrom } of emptiedTables) removeRowsWithoutCells(tr, tr.mapping.slice(mapFrom).map(position));
397
305
  if (resolvedTableCellStructure) markStructuralChange(tr);
398
- if (bulkInlineChangeTracking) markChangedParagraphRanges(tr, bulkInlineChangeTracking);
306
+ pPrMarkOps.sort((a, b) => b.paragraphPos - a.paragraphPos);
307
+ for (const op of pPrMarkOps) {
308
+ const mappedPos = tr.mapping.map(op.paragraphPos);
309
+ const paragraph = tr.doc.nodeAt(mappedPos);
310
+ if (!paragraph || paragraph.type.name !== "paragraph") continue;
311
+ if (op.action === "clear") {
312
+ tr.setNodeAttribute(mappedPos, "pPrMark", null);
313
+ continue;
314
+ }
315
+ if (moveTextBoxesPastNextParagraph(tr, mappedPos)) markStructuralChange(tr);
316
+ const joinPos = mappedPos + paragraph.nodeSize;
317
+ let nextPos = joinPos;
318
+ const boundaries = [];
319
+ while (nextPos < tr.doc.content.size) {
320
+ const boundary = tr.doc.nodeAt(nextPos);
321
+ if (boundary?.type.name !== "blockBookmarkBoundary") break;
322
+ boundaries.push(boundary);
323
+ nextPos += boundary.nodeSize;
324
+ }
325
+ const nextNode = nextPos < tr.doc.content.size ? tr.doc.nodeAt(nextPos) : null;
326
+ if (!(nextNode?.type.name === paragraph.type.name)) {
327
+ const resolved = tr.doc.resolve(mappedPos);
328
+ const endsItsContainer = paragraphEndsItsContainer(resolved, paragraph.type.name);
329
+ const canGo = op.markWasAdded || !endsItsContainer;
330
+ if (holdsNoContent(paragraph) && canGo && resolved.parent.childCount > 1) {
331
+ if (ownsSectionEndpoint(paragraph)) {
332
+ removedSectionEndpointCount++;
333
+ removedSectionReferences.push(...sectionReferencesOf(paragraph));
334
+ }
335
+ tr.delete(mappedPos, mappedPos + paragraph.nodeSize);
336
+ continue;
337
+ }
338
+ tr.setNodeAttribute(mappedPos, "pPrMark", null);
339
+ continue;
340
+ }
341
+ try {
342
+ if (boundaries.length > 0) {
343
+ const emptyFirstParagraph = holdsNoContent(paragraph);
344
+ const joinedAttrs = {
345
+ ...(emptyFirstParagraph ? nextNode : paragraph).attrs,
346
+ pPrMark: nextNode.attrs["pPrMark"],
347
+ _sectionProperties: nextNode.attrs["_sectionProperties"]
348
+ };
349
+ const leftToken = getProseParagraphPropertySourceToken(paragraph);
350
+ const rightToken = getProseParagraphPropertySourceToken(nextNode);
351
+ const inlineBookmarks = inlineBookmarksForParagraphJoin({
352
+ first: paragraph,
353
+ boundaries,
354
+ second: nextNode
355
+ });
356
+ if (!inlineBookmarks) continue;
357
+ tr.replaceWith(joinPos - 1, nextPos + 1, inlineBookmarks);
358
+ tr.setNodeMarkup(mappedPos, void 0, joinedAttrs);
359
+ if (emptyFirstParagraph) markParagraphPropertySourceTransfers(tr, [{
360
+ displacedToken: typeof leftToken === "string" ? leftToken : null,
361
+ selectedToken: typeof rightToken === "string" ? rightToken : null
362
+ }]);
363
+ } else joinAtParagraphMark({
364
+ tr,
365
+ paragraphPos: mappedPos,
366
+ paragraph,
367
+ next: nextNode
368
+ });
369
+ if (ownsSectionEndpoint(paragraph)) {
370
+ removedSectionEndpointCount++;
371
+ removedSectionReferences.push(...sectionReferencesOf(paragraph));
372
+ }
373
+ } catch {}
374
+ }
399
375
  if (removedSectionEndpointCount > 0) markTrackedSectionEndpointRemoval(tr, {
400
376
  sourceDoc: state.doc,
401
377
  removedEndpointCount: removedSectionEndpointCount,
@@ -452,6 +428,35 @@ const resolveRunPropertyChange = ({ tr, node, from, to, mark, mode, revisionSet,
452
428
  tr.removeMark(from, to, mark);
453
429
  const remaining = changes.filter((change) => revisionSet !== null && !revisionSet.has(change.info.id));
454
430
  if (remaining.length > 0) tr.addMark(from, to, mark.type.create({ changes: remaining }));
431
+ const emptyRuns = node.type.name === "field" || node.type.name === "structuredField" ? expectFieldAttrs(node)._docxEmptyResultRuns : void 0;
432
+ const resolvedRuns = emptyRuns ? resolveEmptyFieldResultRuns({
433
+ runs: emptyRuns,
434
+ mode,
435
+ revisionIds: revisionSet
436
+ }) : null;
437
+ if (resolvedRuns) {
438
+ const current = tr.doc.nodeAt(from);
439
+ if (!current) panic("A resolved field has no node at its position");
440
+ tr.setNodeMarkup(from, void 0, {
441
+ ...current.attrs,
442
+ _docxEmptyResultRuns: resolvedRuns.runs
443
+ });
444
+ if (resolvedRuns.visibleFormattingChanged) {
445
+ const styleContext = paragraphRunStyleContextAt({
446
+ doc: tr.doc,
447
+ pos: from,
448
+ styleResolver
449
+ });
450
+ for (const currentMark of node.marks) if (RUN_FORMATTING_MARK_NAMES.has(currentMark.type.name)) tr.removeMark(from, to, currentMark.type);
451
+ for (const nextMark of reconstructRejectedRunFormattingMarks({
452
+ node,
453
+ paragraphContext: styleContext,
454
+ previousFormatting: resolvedRuns.visibleFormatting,
455
+ styleResolver
456
+ })) tr.addMark(from, to, nextMark);
457
+ }
458
+ return;
459
+ }
455
460
  if (mode === "accept") return;
456
461
  const previousFormatting = matches.at(0)?.previousFormatting;
457
462
  const styleContext = paragraphRunStyleContextAt({
@@ -554,7 +559,7 @@ function isTableCellRevisionAttr(value) {
554
559
  const info = value.info;
555
560
  return typeof info === "object" && info !== null && "revisionId" in info && typeof info.revisionId === "number";
556
561
  }
557
- function deleteTableCellAt(tr, cellPos) {
562
+ function deleteTableCellAt(tr, cellPos, emptied) {
558
563
  const cell = tr.doc.nodeAt(cellPos);
559
564
  if (!cell || cell.type.name !== "tableCell" && cell.type.name !== "tableHeader") return;
560
565
  const resolved = tr.doc.resolve(cellPos);
@@ -566,7 +571,12 @@ function deleteTableCellAt(tr, cellPos) {
566
571
  const tablePosition = resolved.before(tableDepth);
567
572
  const cellOffset = cellPos - resolved.start(tableDepth);
568
573
  const removedColumn = TableMap.get(table).findCell(cellOffset).left;
569
- if (row.childCount > 1) {
574
+ const spansDown = Number(cell.attrs["rowspan"]) > 1;
575
+ if (row.childCount > 1 || spansDown) {
576
+ if (row.childCount === 1) emptied.push({
577
+ position: tablePosition,
578
+ mapFrom: tr.mapping.maps.length
579
+ });
570
580
  tr.delete(cellPos, cellPos + cell.nodeSize);
571
581
  reconcileTableGridAfterColumnRemoval({
572
582
  tr,
@@ -594,15 +604,10 @@ function deleteTableRowAt(tr, rowPos) {
594
604
  if (table.type.spec["tableRole"] !== "table") return;
595
605
  const rowIndex = resolved.index();
596
606
  if (table.childCount > 1) {
597
- const map = TableMap.get(table);
598
- removeRow(tr, {
599
- map,
607
+ removeTableRow(tr, {
608
+ map: TableMap.get(table),
600
609
  table,
601
- tableStart: resolved.start(),
602
- left: 0,
603
- top: rowIndex,
604
- right: map.width,
605
- bottom: rowIndex + 1
610
+ tableStart: resolved.start()
606
611
  }, rowIndex);
607
612
  return;
608
613
  }
@@ -640,48 +645,6 @@ function rangeCoversParagraphBoundary(from, to, pos, node) {
640
645
  function rangeCoversNode(from, to, pos, node) {
641
646
  return from <= pos && to >= pos + node.nodeSize;
642
647
  }
643
- /**
644
- * The attrs a reject restores for each property revision the shared node-attr
645
- * pass owns. Total over those kinds, so a revision the model gains either
646
- * declares a different resolution or states here what rejecting it restores.
647
- *
648
- * Each patch narrows the stored set to the property set its own element
649
- * carries. The casts are the ProseMirror attrs boundary: attrs are untyped,
650
- * and a record reached through the site filed under a kind is the one that
651
- * kind's parser and converter wrote.
652
- */
653
- const NODE_ATTRS_REJECT_PATCHES = {
654
- tablePropertyChange: (previousFormatting) => tableRejectAttrPatch(previousFormatting),
655
- tablePropertyExceptionChange: (previousFormatting) => tablePropertyExceptionsRejectAttrPatch(previousFormatting),
656
- tableRowPropertyChange: (previousFormatting) => tableRowRejectAttrPatch(previousFormatting),
657
- tableCellPropertyChange: (previousFormatting, node) => tableCellRejectAttrPatch(previousFormatting, node.attrs["_originalFormatting"])
658
- };
659
- /**
660
- * Resolve the tracked property-change records one site carries on a node.
661
- * Accept keeps the live formatting and clears the matched records; reject
662
- * additionally restores the stored previous formatting wholesale (the change
663
- * element stores the complete old property set — see propertyChangeScope.ts).
664
- * Returns the next attrs, or `null` when no record matches.
665
- */
666
- function resolveNodePropertyChangeAttrs(node, site, mode, revisionSet) {
667
- const changes = propertyRevisionRecords(node, site);
668
- if (changes.length === 0) return null;
669
- const matches = changes.filter((change) => {
670
- const metadata = propertyRevisionMetadata(change.info);
671
- return revisionSet === null || metadata !== null && revisionSet.has(metadata.id);
672
- });
673
- if (matches.length === 0) return null;
674
- const remaining = revisionSet === null ? [] : changes.filter((change) => !matches.includes(change));
675
- const nextAttrs = {
676
- ...node.attrs,
677
- [site.attr]: remaining.length > 0 ? remaining : null
678
- };
679
- if (mode === "reject") {
680
- const rejectPatch = NODE_ATTRS_REJECT_PATCHES[site.kind];
681
- for (const change of matches.toReversed()) Object.assign(nextAttrs, rejectPatch(change.previousFormatting, node));
682
- }
683
- return nextAttrs;
684
- }
685
648
  function isPPrMarkAttr(value) {
686
649
  if (typeof value !== "object" || value === null) return false;
687
650
  const kind = value.kind;
@@ -765,41 +728,68 @@ function acceptChange(from, to) {
765
728
  function rejectChange(from, to) {
766
729
  return resolveChange(from, to, "reject");
767
730
  }
731
+ const resolveAllChanges = (mode) => (state, dispatch) => {
732
+ if (!dispatch) return true;
733
+ const result = resolveStateStory(state, mode);
734
+ if (result.failed) return false;
735
+ if (result.resolved.eq(state.doc)) return true;
736
+ const tr = state.tr.step(new RevisionResolutionStep({
737
+ beforeDoc: state.doc,
738
+ afterDoc: result.resolved,
739
+ steps: result.steps,
740
+ positionMap: result.positionMap
741
+ }));
742
+ markChangedParagraphRanges(tr, {
743
+ ranges: finalRevisionParagraphRanges(result),
744
+ mappingFrom: tr.steps.length,
745
+ replacesStepMapAt: 0
746
+ });
747
+ markParagraphPropertySourceTransfers(tr, result.transfers);
748
+ if (result.structural) markStructuralChange(tr);
749
+ if (result.removedEndpointCount > 0) markTrackedSectionEndpointRemoval(tr, {
750
+ sourceDoc: state.doc,
751
+ removedEndpointCount: result.removedEndpointCount,
752
+ removedReferences: result.removedReferences
753
+ });
754
+ dispatch(tr);
755
+ return true;
756
+ };
768
757
  /**
769
- * Accept all tracked changes in the document.
758
+ * Accept all tracked changes in the document. Returns `false` while pending
759
+ * suggestions are present because this command cannot restage them.
770
760
  */
771
761
  function acceptAllChanges() {
772
- return (state, dispatch) => acceptChange(0, state.doc.content.size)(state, dispatch);
762
+ const resolve = resolveAllChanges("accept");
763
+ return (state, dispatch) => {
764
+ if (getSuggestions(state).length > 0) return false;
765
+ return resolve(state, dispatch);
766
+ };
773
767
  }
774
768
  /**
775
769
  * Reject all tracked changes in the document.
776
770
  */
777
771
  function rejectAllChanges() {
778
- return (state, dispatch) => rejectChange(0, state.doc.content.size)(state, dispatch);
772
+ return resolveAllChanges("reject");
779
773
  }
780
774
  /**
781
775
  * Resolve a complete state synchronously for a headless reader or writer.
782
776
  *
783
- * @internal The replacement transaction is consumed here and never exposed:
784
- * it is deliberately not an editor command and must not be transported or
785
- * mapped through concurrent edits.
777
+ * Uses the same single-step resolver as the interactive editor command.
786
778
  */
787
779
  function resolveAllChangesInHeadlessState(state, mode) {
788
780
  let resolvedState = state;
789
- resolveChange(0, state.doc.content.size, mode, void 0, "headless-bulk-inline")(state, (transaction) => {
781
+ resolveAllChanges(mode)(state, (transaction) => {
790
782
  resolvedState = state.apply(transaction);
791
783
  });
792
784
  return resolvedState;
793
785
  }
794
786
  /**
795
- * Resolve through the editor command path when a caller must map a position in
796
- * the reviewed document back to the tracked source. The bulk resolver is
797
- * faster, but deliberately replaces inline content without retaining mapping.
787
+ * Resolve a story and retain its position map for callers addressing the tracked source.
798
788
  */
799
789
  const resolveAllChangesInHeadlessStateWithMapping = (state, mode) => {
800
790
  let resolvedState = state;
801
791
  let mapping = new Mapping();
802
- resolveChange(0, state.doc.content.size, mode)(state, (transaction) => {
792
+ resolveAllChanges(mode)(state, (transaction) => {
803
793
  resolvedState = state.apply(transaction);
804
794
  mapping = transaction.mapping;
805
795
  });
@@ -933,6 +923,18 @@ const readSuggestedParagraphPropertyChange = (change) => {
933
923
  revisionId: change.info.id
934
924
  };
935
925
  };
926
+ const readSuggestedParagraphMark = (node) => {
927
+ if (node.type.name !== "paragraph") return null;
928
+ const mark = node.attrs["pPrMark"];
929
+ if (!isPPrMarkAttr(mark)) return null;
930
+ const { info } = mark;
931
+ if (!("provenance" in info) || info.provenance !== "suggested" || !("suggestionId" in info) || typeof info.suggestionId !== "string") return null;
932
+ return {
933
+ suggestionId: info.suggestionId,
934
+ revisionId: info.id,
935
+ kind: paragraphMarkWasAdded(mark.kind) ? "insertion" : "deletion"
936
+ };
937
+ };
936
938
  const readStructuralSuggestion = (node) => {
937
939
  const attrs = node.attrs;
938
940
  const name = node.type.name;
@@ -1006,6 +1008,16 @@ const collectSuggestions = (state) => {
1006
1008
  entry.revisionIds.add(structural.revisionId);
1007
1009
  }
1008
1010
  if (node.type.name === "paragraph") {
1011
+ const paragraphMark = readSuggestedParagraphMark(node);
1012
+ if (paragraphMark) {
1013
+ const entry = entryFor(paragraphMark.suggestionId);
1014
+ entry.segments.push({
1015
+ from: pos,
1016
+ to: pos + node.nodeSize
1017
+ });
1018
+ entry.kinds.add(paragraphMark.kind);
1019
+ entry.revisionIds.add(paragraphMark.revisionId);
1020
+ }
1009
1021
  const propertyChanges = expectParagraphAttrs(node)._propertyChanges;
1010
1022
  if (Array.isArray(propertyChanges)) for (const change of propertyChanges) {
1011
1023
  const suggested = readSuggestedParagraphPropertyChange(change);
@@ -1087,6 +1099,11 @@ function getSuggestions(state) {
1087
1099
  });
1088
1100
  return suggestions.toSorted((a, b) => (a.ranges[0]?.from ?? 0) - (b.ranges[0]?.from ?? 0));
1089
1101
  }
1102
+ /** The suggestion a revision belongs to, or `null` for an ordinary tracked change. */
1103
+ function suggestionIdOfRevision(state, revisionId) {
1104
+ for (const [suggestionId, entry] of collectSuggestions(state)) if (entry.revisionIds.has(revisionId)) return suggestionId;
1105
+ return null;
1106
+ }
1090
1107
  /**
1091
1108
  * The document range covering every mark belonging to `suggestionId`, plus the
1092
1109
  * revision ids those marks carry. Returns null when the suggestion is absent
@@ -1482,6 +1499,23 @@ const acceptSuggestions = (matchesSuggestion, options) => {
1482
1499
  ...nextAttrs ?? node.attrs,
1483
1500
  _propertyChanges: propertyChanges
1484
1501
  };
1502
+ const paragraphMark = readSuggestedParagraphMark(node);
1503
+ if (paragraphMark && matchesSuggestion(paragraphMark.suggestionId)) {
1504
+ const mark = node.attrs["pPrMark"];
1505
+ if (isPPrMarkAttr(mark)) nextAttrs = {
1506
+ ...nextAttrs ?? node.attrs,
1507
+ pPrMark: {
1508
+ ...mark,
1509
+ info: {
1510
+ ...mark.info,
1511
+ author: options.author,
1512
+ date,
1513
+ provenance: "user",
1514
+ suggestionId: null
1515
+ }
1516
+ }
1517
+ };
1518
+ }
1485
1519
  if (nextAttrs) {
1486
1520
  tr.setNodeMarkup(pos, void 0, nextAttrs);
1487
1521
  changed = true;
@@ -1809,4 +1843,4 @@ function findPreviousChange(state, startPos) {
1809
1843
  return result.value;
1810
1844
  }
1811
1845
  //#endregion
1812
- export { acceptAIEditRevision, acceptAllChanges, acceptAllSuggestions, acceptChange, acceptSuggestion, addCommentMark, findAIEditRevisionRange, findChangeAtPosition, findNextChange, findParagraphBoundaryChangeAtPosition, findPreviousChange, findSuggestionRange, getSuggestions, rejectAIEditRevision, rejectAllChanges, rejectAllSuggestions, rejectChange, rejectSuggestion, removeCommentMark, resolveAllChangesInHeadlessState, resolveAllChangesInHeadlessStateWithMapping };
1846
+ export { acceptAIEditRevision, acceptAllChanges, acceptAllSuggestions, acceptChange, acceptSuggestion, addCommentMark, findAIEditRevisionRange, findChangeAtPosition, findNextChange, findParagraphBoundaryChangeAtPosition, findPreviousChange, findSuggestionRange, getSuggestions, rejectAIEditRevision, rejectAllChanges, rejectAllSuggestions, rejectChange, rejectSuggestion, removeCommentMark, resolveAllChangesInHeadlessState, resolveAllChangesInHeadlessStateWithMapping, suggestionIdOfRevision };
@@ -2,8 +2,8 @@ import { document_d_exports } from "../../types/document.js";
2
2
  import { ContentControlFilter } from "../../content-controls/findContentControls.js";
3
3
  import { SetContentControlContentInput, SetContentControlValueInput } from "../../content-controls/mutateContentControls.js";
4
4
  import "../../content-controls/index.js";
5
- import { EditorState, Transaction } from "prosemirror-state";
6
5
  import { Node } from "prosemirror-model";
6
+ import { EditorState, Transaction } from "prosemirror-state";
7
7
  //#region src/prosemirror/commands/contentControls.d.ts
8
8
  type ForceOption = {
9
9
  force?: boolean;
@@ -1,6 +1,6 @@
1
1
  import { document_d_exports } from "../../types/document.js";
2
- import { Command, EditorState } from "prosemirror-state";
3
2
  import { Mark } from "prosemirror-model";
3
+ import { Command, EditorState } from "prosemirror-state";
4
4
  //#region src/prosemirror/commands/formatPainter.d.ts
5
5
  /**
6
6
  * Character-formatting marks the painter copies. Structural marks — comments,
@@ -3,8 +3,8 @@ import { TextColorAttrs } from "../schema/marks.js";
3
3
  import "../schema/index.js";
4
4
  import { clearFormatting, createRemoveMarkCommand, createSetMarkCommand, getMarkAttr, isMarkActive } from "../extensions/marks/markUtils.js";
5
5
  import { getHyperlinkAttrs, getSelectedText, isHyperlinkActive } from "../extensions/marks/HyperlinkExtension.js";
6
- import { Command } from "prosemirror-state";
7
6
  import { Mark } from "prosemirror-model";
7
+ import { Command } from "prosemirror-state";
8
8
  //#region src/prosemirror/commands/formatting.d.ts
9
9
  /**
10
10
  * textFormattingToMarks — wraps markUtils version to use singleton schema