@stll/folio-core 0.47.7 → 0.49.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 (213) hide show
  1. package/dist/ai-edits/apply.js +565 -121
  2. package/dist/ai-edits/minimal-replacement.d.ts +64 -0
  3. package/dist/ai-edits/minimal-replacement.js +282 -0
  4. package/dist/controller/fontReadiness.js +3 -3
  5. package/dist/controller/hyphenationReadiness.d.ts +19 -0
  6. package/dist/controller/hyphenationReadiness.js +47 -0
  7. package/dist/controller/layoutPipeline.d.ts +3 -0
  8. package/dist/controller/layoutPipeline.js +70 -18
  9. package/dist/display-list/build/buildDisplayList.js +39 -12
  10. package/dist/display-list/build/pageFurniture.d.ts +7 -1
  11. package/dist/display-list/build/pageFurniture.js +21 -8
  12. package/dist/display-list/build/paragraphPrimitives.js +68 -11
  13. package/dist/display-list/build/tablePrimitives.js +10 -6
  14. package/dist/display-list/build/textBoxPrimitives.js +1 -1
  15. package/dist/display-list/build/unsupported.d.ts +2 -2
  16. package/dist/display-list/build/unsupported.js +0 -0
  17. package/dist/display-list/dom/renderDisplayListToDom.js +0 -1
  18. package/dist/docx/attributeRemainder.js +10 -2
  19. package/dist/docx/blockContentParser.d.ts +2 -0
  20. package/dist/docx/blockContentParser.js +79 -64
  21. package/dist/docx/bulletMarkers.d.ts +18 -2
  22. package/dist/docx/bulletMarkers.js +27 -2
  23. package/dist/docx/commentParser.d.ts +2 -1
  24. package/dist/docx/commentParser.js +57 -45
  25. package/dist/docx/containerChildren.d.ts +21 -8
  26. package/dist/docx/containerChildren.js +39 -9
  27. package/dist/docx/documentParser.d.ts +5 -1
  28. package/dist/docx/documentParser.js +8 -5
  29. package/dist/docx/documentSectionFacts.d.ts +22 -0
  30. package/dist/docx/documentSectionFacts.js +43 -0
  31. package/dist/docx/drawingGroupChildren.d.ts +60 -0
  32. package/dist/docx/drawingGroupChildren.js +176 -0
  33. package/dist/docx/drawingUtils.js +3 -0
  34. package/dist/docx/fieldParser.d.ts +8 -1
  35. package/dist/docx/fieldParser.js +47 -3
  36. package/dist/docx/fontTableParser.js +34 -27
  37. package/dist/docx/footnoteParser.d.ts +3 -2
  38. package/dist/docx/footnoteParser.js +15 -12
  39. package/dist/docx/groupDrawingParser.d.ts +9 -2
  40. package/dist/docx/groupDrawingParser.js +125 -37
  41. package/dist/docx/headerFooterParser.d.ts +7 -2
  42. package/dist/docx/headerFooterParser.js +15 -5
  43. package/dist/docx/hyperlinkParser.d.ts +48 -36
  44. package/dist/docx/hyperlinkParser.js +97 -82
  45. package/dist/docx/numberingParser.js +108 -84
  46. package/dist/docx/packageParts.d.ts +45 -1
  47. package/dist/docx/packageParts.js +93 -2
  48. package/dist/docx/paraIdAttribute.d.ts +3 -2
  49. package/dist/docx/paragraphParser.d.ts +5 -1
  50. package/dist/docx/paragraphParser.js +468 -365
  51. package/dist/docx/paragraphProperties.js +123 -109
  52. package/dist/docx/paragraphPropertySource.d.ts +6 -1
  53. package/dist/docx/paragraphPropertySource.js +9 -1
  54. package/dist/docx/paragraphTextBoxEnrichment.d.ts +2 -1
  55. package/dist/docx/paragraphTextBoxEnrichment.js +143 -10
  56. package/dist/docx/parser.d.ts +7 -1
  57. package/dist/docx/parser.js +33 -16
  58. package/dist/docx/previewBudget.d.ts +55 -33
  59. package/dist/docx/previewBudget.js +59 -65
  60. package/dist/docx/rezip.js +41 -58
  61. package/dist/docx/runParser.d.ts +4 -1
  62. package/dist/docx/runParser.js +182 -184
  63. package/dist/docx/sdtProperties.js +87 -84
  64. package/dist/docx/sectionParser.js +169 -160
  65. package/dist/docx/selectiveSaveFlags.d.ts +10 -3
  66. package/dist/docx/selectiveSaveFlags.js +1 -1
  67. package/dist/docx/selectiveXmlPatch.d.ts +56 -34
  68. package/dist/docx/selectiveXmlPatch.js +222 -115
  69. package/dist/docx/serializer/groupTextBoxWriteBack.d.ts +12 -0
  70. package/dist/docx/serializer/groupTextBoxWriteBack.js +101 -0
  71. package/dist/docx/serializer/paragraphSerializer.js +47 -42
  72. package/dist/docx/serializer/runSerializer.d.ts +5 -1
  73. package/dist/docx/serializer/runSerializer.js +4 -3
  74. package/dist/docx/serializer/settingsSerializer.js +19 -1
  75. package/dist/docx/settingsParser.js +8 -0
  76. package/dist/docx/shapeAlternateContent.d.ts +25 -0
  77. package/dist/docx/shapeAlternateContent.js +52 -0
  78. package/dist/docx/streamingXmlParser.d.ts +6 -2
  79. package/dist/docx/streamingXmlParser.js +12 -7
  80. package/dist/docx/styleParser.js +34 -8
  81. package/dist/docx/tableParser.d.ts +21 -12
  82. package/dist/docx/tableParser.js +518 -441
  83. package/dist/docx/textBoxParser.d.ts +18 -5
  84. package/dist/docx/textBoxParser.js +12 -6
  85. package/dist/docx/verbatimCapture.d.ts +10 -8
  86. package/dist/docx/verbatimCapture.js +45 -2
  87. package/dist/docx/vmlImageParser.d.ts +15 -13
  88. package/dist/docx/vmlImageParser.js +75 -60
  89. package/dist/docx/vmlPreview.d.ts +3 -3
  90. package/dist/docx/vmlPreview.js +3 -4
  91. package/dist/docx/xmlNamespaceContext.d.ts +9 -0
  92. package/dist/docx/xmlNamespaceContext.js +54 -0
  93. package/dist/docx/xmlParser.d.ts +6 -3
  94. package/dist/docx/xmlParser.js +11 -41
  95. package/dist/docx/xmlResourceLimits.d.ts +2 -1
  96. package/dist/docx/xmlResourceLimits.js +4 -1
  97. package/dist/fonts/headlessMeasure.js +0 -0
  98. package/dist/headless-layout.d.ts +11 -2
  99. package/dist/headless-layout.js +153 -107
  100. package/dist/internal/headlessRevisionResolution.js +50 -13
  101. package/dist/internal/paragraphFormattingSerialization.js +3 -3
  102. package/dist/layout-bridge/convert/endnoteLayout.d.ts +65 -0
  103. package/dist/layout-bridge/convert/endnoteLayout.js +227 -0
  104. package/dist/layout-bridge/convert/footnoteLayout.d.ts +19 -3
  105. package/dist/layout-bridge/convert/footnoteLayout.js +40 -31
  106. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -7
  107. package/dist/layout-bridge/convert/headerFooterLayout.js +5 -20
  108. package/dist/layout-bridge/convert/paragraphMarkFormatting.d.ts +10 -0
  109. package/dist/layout-bridge/convert/paragraphMarkFormatting.js +59 -0
  110. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +29 -1
  111. package/dist/layout-bridge/convert/toFlowBlocks.js +284 -39
  112. package/dist/layout-bridge/engine/hitTest.js +5 -3
  113. package/dist/layout-bridge/engine/selectionRects.js +5 -3
  114. package/dist/layout-engine/anchorLayoutInCellCompatibility.d.ts +10 -0
  115. package/dist/layout-engine/anchorLayoutInCellCompatibility.js +22 -0
  116. package/dist/layout-engine/index.d.ts +2 -2
  117. package/dist/layout-engine/index.js +102 -14
  118. package/dist/layout-engine/justificationCompatibility.d.ts +1 -1
  119. package/dist/layout-engine/justificationCompatibility.js +9 -5
  120. package/dist/layout-engine/keep-together.d.ts +15 -6
  121. package/dist/layout-engine/keep-together.js +43 -16
  122. package/dist/layout-engine/layoutInstrumentation.d.ts +8 -2
  123. package/dist/layout-engine/layoutInstrumentation.js +8 -1
  124. package/dist/layout-engine/measure/advanceComposition.js +50 -7
  125. package/dist/layout-engine/measure/hyphenationDictionaries.d.ts +74 -0
  126. package/dist/layout-engine/measure/hyphenationDictionaries.js +138 -0
  127. package/dist/layout-engine/measure/hyphenationPreload.d.ts +11 -0
  128. package/dist/layout-engine/measure/hyphenationPreload.js +24 -0
  129. package/dist/layout-engine/measure/lineBreakProvider.d.ts +12 -2
  130. package/dist/layout-engine/measure/lineBreakProvider.js +30 -30
  131. package/dist/layout-engine/measure/lineBreaks.d.ts +6 -1
  132. package/dist/layout-engine/measure/lineBreaks.js +10 -3
  133. package/dist/layout-engine/measure/listMarkerWidth.d.ts +9 -6
  134. package/dist/layout-engine/measure/listMarkerWidth.js +20 -22
  135. package/dist/layout-engine/measure/measureBlocks.js +46 -10
  136. package/dist/layout-engine/measure/measureContainer.js +51 -8
  137. package/dist/layout-engine/measure/measureHelpers.d.ts +15 -3
  138. package/dist/layout-engine/measure/measureHelpers.js +34 -8
  139. package/dist/layout-engine/measure/measureParagraph.js +143 -101
  140. package/dist/layout-engine/measure/measureTypes.d.ts +5 -0
  141. package/dist/layout-engine/measure/smallCapsCasing.d.ts +56 -0
  142. package/dist/layout-engine/measure/smallCapsCasing.js +88 -0
  143. package/dist/layout-engine/measure/tabCalculator.d.ts +2 -0
  144. package/dist/layout-engine/measure/tabCalculator.js +2 -1
  145. package/dist/layout-engine/measure/tableCellFloating.d.ts +2 -0
  146. package/dist/layout-engine/measure/tableCellFloating.js +51 -19
  147. package/dist/layout-engine/measure/tableCellGrid.d.ts +28 -3
  148. package/dist/layout-engine/measure/tableCellGrid.js +45 -5
  149. package/dist/layout-engine/measure/tableFragmentBorderGeometry.js +2 -1
  150. package/dist/layout-engine/noteAreaFlow.d.ts +19 -0
  151. package/dist/layout-engine/noteAreaFlow.js +83 -0
  152. package/dist/layout-engine/paginator.d.ts +12 -1
  153. package/dist/layout-engine/paginator.js +18 -2
  154. package/dist/layout-engine/paragraphSpacing.d.ts +4 -2
  155. package/dist/layout-engine/paragraphSpacing.js +2 -1
  156. package/dist/layout-engine/tableRowBreak.d.ts +8 -1
  157. package/dist/layout-engine/tableRowBreak.js +25 -2
  158. package/dist/layout-engine/types.d.ts +108 -3
  159. package/dist/layout-engine/types.js +96 -1
  160. package/dist/layout-painter/index.d.ts +3 -0
  161. package/dist/layout-painter/renderPage.js +32 -83
  162. package/dist/layout-painter/renderParagraph.d.ts +6 -1
  163. package/dist/layout-painter/renderParagraph.js +75 -26
  164. package/dist/layout-painter/renderTable.js +26 -13
  165. package/dist/layout-painter/renderTextBox.d.ts +12 -2
  166. package/dist/layout-painter/renderTextBox.js +26 -2
  167. package/dist/prosemirror/alternateContentAttrs.d.ts +9 -0
  168. package/dist/prosemirror/alternateContentAttrs.js +35 -0
  169. package/dist/prosemirror/attrs/index.d.ts +9 -9
  170. package/dist/prosemirror/attrs/index.js +133 -11
  171. package/dist/prosemirror/commands/comments.js +51 -41
  172. package/dist/prosemirror/contentControlRevisions.d.ts +43 -0
  173. package/dist/prosemirror/contentControlRevisions.js +84 -0
  174. package/dist/prosemirror/conversion/fromProseDoc.js +54 -23
  175. package/dist/prosemirror/conversion/markInterner.d.ts +21 -0
  176. package/dist/prosemirror/conversion/markInterner.js +90 -0
  177. package/dist/prosemirror/conversion/toProseDoc.js +117 -58
  178. package/dist/prosemirror/extensions/core/DocExtension.js +2 -1
  179. package/dist/prosemirror/extensions/core/ParagraphExtension.js +1 -0
  180. package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.d.ts +7 -7
  181. package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +7 -7
  182. package/dist/prosemirror/extensions/marks/markUtils.d.ts +6 -2
  183. package/dist/prosemirror/extensions/marks/markUtils.js +39 -51
  184. package/dist/prosemirror/extensions/nodes/FieldExtension.js +6 -3
  185. package/dist/prosemirror/extensions/nodes/SdtExtension.js +9 -2
  186. package/dist/prosemirror/extensions/nodes/ShapeExtension.js +1 -0
  187. package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +5 -1
  188. package/dist/prosemirror/listMarker.d.ts +1 -0
  189. package/dist/prosemirror/listMarker.js +4 -2
  190. package/dist/prosemirror/listRenderingAttrs.d.ts +1 -0
  191. package/dist/prosemirror/listRenderingAttrs.js +3 -0
  192. package/dist/prosemirror/paragraphDirection.d.ts +29 -2
  193. package/dist/prosemirror/paragraphDirection.js +21 -2
  194. package/dist/prosemirror/plugins/suggestionMode.js +37 -8
  195. package/dist/prosemirror/rejoinRunCarriers.d.ts +27 -0
  196. package/dist/prosemirror/rejoinRunCarriers.js +66 -0
  197. package/dist/prosemirror/runIdentityAcrossRevisions.d.ts +10 -0
  198. package/dist/prosemirror/runIdentityAcrossRevisions.js +90 -0
  199. package/dist/prosemirror/schema/nodes.d.ts +50 -6
  200. package/dist/prosemirror/textBoxHostParagraph.d.ts +13 -0
  201. package/dist/prosemirror/textBoxHostParagraph.js +21 -0
  202. package/dist/prosemirror/validation.js +91 -80
  203. package/dist/types/content.d.ts +2 -2
  204. package/dist/utils/createDocument.js +10 -1
  205. package/dist/utils/scriptSegments.d.ts +33 -4
  206. package/dist/utils/scriptSegments.js +39 -6
  207. package/dist/utils/textFormattingMerge.d.ts +17 -3
  208. package/dist/utils/textFormattingMerge.js +18 -12
  209. package/dist/utils/trailingText.d.ts +22 -0
  210. package/dist/utils/trailingText.js +32 -0
  211. package/package.json +2 -2
  212. package/dist/layout-engine/justifiedLineFit.d.ts +0 -7
  213. package/dist/layout-engine/justifiedLineFit.js +0 -6
@@ -14,6 +14,7 @@ import { panic } from "better-result";
14
14
  import { DRAWING_RAW_XML_MODES, THEME_COLORS, isOoxmlSymbolCharacter } from "@stll/docx-core/model";
15
15
  import { isSafePreservedChildXml, isWithinPreservedMarkupBudget } from "@stll/docx-core/schema";
16
16
  //#region src/prosemirror/attrs/index.ts
17
+ const RUN_FORMATTING_VALUE_PROPERTY_SET = new Set(RUN_FORMATTING_VALUE_PROPERTIES);
17
18
  const PRESERVED_XML_LEVEL_VALUES = new Set(Object.values(PRESERVED_XML_LEVELS));
18
19
  const IMAGE_DISPLAY_MODES = [
19
20
  "inline",
@@ -149,15 +150,12 @@ const SECTION_VERTICAL_ALIGNMENTS = [
149
150
  "bottom"
150
151
  ];
151
152
  const OMITTED_GRID_SLOT_VALUES = ["before", "after"];
152
- const paragraphAttrsCache = /* @__PURE__ */ new WeakMap();
153
153
  const hardBreakAttrsCache = /* @__PURE__ */ new WeakMap();
154
154
  const pageBreakRunAttrsCache = /* @__PURE__ */ new WeakMap();
155
155
  const tabAttrsCache = /* @__PURE__ */ new WeakMap();
156
156
  const symbolAttrsCache = /* @__PURE__ */ new WeakMap();
157
157
  const preservedXmlAttrsCache = /* @__PURE__ */ new WeakMap();
158
158
  const preservedBlockAttrsCache = /* @__PURE__ */ new WeakMap();
159
- const tableAttrsCache = /* @__PURE__ */ new WeakMap();
160
- const tableRowAttrsCache = /* @__PURE__ */ new WeakMap();
161
159
  const tableCellAttrsCache = /* @__PURE__ */ new WeakMap();
162
160
  const imageAttrsCache = /* @__PURE__ */ new WeakMap();
163
161
  const fieldAttrsCache = /* @__PURE__ */ new WeakMap();
@@ -185,7 +183,36 @@ const runIdentityAttrsCache = /* @__PURE__ */ new WeakMap();
185
183
  const inlineWrapperAttrsCache = /* @__PURE__ */ new WeakMap();
186
184
  const runFormattingOverrideAttrsCache = /* @__PURE__ */ new WeakMap();
187
185
  const hyperlinkAttrsCache = /* @__PURE__ */ new WeakMap();
188
- const readParagraphAttrs = (node) => {
186
+ /**
187
+ * Read a node's attrs once per node. Nodes are immutable, and one conversion
188
+ * reads each paragraph, table and row several times (node validation, the
189
+ * bookmark walk, numbering). The cached result is frozen, value and issues
190
+ * included, so no caller can change what the next one reads.
191
+ */
192
+ const memoizeNodeAttrsReader = (read) => {
193
+ const results = /* @__PURE__ */ new WeakMap();
194
+ return (node) => {
195
+ const cached = results.get(node);
196
+ if (cached !== void 0) return cached;
197
+ const result = freezeAttrsResult(read(node));
198
+ results.set(node, result);
199
+ return result;
200
+ };
201
+ };
202
+ const freezeAttrsResult = (result) => {
203
+ if (!result.ok) {
204
+ const issues = result.issues.map((issue) => Object.freeze({ ...issue }));
205
+ return Object.freeze({
206
+ ok: false,
207
+ issues: Object.freeze(issues)
208
+ });
209
+ }
210
+ return Object.freeze({
211
+ ok: true,
212
+ value: Object.freeze(result.value)
213
+ });
214
+ };
215
+ const readParagraphAttrsUncached = (node) => {
189
216
  const attrs = attrsRecord(node.attrs);
190
217
  const issues = [];
191
218
  expectNodeType(node, "paragraph", issues);
@@ -244,6 +271,7 @@ const readParagraphAttrs = (node) => {
244
271
  });
245
272
  optionalStringArray(attrs, "listLevelNumFmts", "paragraph.attrs.listLevelNumFmts", issues);
246
273
  optionalNumberArray(attrs, "listLevelStarts", "paragraph.attrs.listLevelStarts", issues);
274
+ optionalTabStops(attrs, "listLevelTabs", "paragraph.attrs.listLevelTabs", issues);
247
275
  optionalNumber(attrs, "listAbstractNumId", "paragraph.attrs.listAbstractNumId", issues);
248
276
  optionalBorderMap(attrs, "borders", "paragraph.attrs.borders", issues, [
249
277
  "top",
@@ -271,7 +299,8 @@ const readParagraphAttrs = (node) => {
271
299
  optionalPreservedAttributes(attrs, "_preservedAttributes", "paragraph.attrs._preservedAttributes", issues);
272
300
  return attrsResult(attrs, issues);
273
301
  };
274
- const expectParagraphAttrs = (node) => expectCachedNodeAttrs(node, paragraphAttrsCache, readParagraphAttrs, "paragraph attrs");
302
+ const readParagraphAttrs = memoizeNodeAttrsReader(readParagraphAttrsUncached);
303
+ const expectParagraphAttrs = (node) => expectAttrs(readParagraphAttrs(node), "paragraph attrs");
275
304
  const readHardBreakAttrs = (node) => {
276
305
  const attrs = attrsRecord(node.attrs);
277
306
  const issues = [];
@@ -348,7 +377,7 @@ const readPreservedBlockAttrs = (node) => {
348
377
  return attrsResult(attrs, issues);
349
378
  };
350
379
  const expectPreservedBlockAttrs = (node) => expectCachedNodeAttrs(node, preservedBlockAttrsCache, readPreservedBlockAttrs, "preservedBlock attrs");
351
- const readTableAttrs = (node) => {
380
+ const readTableAttrsUncached = (node) => {
352
381
  const attrs = attrsRecord(node.attrs);
353
382
  const issues = [];
354
383
  expectNodeType(node, "table", issues);
@@ -375,8 +404,9 @@ const readTableAttrs = (node) => {
375
404
  optionalTablePreservedMarkup(attrs, "_preserved", "table.attrs._preserved", issues);
376
405
  return attrsResult(attrs, issues);
377
406
  };
378
- const expectTableAttrs = (node) => expectCachedNodeAttrs(node, tableAttrsCache, readTableAttrs, "table attrs");
379
- const readTableRowAttrs = (node) => {
407
+ const readTableAttrs = memoizeNodeAttrsReader(readTableAttrsUncached);
408
+ const expectTableAttrs = (node) => expectAttrs(readTableAttrs(node), "table attrs");
409
+ const readTableRowAttrsUncached = (node) => {
380
410
  const attrs = attrsRecord(node.attrs);
381
411
  const issues = [];
382
412
  expectNodeType(node, "tableRow", issues);
@@ -399,7 +429,8 @@ const readTableRowAttrs = (node) => {
399
429
  optionalTablePreservedMarkup(attrs, "_preserved", "tableRow.attrs._preserved", issues);
400
430
  return attrsResult(attrs, issues);
401
431
  };
402
- const expectTableRowAttrs = (node) => expectCachedNodeAttrs(node, tableRowAttrsCache, readTableRowAttrs, "table row attrs");
432
+ const readTableRowAttrs = memoizeNodeAttrsReader(readTableRowAttrsUncached);
433
+ const expectTableRowAttrs = (node) => expectAttrs(readTableRowAttrs(node), "table row attrs");
403
434
  const readTableCellAttrs = (node) => {
404
435
  const attrs = attrsRecord(node.attrs);
405
436
  const issues = [];
@@ -509,6 +540,7 @@ const readFieldAttrs = (node) => {
509
540
  requiredOneOf(attrs, "fieldKind", "field.attrs.fieldKind", issues, FIELD_KINDS);
510
541
  optionalBoolean(attrs, "fldLock", "field.attrs.fldLock", issues);
511
542
  optionalBoolean(attrs, "dirty", "field.attrs.dirty", issues);
543
+ optionalBoolean(attrs, "fieldResultIsFallback", "field.attrs.fieldResultIsFallback", issues);
512
544
  return attrsResult(attrs, issues);
513
545
  };
514
546
  const expectFieldAttrs = (node) => expectCachedNodeAttrs(node, fieldAttrsCache, readFieldAttrs, "field attrs");
@@ -606,6 +638,7 @@ const readShapeAttrs = (node) => {
606
638
  optionalNumber(attrs, "shadowOffsetY", "shape.attrs.shadowOffsetY", issues);
607
639
  optionalString(attrs, "glowColor", "shape.attrs.glowColor", issues);
608
640
  optionalNumber(attrs, "glowRadius", "shape.attrs.glowRadius", issues);
641
+ optionalAlternateContent(attrs, "shape.attrs._docxAlternateContent", issues);
609
642
  return attrsResult(attrs, issues);
610
643
  };
611
644
  const expectShapeAttrs = (node) => expectCachedNodeAttrs(node, shapeAttrsCache, readShapeAttrs, "shape attrs");
@@ -623,6 +656,7 @@ const readTextBoxAttrs = (node) => {
623
656
  optionalString(attrs, "alt", "textBox.attrs.alt", issues);
624
657
  optionalString(attrs, "title", "textBox.attrs.title", issues);
625
658
  optionalString(attrs, "fillColor", "textBox.attrs.fillColor", issues);
659
+ optionalGradientFill(attrs, "gradientFill", "textBox.attrs.gradientFill", issues);
626
660
  optionalNumber(attrs, "outlineWidth", "textBox.attrs.outlineWidth", issues);
627
661
  optionalAuthoredEmu(attrs, "_docxAuthoredEmu", "textBox.attrs._docxAuthoredEmu", issues, TEXT_BOX_AUTHORED_EMU_ATTRS);
628
662
  optionalString(attrs, "outlineColor", "textBox.attrs.outlineColor", issues);
@@ -650,12 +684,15 @@ const readTextBoxAttrs = (node) => {
650
684
  optionalEffectExtentSlots(attrs, "wrapEffectExtentSlots", "textBox.attrs.wrapEffectExtentSlots", issues);
651
685
  optionalWrapPolygon(attrs, "wrapPolygon", "textBox.attrs.wrapPolygon", issues);
652
686
  optionalOneOf(attrs, "_docxPlacement", "textBox.attrs._docxPlacement", issues, TEXT_BOX_DOCX_PLACEMENTS);
687
+ optionalAlternateContent(attrs, "textBox.attrs._docxAlternateContent", issues);
653
688
  optionalString(attrs, "_docxGroupId", "textBox.attrs._docxGroupId", issues);
654
689
  optionalString(attrs, "_docxAnchorId", "textBox.attrs._docxAnchorId", issues);
690
+ optionalDrawingGroupChild(attrs, "_docxGroupChild", "textBox.attrs._docxGroupChild", issues);
655
691
  requiredTextBoxBodyContentState(attrs, issues);
656
692
  optionalTextBoxTrackedChange(attrs, issues);
657
693
  optionalTextBoxInlineSdts(attrs, issues);
658
694
  optionalPreservedAttributes(attrs, "_preservedAttributes", "textBox.attrs._preservedAttributes", issues);
695
+ optionalRecord(attrs, "_docxHostParagraph", "textBox.attrs._docxHostParagraph", issues);
659
696
  return attrsResult(attrs, issues);
660
697
  };
661
698
  const expectTextBoxAttrs = (node) => expectCachedNodeAttrs(node, textBoxAttrsCache, readTextBoxAttrs, "text box attrs");
@@ -1042,8 +1079,7 @@ const readRunFormattingOverrideMarkAttrs = (mark) => {
1042
1079
  optionalTextFormatting(attrs, "_authoredValues", "runFormattingOverride.attrs._authoredValues", issues);
1043
1080
  const authoredValues = attrs["_authoredValues"];
1044
1081
  if (isRecord(authoredValues)) {
1045
- const allowed = new Set(RUN_FORMATTING_VALUE_PROPERTIES);
1046
- for (const property of Object.keys(authoredValues)) if (!allowed.has(property)) issues.push({
1082
+ for (const property of Object.keys(authoredValues)) if (!RUN_FORMATTING_VALUE_PROPERTY_SET.has(property)) issues.push({
1047
1083
  path: `runFormattingOverride.attrs._authoredValues.${property}`,
1048
1084
  message: "Expected a non-boolean authored formatting property."
1049
1085
  });
@@ -1587,6 +1623,20 @@ const optionalTextBoxTrackedChange = (attrs, issues) => {
1587
1623
  requiredString(info, "author", "textBox.attrs._docxTrackedChange.info.author", issues);
1588
1624
  optionalString(info, "date", "textBox.attrs._docxTrackedChange.info.date", issues);
1589
1625
  };
1626
+ /** `_docxAlternateContent`: a captured element and its node fingerprint, or absent. */
1627
+ const optionalAlternateContent = (attrs, path, issues) => {
1628
+ const value = attrs["_docxAlternateContent"];
1629
+ if (value === void 0 || value === null) return;
1630
+ if (!isRecord(value)) {
1631
+ issues.push({
1632
+ path,
1633
+ message: "Expected an object."
1634
+ });
1635
+ return;
1636
+ }
1637
+ requiredString(value, "xml", `${path}.xml`, issues);
1638
+ requiredString(value, "fingerprint", `${path}.fingerprint`, issues);
1639
+ };
1590
1640
  const requiredTextBoxBodyContentState = (attrs, issues) => {
1591
1641
  const value = attrs["_docxTextBodyContentState"];
1592
1642
  if (!isRecord(value)) {
@@ -1636,6 +1686,7 @@ const validateSdtAttrsRecord = (attrs, path, issues) => {
1636
1686
  optionalPreservedMarkup(attrs, "_preserved", `${path}._preserved`, issues);
1637
1687
  optionalString(attrs, "rawEndPropertiesXml", `${path}.rawEndPropertiesXml`, issues);
1638
1688
  optionalSdtEndProperties(attrs, `${path}.endProperties`, issues);
1689
+ optionalNumberArray(attrs, "_docxEnclosingRevisionIds", `${path}._docxEnclosingRevisionIds`, issues);
1639
1690
  };
1640
1691
  /**
1641
1692
  * The attribute remainder an authored element's record carries.
@@ -2199,6 +2250,7 @@ const validateParagraphFormatting = (value, path, issues) => {
2199
2250
  ]);
2200
2251
  optionalOneOfArray(value, "listLevelNumFmts", `${path}.listLevelNumFmts`, issues, COUNTER_FORMAT_VALUES);
2201
2252
  optionalNumberArray(value, "listLevelStarts", `${path}.listLevelStarts`, issues);
2253
+ optionalTabStops(value, "listLevelTabs", `${path}.listLevelTabs`, issues);
2202
2254
  optionalAutospacingBase(value, `${path}._autospacingBase`, issues);
2203
2255
  for (const key of ["numPr", "numPrFromStyle"]) optionalParagraphNumbering(value, key, `${path}.${key}`, issues);
2204
2256
  const direction = value["direction"];
@@ -2523,6 +2575,76 @@ const optionalWrapPolygon = (attrs, key, path, issues) => {
2523
2575
  readWrapPolygonPoint(point, `${path}.lineTo[${index}]`, issues);
2524
2576
  });
2525
2577
  };
2578
+ /** A text box's gradient fill: the model's `ShapeFill`, and only its gradient arm. */
2579
+ const optionalGradientFill = (attrs, key, path, issues) => {
2580
+ const value = attrs[key];
2581
+ if (value === void 0 || value === null) return;
2582
+ if (!isRecord(value)) {
2583
+ issues.push({
2584
+ path,
2585
+ message: "Expected an object."
2586
+ });
2587
+ return;
2588
+ }
2589
+ if (value["type"] !== "gradient") issues.push({
2590
+ path: `${path}.type`,
2591
+ message: "Expected \"gradient\"."
2592
+ });
2593
+ optionalString(value, "rawXml", `${path}.rawXml`, issues);
2594
+ const gradient = value["gradient"];
2595
+ if (!isRecord(gradient)) {
2596
+ issues.push({
2597
+ path: `${path}.gradient`,
2598
+ message: "Expected an object."
2599
+ });
2600
+ return;
2601
+ }
2602
+ optionalOneOf(gradient, "type", `${path}.gradient.type`, issues, SHAPE_GRADIENT_TYPES);
2603
+ optionalNumber(gradient, "angle", `${path}.gradient.angle`, issues);
2604
+ optionalBoolean(gradient, "scaled", `${path}.gradient.scaled`, issues);
2605
+ const stops = gradient["stops"];
2606
+ if (!Array.isArray(stops)) {
2607
+ issues.push({
2608
+ path: `${path}.gradient.stops`,
2609
+ message: "Expected an array."
2610
+ });
2611
+ return;
2612
+ }
2613
+ stops.forEach((stop, index) => {
2614
+ const stopPath = `${path}.gradient.stops[${index}]`;
2615
+ if (!isRecord(stop)) {
2616
+ issues.push({
2617
+ path: stopPath,
2618
+ message: "Expected a gradient stop object."
2619
+ });
2620
+ return;
2621
+ }
2622
+ if (typeof stop["position"] !== "number") issues.push({
2623
+ path: `${stopPath}.position`,
2624
+ message: "Expected a number."
2625
+ });
2626
+ optionalColorValue(stop, "color", `${stopPath}.color`, issues);
2627
+ });
2628
+ };
2629
+ /** Where a text box sits inside a DrawingML group: its element path and two fingerprints. */
2630
+ const optionalDrawingGroupChild = (attrs, key, path, issues) => {
2631
+ const value = attrs[key];
2632
+ if (value === void 0 || value === null) return;
2633
+ if (!isRecord(value)) {
2634
+ issues.push({
2635
+ path,
2636
+ message: "Expected an object."
2637
+ });
2638
+ return;
2639
+ }
2640
+ const childPath = value["path"];
2641
+ if (!Array.isArray(childPath) || childPath.length === 0 || !childPath.every((index) => Number.isInteger(index) && index >= 0)) issues.push({
2642
+ path: `${path}.path`,
2643
+ message: "Expected a non-empty array of indices."
2644
+ });
2645
+ requiredString(value, "group", `${path}.group`, issues);
2646
+ requiredString(value, "content", `${path}.content`, issues);
2647
+ };
2526
2648
  /** `a:hlinkClick` as captured: its own bytes, plus the target it named. */
2527
2649
  const optionalDocPrLink = (attrs, key, path, issues) => {
2528
2650
  const value = attrs[key];
@@ -4,11 +4,13 @@ import { appendHeadlessInlineResolution } from "../../internal/headlessRevisionR
4
4
  import { stateAllowsHeadlessRevisionResolution } from "../../internal/headlessRevisionResolutionGuard.js";
5
5
  import { expectParagraphAttrs, expectRunPropertyChangeMarkAttrs, expectTrackedChangeMarkAttrs } from "../attrs/index.js";
6
6
  import { addedBreakCarrierBefore, finalParagraphsOf, paragraphEndsItsContainer } from "../containerFinalParagraph.js";
7
+ import { enclosingRevisionIds, resolutionRemovesControl, withoutResolvedEnclosures } from "../contentControlRevisions.js";
7
8
  import { resolveParagraphDefaultTextFormatting } from "../conversion/toProseDoc.js";
8
9
  import { markChangedParagraphRanges, markStructuralChange, markTrackedSectionEndpointRemoval } from "../extensions/features/ParagraphChangeTrackerExtension.js";
9
10
  import "../extensions/nodes/SdtExtension.js";
10
11
  import { getDocumentStyleResolver } from "../plugins/documentStyles.js";
11
12
  import { setParagraphAttrsWithRebasedRunFormatting } from "../rebaseParagraphRunFormatting.js";
13
+ import { rejoinRunsAt } from "../rejoinRunCarriers.js";
12
14
  import { getFolioNodeRevisionCarriers, nodePropertyRevisionSites, propertyRevisionMetadata, propertyRevisionRecords } from "../revisionCarriers.js";
13
15
  import { RUN_FORMATTING_MARK_NAMES } from "../runFormattingMarkNames.js";
14
16
  import { reconstructRejectedRunFormattingMarks } from "../runPropertyChangeResolution.js";
@@ -109,6 +111,8 @@ function resolveChange(from, to, mode, revisionIds, execution = "legacy") {
109
111
  if (dispatch) {
110
112
  const tr = state.tr;
111
113
  const deleteRanges = [];
114
+ /** Where resolved inline content began and ended, in `state.doc`. */
115
+ const resolvedBoundaries = [];
112
116
  const pPrMarkOps = [];
113
117
  const tableRowStructuralOps = [];
114
118
  const tableCellStructuralOps = [];
@@ -198,15 +202,27 @@ function resolveChange(from, to, mode, revisionIds, execution = "legacy") {
198
202
  const nodeEnd = pos + node.nodeSize;
199
203
  const rangeFrom = Math.max(from, pos);
200
204
  const rangeTo = Math.min(to, nodeEnd);
201
- if (node.type.name === "sdt" && removeType !== void 0 && rangeCoversNode(from, to, pos, node) && revisionCoversWholeControl(node, removeType, matchesRevision)) {
202
- deleteRanges.push({
203
- from: pos,
204
- to: nodeEnd
205
- });
206
- return false;
205
+ if (node.type.name === "sdt") {
206
+ if (!rangeCoversNode(from, to, pos, node)) return true;
207
+ const resolvesRevision = (revisionId) => revisionSet === null || revisionSet.has(revisionId);
208
+ if (resolutionRemovesControl({
209
+ control: node,
210
+ removeType,
211
+ resolves: resolvesRevision
212
+ })) {
213
+ deleteRanges.push({
214
+ from: pos,
215
+ to: nodeEnd
216
+ });
217
+ return false;
218
+ }
219
+ const released = withoutResolvedEnclosures(node, resolvesRevision);
220
+ if (released) tr.setNodeMarkup(pos, void 0, released);
221
+ return true;
207
222
  }
208
223
  const runPropertyChangeMark = node.marks.find((mark) => mark.type.name === "runPropertyChange");
209
224
  const removesNode = removeType !== void 0 && node.marks.some((mark) => mark.type === removeType && matchesRevision(mark));
225
+ if (removesNode || runPropertyChangeMark !== void 0 || node.marks.some((mark) => (mark.type === insertionType || mark.type === deletionType) && matchesRevision(mark))) resolvedBoundaries.push(rangeFrom, rangeTo);
210
226
  if (runPropertyChangeMark) resolveRunPropertyChange({
211
227
  tr,
212
228
  node,
@@ -386,6 +402,11 @@ function resolveChange(from, to, mode, revisionIds, execution = "legacy") {
386
402
  removedReferences: removedSectionReferences
387
403
  });
388
404
  if (!terminalTableDeletionIsPending(tr)) resolveTerminalTableReviewCarrier(tr, mode);
405
+ rejoinRunsAt({
406
+ tr,
407
+ boundaries: resolvedBoundaries.map((position) => tr.mapping.map(position)),
408
+ styleResolver
409
+ });
389
410
  if (tr.steps.length > 0) dispatch(tr);
390
411
  }
391
412
  return true;
@@ -620,24 +641,6 @@ function rangeCoversNode(from, to, pos, node) {
620
641
  return from <= pos && to >= pos + node.nodeSize;
621
642
  }
622
643
  /**
623
- * Whether a revision covers everything an inline content control holds.
624
- *
625
- * The save leg writes such a revision around the control (`w:ins > w:sdt`),
626
- * so resolving it is an operation over the control itself: a reader who
627
- * rejects an inserted control gets no control, not an empty one standing
628
- * where it was. A revision over part of the content is a revision over that
629
- * part, and a control that holds nothing is covered by nothing.
630
- */
631
- function revisionCoversWholeControl(node, removeType, matchesRevision) {
632
- if (node.childCount === 0) return false;
633
- for (let index = 0; index < node.childCount; index += 1) {
634
- const child = node.child(index);
635
- if (child.marks.some((mark) => mark.type === removeType && matchesRevision(mark))) continue;
636
- if (child.type.name !== "sdt" || !revisionCoversWholeControl(child, removeType, matchesRevision)) return false;
637
- }
638
- return true;
639
- }
640
- /**
641
644
  * The attrs a reject restores for each property revision the shared node-attr
642
645
  * pass owns. Total over those kinds, so a revision the model gains either
643
646
  * declares a different resolution or states here what rejecting it restores.
@@ -826,6 +829,7 @@ function findAIEditRevisionRange(state, revisionIds) {
826
829
  };
827
830
  state.doc.descendants((node, pos) => {
828
831
  for (const carrier of getFolioNodeRevisionCarriers(node, pos)) if (idSet.has(carrier.id)) includeRange(carrier.from, carrier.to);
832
+ if (node.type.name === "sdt" && enclosingRevisionIds(node).some((id) => idSet.has(id))) includeRange(pos, pos + node.nodeSize);
829
833
  if (node.type.name === "tableRow") for (const attrName of ["trIns", "trDel"]) {
830
834
  const marker = node.attrs[attrName];
831
835
  if (isTableRowRevisionAttr(marker) && idSet.has(marker.revisionId)) {
@@ -1724,24 +1728,30 @@ function expandTrackedChangeRange(state, mark, fromHint, toHint) {
1724
1728
  const carriesSameInlineMark = (node) => node?.isInline === true && node.marks.some((m) => m.eq(mark));
1725
1729
  let from = fromHint;
1726
1730
  let to = toHint;
1727
- let $from = state.doc.resolve(from);
1728
- let nodeBefore = $from.nodeBefore;
1729
- while (carriesSameInlineMark(nodeBefore)) {
1730
- from -= nodeBefore.nodeSize;
1731
- $from = state.doc.resolve(from);
1732
- nodeBefore = $from.nodeBefore;
1733
- }
1734
- let $to = state.doc.resolve(to);
1735
- let nodeAfter = $to.nodeAfter;
1736
- while (carriesSameInlineMark(nodeAfter)) {
1737
- to += nodeAfter.nodeSize;
1738
- $to = state.doc.resolve(to);
1739
- nodeAfter = $to.nodeAfter;
1731
+ const revisionId = mark.attrs["revisionId"];
1732
+ for (;;) {
1733
+ let $from = state.doc.resolve(from);
1734
+ let nodeBefore = $from.nodeBefore;
1735
+ while (carriesSameInlineMark(nodeBefore)) {
1736
+ from -= nodeBefore.nodeSize;
1737
+ $from = state.doc.resolve(from);
1738
+ nodeBefore = $from.nodeBefore;
1739
+ }
1740
+ let $to = state.doc.resolve(to);
1741
+ let nodeAfter = $to.nodeAfter;
1742
+ while (carriesSameInlineMark(nodeAfter)) {
1743
+ to += nodeAfter.nodeSize;
1744
+ $to = state.doc.resolve(to);
1745
+ nodeAfter = $to.nodeAfter;
1746
+ }
1747
+ const control = $from.parent;
1748
+ if (control.type.name !== "sdt" || typeof revisionId !== "number" || !enclosingRevisionIds(control).includes(revisionId) || from !== $from.start() || to !== $from.end()) return {
1749
+ from,
1750
+ to
1751
+ };
1752
+ from = $from.before();
1753
+ to = $from.after();
1740
1754
  }
1741
- return {
1742
- from,
1743
- to
1744
- };
1745
1755
  }
1746
1756
  /**
1747
1757
  * Find the next tracked change after the given position. Returns the full
@@ -0,0 +1,43 @@
1
+ import { Transaction } from "prosemirror-state";
2
+ import { MarkType, Node } from "prosemirror-model";
3
+ //#region src/prosemirror/contentControlRevisions.d.ts
4
+ declare const ENCLOSING_REVISION_IDS_ATTR = "_docxEnclosingRevisionIds";
5
+ /** The revisions whose element encloses `control`. */
6
+ declare const enclosingRevisionIds: (control: Node) => readonly number[];
7
+ /** `control`'s attrs with `revisionId` added to its enclosing revisions. */
8
+ declare const withEnclosingRevision: (control: Node, revisionId: number) => Node["attrs"] | null;
9
+ type ResolutionRemovesControlOptions = {
10
+ control: Node;
11
+ /** The revision mark type the resolution removes content under. */
12
+ removeType: MarkType | undefined;
13
+ /** Whether the resolution resolves revision `revisionId`. */
14
+ resolves: (revisionId: number) => boolean;
15
+ };
16
+ /**
17
+ * Whether resolving removes the control itself: a revision that encloses it is
18
+ * resolved in the direction that removes its content, and still covers all of
19
+ * it. Removing only the content leaves the control standing, emptied.
20
+ */
21
+ declare const resolutionRemovesControl: ({ control, removeType, resolves }: ResolutionRemovesControlOptions) => boolean;
22
+ /**
23
+ * `control`'s attrs without the enclosing revisions `resolved` names, or
24
+ * `null` when none of them is: a resolved revision no longer exists, and an id
25
+ * left behind would claim whatever revision is later given that id.
26
+ */
27
+ declare const withoutResolvedEnclosures: (control: Node, resolved: (revisionId: number) => boolean) => Node["attrs"] | null;
28
+ type EncloseWholeControlsOptions = {
29
+ tr: Transaction;
30
+ from: number;
31
+ to: number;
32
+ revisionId: number;
33
+ };
34
+ /**
35
+ * Record `revisionId` as enclosing every inline control `[from, to]` covers
36
+ * whole, opening and closing token included: the revision removes or adds the
37
+ * control, as deleting or inserting the same range directly would. A control
38
+ * the range covers only the content of is left alone, and its revision stays
39
+ * one over that content.
40
+ */
41
+ declare const encloseWholeControls: ({ tr, from, to, revisionId }: EncloseWholeControlsOptions) => void;
42
+ //#endregion
43
+ export { ENCLOSING_REVISION_IDS_ATTR, encloseWholeControls, enclosingRevisionIds, resolutionRemovesControl, withEnclosingRevision, withoutResolvedEnclosures };
@@ -0,0 +1,84 @@
1
+ import { expectTrackedChangeMarkAttrs } from "./attrs/index.js";
2
+ import "./extensions/nodes/SdtExtension.js";
3
+ //#region src/prosemirror/contentControlRevisions.ts
4
+ const ENCLOSING_REVISION_IDS_ATTR = "_docxEnclosingRevisionIds";
5
+ const isInlineControl = (node) => node.type.name === "sdt";
6
+ /** The revisions whose element encloses `control`. */
7
+ const enclosingRevisionIds = (control) => {
8
+ const ids = control.attrs[ENCLOSING_REVISION_IDS_ATTR];
9
+ return Array.isArray(ids) ? ids.filter((id) => typeof id === "number") : [];
10
+ };
11
+ /** `control`'s attrs with `revisionId` added to its enclosing revisions. */
12
+ const withEnclosingRevision = (control, revisionId) => {
13
+ const ids = enclosingRevisionIds(control);
14
+ return ids.includes(revisionId) ? null : {
15
+ ...control.attrs,
16
+ [ENCLOSING_REVISION_IDS_ATTR]: [...ids, revisionId]
17
+ };
18
+ };
19
+ const REMOVED_LAYERS = {
20
+ deletion: /* @__PURE__ */ new Set(["deletion", "moveFrom"]),
21
+ insertion: /* @__PURE__ */ new Set(["insertion", "moveTo"])
22
+ };
23
+ /** Whether `mark`, or a revision it is nested in, is `revisionId` of `removeType`'s kind. */
24
+ const carriesRevision = (mark, removeType, revisionId) => {
25
+ if (mark.type.name !== "insertion" && mark.type.name !== "deletion") return false;
26
+ const attrs = expectTrackedChangeMarkAttrs(mark);
27
+ if (mark.type === removeType && attrs.revisionId === revisionId) return true;
28
+ const removed = removeType.name === "deletion" ? REMOVED_LAYERS.deletion : REMOVED_LAYERS.insertion;
29
+ return (attrs._docxRevisionAncestors ?? []).some((layer) => layer.revisionId === revisionId && removed.has(layer.type));
30
+ };
31
+ const coveredBy = (node, covers) => {
32
+ if (node.childCount === 0) return false;
33
+ for (let index = 0; index < node.childCount; index += 1) {
34
+ const child = node.child(index);
35
+ if (child.marks.some(covers)) continue;
36
+ if (!isInlineControl(child) || !coveredBy(child, covers)) return false;
37
+ }
38
+ return true;
39
+ };
40
+ /**
41
+ * Whether resolving removes the control itself: a revision that encloses it is
42
+ * resolved in the direction that removes its content, and still covers all of
43
+ * it. Removing only the content leaves the control standing, emptied.
44
+ */
45
+ const resolutionRemovesControl = ({ control, removeType, resolves }) => {
46
+ if (removeType === void 0 || !isInlineControl(control)) return false;
47
+ return enclosingRevisionIds(control).some((revisionId) => resolves(revisionId) && coveredBy(control, (mark) => carriesRevision(mark, removeType, revisionId)));
48
+ };
49
+ /**
50
+ * `control`'s attrs without the enclosing revisions `resolved` names, or
51
+ * `null` when none of them is: a resolved revision no longer exists, and an id
52
+ * left behind would claim whatever revision is later given that id.
53
+ */
54
+ const withoutResolvedEnclosures = (control, resolved) => {
55
+ const ids = enclosingRevisionIds(control);
56
+ const remaining = ids.filter((revisionId) => !resolved(revisionId));
57
+ if (remaining.length === ids.length) return null;
58
+ return {
59
+ ...control.attrs,
60
+ [ENCLOSING_REVISION_IDS_ATTR]: remaining.length > 0 ? remaining : null
61
+ };
62
+ };
63
+ /**
64
+ * Record `revisionId` as enclosing every inline control `[from, to]` covers
65
+ * whole, opening and closing token included: the revision removes or adds the
66
+ * control, as deleting or inserting the same range directly would. A control
67
+ * the range covers only the content of is left alone, and its revision stays
68
+ * one over that content.
69
+ */
70
+ const encloseWholeControls = ({ tr, from, to, revisionId }) => {
71
+ const enclosed = [];
72
+ tr.doc.nodesBetween(from, to, (node, pos) => {
73
+ if (!isInlineControl(node) || pos < from || pos + node.nodeSize > to) return true;
74
+ const attrs = withEnclosingRevision(node, revisionId);
75
+ if (attrs) enclosed.push({
76
+ pos,
77
+ attrs
78
+ });
79
+ return true;
80
+ });
81
+ for (const { pos, attrs } of enclosed) tr.setNodeMarkup(pos, void 0, attrs);
82
+ };
83
+ //#endregion
84
+ export { ENCLOSING_REVISION_IDS_ATTR, encloseWholeControls, enclosingRevisionIds, resolutionRemovesControl, withEnclosingRevision, withoutResolvedEnclosures };