@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
@@ -2,8 +2,9 @@ import { rangedCommentIds } from "../../docx/commentAnchorIndex.js";
2
2
  import { resolveColorValueToHex } from "../../docx/drawingUtils.js";
3
3
  import { isInlineSdtContent, isTrackedChangeWrapperChild } from "../../docx/inlineWrapperContent.js";
4
4
  import { mergeParagraphNumbering as mergeParagraphNumbering$1, paragraphNumberingReferenceId as paragraphNumberingReferenceId$1 } from "../../docx/numberingReference.js";
5
- import { PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, createProseParagraphWithPropertySource, getDocumentParagraphPropertySourceContract, recreateProseNodeWithParagraphPropertySource, transportTableCellsWithParagraphPropertySources } from "../../docx/paragraphPropertySource.js";
5
+ import { PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, createProseParagraphWithPropertySource, getDocumentParagraphPropertySourceContract, proseParagraphAttrsWithoutPropertySource, recreateProseNodeWithParagraphPropertySource, transportTableCellsWithParagraphPropertySources } from "../../docx/paragraphPropertySource.js";
6
6
  import { isBaselineVertAlign } from "../../docx/runParser.js";
7
+ import { replayableShapeAlternateContent } from "../../docx/shapeAlternateContent.js";
7
8
  import { resolveTableLook } from "../../docx/tableLook.js";
8
9
  import { isCellMergeContinuation } from "../../docx/tableParser.js";
9
10
  import { copiedWrapPolygon } from "../../docx/wrapPolygon.js";
@@ -16,9 +17,11 @@ import { mergeParagraphFormatting, mergeParagraphTabStops } from "../../utils/pa
16
17
  import { tableOfContentsStyleLevel } from "../../utils/tableOfContentsStyle.js";
17
18
  import { mergeTextFormatting } from "../../utils/textFormattingMerge.js";
18
19
  import { emuToPixels, emuToStrokePixels } from "../../utils/units.js";
20
+ import { withAlternateContent } from "../alternateContentAttrs.js";
19
21
  import { expectInlineWrapperMarkAttrs, expectTrackedChangeMarkAttrs } from "../attrs/index.js";
20
22
  import { authoredTransformAttrs } from "../authoredTransformAttrs.js";
21
23
  import { setAutospacingBaseValue } from "../autospacingBase.js";
24
+ import { withEnclosingRevision } from "../contentControlRevisions.js";
22
25
  import { planEmptyRanges } from "../emptyRangeAnchor.js";
23
26
  import { INLINE_WRAPPER_MARK_NAME } from "../extensions/marks/InlineWrapperExtension.js";
24
27
  import { textFormattingToMarks } from "../extensions/marks/markUtils.js";
@@ -34,6 +37,7 @@ import { directionFromBidi } from "../paragraphDirection.js";
34
37
  import { styleResolvedParagraphFormatting } from "../paragraphFormattingProvenance.js";
35
38
  import { lineSpacingProvenanceFromSpacing } from "../paragraphSpacing.js";
36
39
  import { RUN_IDENTITY_MARK_NAME, hasRunIdentityPayload, runIdentityAttrs } from "../runIdentity.js";
40
+ import { continueRunIdentitiesAcrossRevisions } from "../runIdentityAcrossRevisions.js";
37
41
  import { getParagraphMarkSuppressionOverrides, hasDirectRunFormatting, resolveParagraphBodyRunFormatting, stripParagraphMarkFormattingForBodyRuns, stripParagraphMarkOnlyFormatting, suppressParagraphMarkFormatting } from "../runStyleFormatting.js";
38
42
  import { schema } from "../schema/index.js";
39
43
  import { PRESERVED_XML_LEVELS } from "../schema/nodes.js";
@@ -41,6 +45,7 @@ import { cascadeStyleTextFormatting } from "../styles/styleToggleCascade.js";
41
45
  import { canCarryTrackedRunMark, trackedRunInlineAtomDisposition } from "../trackedRunInlineAtoms.js";
42
46
  import { assertValidProseMirrorDocument } from "../validation.js";
43
47
  import { resolveEffectiveTableCellFormatting } from "./effectiveTableCellFormatting.js";
48
+ import { createMarkInterner } from "./markInterner.js";
44
49
  import { hasSinkChildren } from "./preservedSinkCarriers.js";
45
50
  import { sdtAttrsFromProperties } from "./sdtAttrs.js";
46
51
  import { panic } from "better-result";
@@ -85,7 +90,7 @@ const runIdentityMark = (run, nextRunIdentityId) => {
85
90
  const payload = {
86
91
  preservedAttributes: run.preservedAttributes,
87
92
  preserved: run.formatting?.preserved,
88
- emptyFormatting: run.formatting !== void 0 && Object.keys(run.formatting).length === 0 ? true : void 0
93
+ emptyFormatting: run.formatting !== void 0 && Object.keys(run.formatting).length === 0 && (run.propertyChanges?.length ?? 0) === 0 ? true : void 0
89
94
  };
90
95
  if (!runHasPageBreakContent(run) && !runHasMixedContent(run) && !hasRunIdentityPayload(payload)) return null;
91
96
  return schema.mark(RUN_IDENTITY_MARK_NAME, runIdentityAttrs(nextRunIdentityId(), payload));
@@ -227,7 +232,8 @@ function toProseDoc(document, options) {
227
232
  pageBreakRunSourceDescendants: buildPageBreakRunSourceDescendantIndex(paragraphs),
228
233
  storyRangedCommentIds: rangedCommentIds(paragraphs),
229
234
  openCommentIds: /* @__PURE__ */ new Set(),
230
- warnPageBreakProjection: pageBreakProjectionWarn(options?.warn)
235
+ warnPageBreakProjection: pageBreakProjectionWarn(options?.warn),
236
+ createMark: createMarkInterner(schema)
231
237
  };
232
238
  const convertBodyBlocks = (blocks) => {
233
239
  const out = [];
@@ -259,10 +265,12 @@ function toProseDoc(document, options) {
259
265
  if (nodes.length === 0) nodes.push(schema.node("paragraph", {}, []));
260
266
  const finalSectionStart = document.package.document.sections?.at(-1)?.properties.sectionStart ?? null;
261
267
  const adjustLineHeightInTable = document.package.settings?.adjustLineHeightInTable === true;
268
+ const doNotUseIndentAsNumberingTabStop = document.package.settings?.doNotUseIndentAsNumberingTabStop === true;
262
269
  const pmDoc = stampNumberedRefFieldBaselines(schema.node("doc", {
263
270
  [PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR]: getDocumentParagraphPropertySourceContract(document) ?? null,
264
271
  _finalSectionStart: finalSectionStart,
265
- _adjustLineHeightInTable: adjustLineHeightInTable
272
+ _adjustLineHeightInTable: adjustLineHeightInTable,
273
+ _doNotUseIndentAsNumberingTabStop: doNotUseIndentAsNumberingTabStop
266
274
  }, nodes));
267
275
  assertValidProseMirrorDocument(pmDoc, "Document conversion produced an invalid ProseMirror document");
268
276
  return pmDoc;
@@ -355,7 +363,10 @@ function convertBlockSdt(blockSdt, convertBlocks) {
355
363
  function convertParagraph(paragraph, styleResolver, context, extraRunFormatting, tableParagraphOverlay, textBoxAnchors) {
356
364
  const { nextHyperlinkInstanceIndex, pairedBookmarkIds, pageBreakRunSourceDescendants, storyRangedCommentIds, openCommentIds } = context;
357
365
  let runIdentityId = 0;
358
- const nextRunIdentityId = () => runIdentityId++;
366
+ const runScope = {
367
+ nextRunIdentityId: () => runIdentityId++,
368
+ createMark: context.createMark
369
+ };
359
370
  const { attrs, effectiveFrame } = paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOverlay);
360
371
  reportParagraphPageBreakProjection({
361
372
  paragraph,
@@ -452,7 +463,7 @@ function convertParagraph(paragraph, styleResolver, context, extraRunFormatting,
452
463
  historical: getHistoricalRunFormatting
453
464
  };
454
465
  const emitTrackedChange = (change, markType, moveKind) => {
455
- emitInlineNodes(convertTrackedChange(change, markType, nextHyperlinkInstanceIndex, nextRunIdentityId, trackedRunFormattingResolvers, styleResolver, moveKind, textBoxAnchors, wrapperStack));
466
+ emitInlineNodes(convertTrackedChange(change, markType, nextHyperlinkInstanceIndex, runScope, trackedRunFormattingResolvers, styleResolver, moveKind, textBoxAnchors, wrapperStack));
456
467
  };
457
468
  const stacked = withInlineWrapperStacks(paragraph.content);
458
469
  const emptyRanges = planEmptyRanges(stacked.map((item) => item.content));
@@ -476,7 +487,7 @@ function convertParagraph(paragraph, styleResolver, context, extraRunFormatting,
476
487
  emitInlineNode(schema.node("commentReference", { commentId: content.id }));
477
488
  break;
478
489
  case "run":
479
- emitInlineNodes(convertRun(content, getInheritedRunFormatting(content.formatting), nextRunIdentityId, styleResolver, textBoxAnchors));
490
+ emitInlineNodes(convertRun(content, getInheritedRunFormatting(content.formatting), runScope, styleResolver, textBoxAnchors));
480
491
  break;
481
492
  case "hyperlink": {
482
493
  const linkNodes = convertHyperlink(content, {
@@ -484,7 +495,7 @@ function convertParagraph(paragraph, styleResolver, context, extraRunFormatting,
484
495
  styleResolver,
485
496
  hyperlinkIndex: nextHyperlinkInstanceIndex(),
486
497
  textBoxAnchors,
487
- nextRunIdentityId
498
+ runScope
488
499
  });
489
500
  if (linkNodes.length === 0) {
490
501
  const emptyWrapperStacks = emptyInlineWrapperStacks(content.children);
@@ -511,12 +522,12 @@ function convertParagraph(paragraph, styleResolver, context, extraRunFormatting,
511
522
  getInheritedRunFormatting,
512
523
  styleResolver,
513
524
  nextHyperlinkInstanceIndex,
514
- nextRunIdentityId,
525
+ runScope,
515
526
  textBoxAnchors
516
527
  }));
517
528
  break;
518
529
  case "inlineSdt":
519
- emitInlineNode(convertInlineSdt(content, nextHyperlinkInstanceIndex, nextRunIdentityId, getInheritedRunFormatting, trackedRunFormattingResolvers, styleResolver, textBoxAnchors, stack));
530
+ emitInlineNode(convertInlineSdt(content, nextHyperlinkInstanceIndex, runScope, getInheritedRunFormatting, trackedRunFormattingResolvers, styleResolver, textBoxAnchors, stack));
520
531
  break;
521
532
  case "insertion":
522
533
  case "moveTo":
@@ -570,7 +581,7 @@ function convertParagraph(paragraph, styleResolver, context, extraRunFormatting,
570
581
  if (emptyHyperlinks) attrs._emptyHyperlinks = emptyHyperlinks;
571
582
  return createProseParagraphWithPropertySource(schema.nodes["paragraph"], paragraph, {
572
583
  attrs,
573
- content: inlineNodes
584
+ content: continueRunIdentitiesAcrossRevisions(inlineNodes)
574
585
  });
575
586
  }
576
587
  /**
@@ -602,16 +613,20 @@ function anchorPointComment(nodes, commentId) {
602
613
  * One node of a revision's content with the revision recorded on it.
603
614
  *
604
615
  * An inline content control is an `inline*` node rather than an atom, so it is
605
- * not a run carrier: the revision goes on the leaves it holds. That is what
606
- * makes `w:ins > w:sdt` and `w:sdt > w:ins` the same marks on the same leaves,
607
- * and it is what lets the save leg hoist a revision covering all of them back
608
- * around the control instead of losing it.
616
+ * not a run carrier: the revision goes on the leaves it holds, and the control
617
+ * records that the revision encloses it. The leaves alone would read the same
618
+ * for `w:ins > w:sdt` and `w:sdt > w:ins`; the record is what lets the save leg
619
+ * write the revision back around the control, and resolving it remove the
620
+ * control, only for the first.
609
621
  */
610
622
  const withTrackedRunMark = (node, mark, ancestor) => {
611
623
  if (node.type.name === "sdt") {
612
624
  const marked = [];
613
625
  for (let index = 0; index < node.childCount; index += 1) marked.push(withTrackedRunMark(node.child(index), mark, ancestor));
614
- return recreateProseNodeWithParagraphPropertySource(node, { content: marked });
626
+ return recreateProseNodeWithParagraphPropertySource(node, {
627
+ attrs: withEnclosingRevision(node, ancestor.revisionId) ?? node.attrs,
628
+ content: marked
629
+ });
615
630
  }
616
631
  const nestedMark = node.marks.find(({ type }) => type.name === "insertion" || type.name === "deletion");
617
632
  if (nestedMark) {
@@ -630,13 +645,13 @@ const withTrackedRunMark = (node, mark, ancestor) => {
630
645
  * Convert tracked change (insertion or deletion) content to PM nodes with
631
646
  * an insertion/deletion mark applied.
632
647
  */
633
- function convertTrackedChange(change, markType, nextHyperlinkInstanceIndex, nextRunIdentityId, runFormattingResolvers, styleResolver, moveKind = null, textBoxAnchors, wrappedBy = []) {
648
+ function convertTrackedChange(change, markType, nextHyperlinkInstanceIndex, runScope, runFormattingResolvers, styleResolver, moveKind = null, textBoxAnchors, wrappedBy = []) {
634
649
  const nodes = [];
635
650
  const getTrackedRunFormatting = markType === "deletion" ? runFormattingResolvers.historical : runFormattingResolvers.current;
636
651
  for (const { content: item, stack } of withInlineWrapperStacks(change.content)) {
637
652
  if (!isTrackedChangeWrapperChild(item)) continue;
638
653
  const itemNodes = [];
639
- if (item.type === "run") itemNodes.push(...convertRun(item, getTrackedRunFormatting(item.formatting), nextRunIdentityId, styleResolver, textBoxAnchors));
654
+ if (item.type === "run") itemNodes.push(...convertRun(item, getTrackedRunFormatting(item.formatting), runScope, styleResolver, textBoxAnchors));
640
655
  else if (item.type === "hyperlink") {
641
656
  const currentHyperlinkIndex = nextHyperlinkInstanceIndex();
642
657
  itemNodes.push(...convertHyperlink(item, {
@@ -644,14 +659,14 @@ function convertTrackedChange(change, markType, nextHyperlinkInstanceIndex, next
644
659
  styleResolver,
645
660
  hyperlinkIndex: currentHyperlinkIndex,
646
661
  textBoxAnchors,
647
- nextRunIdentityId
662
+ runScope
648
663
  }));
649
664
  } else if (item.type === "simpleField" || item.type === "complexField") {
650
665
  const fieldNode = convertField(item, {
651
666
  getInheritedRunFormatting: getTrackedRunFormatting,
652
667
  styleResolver,
653
668
  nextHyperlinkInstanceIndex,
654
- nextRunIdentityId,
669
+ runScope,
655
670
  textBoxAnchors
656
671
  });
657
672
  if (fieldNode) itemNodes.push(fieldNode);
@@ -661,9 +676,9 @@ function convertTrackedChange(change, markType, nextHyperlinkInstanceIndex, next
661
676
  } else if (item.type === "insertion" || item.type === "deletion" || item.type === "moveFrom" || item.type === "moveTo") {
662
677
  const nestedMarkType = item.type === "insertion" || item.type === "moveTo" ? "insertion" : "deletion";
663
678
  const nestedMoveKind = item.type === "moveFrom" || item.type === "moveTo" ? item.type : null;
664
- itemNodes.push(...convertTrackedChange(item, nestedMarkType, nextHyperlinkInstanceIndex, nextRunIdentityId, runFormattingResolvers, styleResolver, nestedMoveKind, textBoxAnchors, [...wrappedBy, ...stack]));
679
+ itemNodes.push(...convertTrackedChange(item, nestedMarkType, nextHyperlinkInstanceIndex, runScope, runFormattingResolvers, styleResolver, nestedMoveKind, textBoxAnchors, [...wrappedBy, ...stack]));
665
680
  } else if (item.type === "inlineSdt") {
666
- const sdtNode = convertInlineSdt(item, nextHyperlinkInstanceIndex, nextRunIdentityId, getTrackedRunFormatting, runFormattingResolvers, styleResolver, textBoxAnchors, [...wrappedBy, ...stack]);
681
+ const sdtNode = convertInlineSdt(item, nextHyperlinkInstanceIndex, runScope, getTrackedRunFormatting, runFormattingResolvers, styleResolver, textBoxAnchors, [...wrappedBy, ...stack]);
667
682
  if (sdtNode) itemNodes.push(sdtNode);
668
683
  } else if (item.type === "bookmarkStart") itemNodes.push(schema.node("bookmarkBoundary", {
669
684
  type: "start",
@@ -1080,8 +1095,7 @@ function convertTable(table, styleResolver, context) {
1080
1095
  const tableStyleId = table.formatting?.styleId;
1081
1096
  const look = resolveTableLook(table.formatting?.look);
1082
1097
  const tableStyle = tableStyleId ? styleResolver?.getStyle(tableStyleId) : void 0;
1083
- const defaultTableStyle = styleResolver?.getDefaultTableStyle();
1084
- const fallbackTableStyle = tableStyleId ? void 0 : defaultTableStyle;
1098
+ const fallbackTableStyle = tableStyle ? void 0 : styleResolver?.getDefaultTableStyle();
1085
1099
  const conditionalTableStyleId = tableStyle?.styleId ?? fallbackTableStyle?.styleId;
1086
1100
  const resolvedTableBorders = table.formatting?.borders ?? tableStyle?.tblPr?.borders ?? fallbackTableStyle?.tblPr?.borders;
1087
1101
  const fallbackTableIndent = fallbackTableStyle?.tblPr?.indent;
@@ -1466,7 +1480,8 @@ function standaloneTableCellToProseMirror(cell, nodeType) {
1466
1480
  pageBreakRunSourceDescendants,
1467
1481
  storyRangedCommentIds: rangedCommentIds(cell.content),
1468
1482
  openCommentIds: /* @__PURE__ */ new Set(),
1469
- warnPageBreakProjection: noPageBreakProjectionWarning
1483
+ warnPageBreakProjection: noPageBreakProjectionWarning,
1484
+ createMark: createMarkInterner(schema)
1470
1485
  },
1471
1486
  isHeader: nodeType === "tableHeader",
1472
1487
  gridWidthPercent: void 0,
@@ -1479,7 +1494,7 @@ function standaloneTableCellToProseMirror(cell, nodeType) {
1479
1494
  defaultCellMargins: void 0
1480
1495
  });
1481
1496
  }
1482
- function convertField(field, { getInheritedRunFormatting, styleResolver, nextHyperlinkInstanceIndex, nextRunIdentityId, textBoxAnchors }) {
1497
+ function convertField(field, { getInheritedRunFormatting, styleResolver, nextHyperlinkInstanceIndex, runScope, textBoxAnchors }) {
1483
1498
  let displayText = "";
1484
1499
  let fieldFormatting;
1485
1500
  let fieldPropertyChanges;
@@ -1490,7 +1505,7 @@ function convertField(field, { getInheritedRunFormatting, styleResolver, nextHyp
1490
1505
  fieldFormatting ??= run.formatting;
1491
1506
  fieldPropertyChanges ??= run.propertyChanges;
1492
1507
  if (!hasStructuredSourceContent) return;
1493
- into.push(...convertRun(run, getInheritedRunFormatting(run.formatting, field.fieldType), nextRunIdentityId, styleResolver, textBoxAnchors));
1508
+ into.push(...convertRun(run, getInheritedRunFormatting(run.formatting, field.fieldType), runScope, styleResolver, textBoxAnchors));
1494
1509
  };
1495
1510
  if (field.type === "simpleField") for (const { content, stack } of withInlineWrapperStacks(field.content)) {
1496
1511
  const itemNodes = [];
@@ -1512,7 +1527,7 @@ function convertField(field, { getInheritedRunFormatting, styleResolver, nextHyp
1512
1527
  styleResolver,
1513
1528
  hyperlinkIndex: nextHyperlinkInstanceIndex(),
1514
1529
  textBoxAnchors,
1515
- nextRunIdentityId
1530
+ runScope
1516
1531
  }));
1517
1532
  break;
1518
1533
  default: break;
@@ -1522,7 +1537,12 @@ function convertField(field, { getInheritedRunFormatting, styleResolver, nextHyp
1522
1537
  else for (const run of field.fieldResult) appendRun(run, inlineNodes);
1523
1538
  if (!fieldFormatting && field.type === "complexField" && field.fieldResult.length === 0) fieldFormatting = field.formatting;
1524
1539
  const inheritedFormatting = getInheritedRunFormatting(fieldFormatting, field.fieldType);
1525
- const { marks } = buildRunMarks(fieldFormatting, inheritedFormatting, styleResolver);
1540
+ const { marks } = buildRunMarks({
1541
+ runFormatting: fieldFormatting,
1542
+ inherited: inheritedFormatting,
1543
+ styleResolver,
1544
+ createMark: runScope.createMark
1545
+ });
1526
1546
  const hasConvertedHyperlinkContent = inlineNodes.some((node) => node.marks.some((mark) => mark.type.name === "hyperlink"));
1527
1547
  const hasConvertedPageBreakContent = inlineNodes.some((node) => node.type.name === "pageBreakRun");
1528
1548
  const hasConvertedPreservedContent = inlineNodes.some((node) => node.type.name === "preservedXml");
@@ -1535,7 +1555,8 @@ function convertField(field, { getInheritedRunFormatting, styleResolver, nextHyp
1535
1555
  displayText,
1536
1556
  fieldKind: field.type === "simpleField" ? "simple" : "complex",
1537
1557
  fldLock: field.fldLock ?? null,
1538
- dirty: field.dirty ?? null
1558
+ dirty: field.dirty ?? null,
1559
+ fieldResultIsFallback: field.type === "complexField" ? field.fieldResultIsFallback ?? null : null
1539
1560
  }, createStructuredField ? inlineNodes : void 0, marks);
1540
1561
  }
1541
1562
  /**
@@ -1602,7 +1623,7 @@ function convertMathEquation(math) {
1602
1623
  * its own leaves, so nothing outside can mark them afterwards: the caller's
1603
1624
  * stack has to reach them here, under the wrappers written inside the control.
1604
1625
  */
1605
- function convertInlineSdt(sdt, nextHyperlinkInstanceIndex, nextRunIdentityId, getInheritedRunFormatting, trackedRunFormattingResolvers, styleResolver, textBoxAnchors, wrappedBy = []) {
1626
+ function convertInlineSdt(sdt, nextHyperlinkInstanceIndex, runScope, getInheritedRunFormatting, trackedRunFormattingResolvers, styleResolver, textBoxAnchors, wrappedBy = []) {
1606
1627
  const props = sdt.properties;
1607
1628
  const inlineNodes = [];
1608
1629
  const stacked = withInlineWrapperStacks(sdt.content, wrappedBy);
@@ -1618,7 +1639,7 @@ function convertInlineSdt(sdt, nextHyperlinkInstanceIndex, nextRunIdentityId, ge
1618
1639
  if (emptyRanges.closedAt.has(index)) continue;
1619
1640
  switch (content.type) {
1620
1641
  case "run":
1621
- itemNodes.push(...convertRun(content, getInheritedRunFormatting(content.formatting), nextRunIdentityId, styleResolver, textBoxAnchors));
1642
+ itemNodes.push(...convertRun(content, getInheritedRunFormatting(content.formatting), runScope, styleResolver, textBoxAnchors));
1622
1643
  break;
1623
1644
  case "hyperlink": {
1624
1645
  const currentHyperlinkIndex = nextHyperlinkInstanceIndex();
@@ -1627,7 +1648,7 @@ function convertInlineSdt(sdt, nextHyperlinkInstanceIndex, nextRunIdentityId, ge
1627
1648
  styleResolver,
1628
1649
  hyperlinkIndex: currentHyperlinkIndex,
1629
1650
  textBoxAnchors,
1630
- nextRunIdentityId
1651
+ runScope
1631
1652
  }));
1632
1653
  break;
1633
1654
  }
@@ -1637,14 +1658,14 @@ function convertInlineSdt(sdt, nextHyperlinkInstanceIndex, nextRunIdentityId, ge
1637
1658
  getInheritedRunFormatting,
1638
1659
  styleResolver,
1639
1660
  nextHyperlinkInstanceIndex,
1640
- nextRunIdentityId,
1661
+ runScope,
1641
1662
  textBoxAnchors
1642
1663
  });
1643
1664
  if (fieldNode) itemNodes.push(fieldNode);
1644
1665
  break;
1645
1666
  }
1646
1667
  case "inlineSdt": {
1647
- const nestedSdt = convertInlineSdt(content, nextHyperlinkInstanceIndex, nextRunIdentityId, getInheritedRunFormatting, trackedRunFormattingResolvers, styleResolver, textBoxAnchors, stack);
1668
+ const nestedSdt = convertInlineSdt(content, nextHyperlinkInstanceIndex, runScope, getInheritedRunFormatting, trackedRunFormattingResolvers, styleResolver, textBoxAnchors, stack);
1648
1669
  if (nestedSdt) itemNodes.push(nestedSdt);
1649
1670
  break;
1650
1671
  }
@@ -1652,7 +1673,7 @@ function convertInlineSdt(sdt, nextHyperlinkInstanceIndex, nextRunIdentityId, ge
1652
1673
  case "deletion":
1653
1674
  case "moveTo":
1654
1675
  case "moveFrom":
1655
- itemNodes.push(...convertTrackedChange(content, content.type === "insertion" || content.type === "moveTo" ? "insertion" : "deletion", nextHyperlinkInstanceIndex, nextRunIdentityId, trackedRunFormattingResolvers, styleResolver, content.type === "moveTo" || content.type === "moveFrom" ? content.type : null, textBoxAnchors));
1676
+ itemNodes.push(...convertTrackedChange(content, content.type === "insertion" || content.type === "moveTo" ? "insertion" : "deletion", nextHyperlinkInstanceIndex, runScope, trackedRunFormattingResolvers, styleResolver, content.type === "moveTo" || content.type === "moveFrom" ? content.type : null, textBoxAnchors));
1656
1677
  break;
1657
1678
  case "mathEquation": {
1658
1679
  const mathNode = convertMathEquation(content);
@@ -1697,11 +1718,16 @@ function convertInlineSdt(sdt, nextHyperlinkInstanceIndex, nextRunIdentityId, ge
1697
1718
  * @param run - The run to convert
1698
1719
  * @param resolvedStyleFormatting - Paragraph formatting and its explicit style-toggle state
1699
1720
  */
1700
- function convertRun(run, resolvedStyleFormatting, nextRunIdentityId, styleResolver, textBoxAnchors) {
1721
+ function convertRun(run, resolvedStyleFormatting, runScope, styleResolver, textBoxAnchors) {
1701
1722
  const nodes = [];
1702
- const { marks, mergedFormatting } = buildRunMarks(run.formatting, resolvedStyleFormatting, styleResolver);
1723
+ const { marks, mergedFormatting } = buildRunMarks({
1724
+ runFormatting: run.formatting,
1725
+ inherited: resolvedStyleFormatting,
1726
+ styleResolver,
1727
+ createMark: runScope.createMark
1728
+ });
1703
1729
  if (run.propertyChanges && run.propertyChanges.length > 0) marks.push(schema.mark("runPropertyChange", { changes: [...run.propertyChanges] }));
1704
- const identity = runIdentityMark(run, nextRunIdentityId);
1730
+ const identity = runIdentityMark(run, runScope.nextRunIdentityId);
1705
1731
  if (identity) marks.push(identity);
1706
1732
  for (const content of run.content) {
1707
1733
  const contentNodes = convertRunContent(content, marks, mergedFormatting, textBoxAnchors, run.formatting);
@@ -2015,12 +2041,13 @@ const canReconstructAuthoredRunFormatting = ({ directFormatting, effectiveFormat
2015
2041
  }
2016
2042
  return true;
2017
2043
  };
2018
- function buildRunMarks(runFormatting, inherited, styleResolver) {
2044
+ function buildRunMarks({ runFormatting, inherited, styleResolver, createMark }) {
2019
2045
  if (runFormatting === void 0 && inherited.implicitCharacterStyleApplied === true && inherited.paragraphMarkOverrides === void 0) return {
2020
2046
  marks: textFormattingToMarks(inherited.formatting, schema, {
2021
2047
  overrideFormatting: void 0,
2022
2048
  directFormatting: void 0,
2023
- authoredCarrier: "reconstruct"
2049
+ authoredCarrier: "reconstruct",
2050
+ createMark
2024
2051
  }),
2025
2052
  mergedFormatting: inherited.formatting
2026
2053
  };
@@ -2064,9 +2091,10 @@ function buildRunMarks(runFormatting, inherited, styleResolver) {
2064
2091
  const marks = textFormattingToMarks(mergedFormatting, schema, {
2065
2092
  overrideFormatting,
2066
2093
  directFormatting: runFormatting,
2067
- authoredCarrier
2094
+ authoredCarrier,
2095
+ createMark
2068
2096
  });
2069
- if (styleId) marks.push(schema.mark("characterStyle", { styleId }));
2097
+ if (styleId) marks.push(createMark("characterStyle", { styleId }));
2070
2098
  return {
2071
2099
  marks,
2072
2100
  mergedFormatting
@@ -2144,7 +2172,7 @@ function convertRunContent(content, marks, formatting, textBoxAnchors, authoredF
2144
2172
  const anchorId = textBoxAnchors?.get(shp);
2145
2173
  return anchorId ? [schema.node("textBoxAnchor", { anchorId }).mark(marks)] : [];
2146
2174
  }
2147
- return [withRunBoundaryMarks(convertShape(shp, carriedRunFormatting(authoredFormatting)), marks)];
2175
+ return [withRunBoundaryMarks(withAlternateContent(convertShape(shp, carriedRunFormatting(authoredFormatting)), replayableShapeAlternateContent(content)), marks)];
2148
2176
  }
2149
2177
  case "footnoteRef": {
2150
2178
  const footnoteMark = schema.mark("footnoteRef", {
@@ -2195,6 +2223,12 @@ function withRunBoundaryMarks(node, marks) {
2195
2223
  */
2196
2224
  const authoredEmuAttrs = (values) => Object.values(values).some((value) => value !== void 0) ? values : void 0;
2197
2225
  /**
2226
+ * A text box's gradient fill, copied for the reason {@link copiedDrawingAnchor}
2227
+ * is: ProseMirror keeps object-valued attrs by reference. Any other fill is
2228
+ * stated by `fillColor`, or not at all.
2229
+ */
2230
+ const copiedGradientFill = (fill) => fill?.type === "gradient" && fill.gradient !== void 0 ? structuredClone(fill) : void 0;
2231
+ /**
2198
2232
  * A copy of the anchor record: ProseMirror keeps object-valued attrs by
2199
2233
  * reference, so sharing it with the source would let a mutation of either reach
2200
2234
  * the other outside a transaction.
@@ -2334,7 +2368,7 @@ function convertImage({ image, rawXml, rawXmlMode, rawImageFingerprint, runForma
2334
2368
  _docxRunFormatting: runFormatting
2335
2369
  });
2336
2370
  }
2337
- function convertHyperlink(hyperlink, { getInheritedRunFormatting, styleResolver, hyperlinkIndex, textBoxAnchors, nextRunIdentityId }) {
2371
+ function convertHyperlink(hyperlink, { getInheritedRunFormatting, styleResolver, hyperlinkIndex, textBoxAnchors, runScope }) {
2338
2372
  const nodes = [];
2339
2373
  const href = hyperlink.href || (hyperlink.anchor ? `#${hyperlink.anchor}` : "");
2340
2374
  const linkMark = schema.mark("hyperlink", {
@@ -2371,9 +2405,14 @@ function convertHyperlink(hyperlink, { getInheritedRunFormatting, styleResolver,
2371
2405
  break;
2372
2406
  case "run": {
2373
2407
  const inheritedFormatting = getInheritedRunFormatting(child.formatting);
2374
- const { marks: runMarks, mergedFormatting } = buildRunMarks(child.formatting, inheritedFormatting, styleResolver);
2408
+ const { marks: runMarks, mergedFormatting } = buildRunMarks({
2409
+ runFormatting: child.formatting,
2410
+ inherited: inheritedFormatting,
2411
+ styleResolver,
2412
+ createMark: runScope.createMark
2413
+ });
2375
2414
  if (child.propertyChanges && child.propertyChanges.length > 0) runMarks.push(schema.mark("runPropertyChange", { changes: [...child.propertyChanges] }));
2376
- const identity = runIdentityMark(child, nextRunIdentityId);
2415
+ const identity = runIdentityMark(child, runScope.nextRunIdentityId);
2377
2416
  if (identity) runMarks.push(identity);
2378
2417
  const allMarks = [...runMarks, linkMark];
2379
2418
  for (const content of child.content) childNodes.push(...convertRunContent(content, allMarks, mergedFormatting, textBoxAnchors, child.formatting));
@@ -2511,17 +2550,30 @@ function convertParagraphWithTextBoxes(block, styleResolver, { textBoxGroupId, c
2511
2550
  const keepWrapperParagraph = isEmptyAfterExtraction && (preserveEmptyWrapper === true || hasParagraphBoundaryPayload(block, pmParagraph));
2512
2551
  if (!isEmptyAfterExtraction || keepWrapperParagraph) nodes.push(pmParagraph);
2513
2552
  const standalone = isEmptyAfterExtraction && !keepWrapperParagraph;
2514
- for (const [index, { textBox, anchorId, trackedChange, inlineSdts }] of textBoxes.entries()) nodes.push(convertTextBox(textBox, styleResolver, {
2515
- placement: standalone ? "standalone" : "inlineWithPrevious",
2516
- groupId: textBoxGroupId,
2517
- anchorId,
2518
- context,
2519
- trackedChange,
2520
- inlineSdts,
2521
- ...standalone && index === 0 && block.preservedAttributes ? { hostPreservedAttributes: block.preservedAttributes } : {}
2522
- }));
2553
+ for (const [index, { textBox, alternateContentXml, anchorId, trackedChange, inlineSdts }] of textBoxes.entries()) {
2554
+ const textBoxNode = convertTextBox(textBox, styleResolver, {
2555
+ placement: standalone ? "standalone" : "inlineWithPrevious",
2556
+ groupId: textBoxGroupId,
2557
+ anchorId,
2558
+ context,
2559
+ trackedChange,
2560
+ inlineSdts,
2561
+ ...standalone && index === 0 && block.preservedAttributes ? { hostPreservedAttributes: block.preservedAttributes } : {},
2562
+ ...standalone && index === 0 ? { hostParagraph: hostParagraphAttrs(pmParagraph.attrs) } : {}
2563
+ });
2564
+ nodes.push(withAlternateContent(textBoxNode, alternateContentXml));
2565
+ }
2523
2566
  return nodes;
2524
2567
  }
2568
+ /**
2569
+ * The host paragraph's attributes without its identity. The node may be
2570
+ * copied, and a copy must not make a second claim on the same `w:p`; the
2571
+ * attribute remainder travels in the node's own `_preservedAttributes`.
2572
+ */
2573
+ function hostParagraphAttrs(attrs) {
2574
+ const { paraId: _paraId, textId: _textId, idStability: _idStability, _preservedAttributes, ...host } = proseParagraphAttrsWithoutPropertySource(attrs);
2575
+ return host;
2576
+ }
2525
2577
  function hasContentBesidesTextBoxAnchors(paragraph) {
2526
2578
  let hasContent = false;
2527
2579
  paragraph.descendants((node) => {
@@ -2568,6 +2620,7 @@ function extractTextBoxes(paragraph, textBoxGroupId) {
2568
2620
  textBoxAnchors.set(runContent.shape, anchorId);
2569
2621
  textBoxes.push({
2570
2622
  textBox: textBoxFromShape(runContent.shape, runContent.shape.textBody),
2623
+ alternateContentXml: replayableShapeAlternateContent(runContent),
2571
2624
  anchorId,
2572
2625
  trackedChange: context.trackedChange,
2573
2626
  inlineSdts: context.inlineSdts
@@ -2660,6 +2713,7 @@ function textBoxFromShape(shape, textBody) {
2660
2713
  if (textBody.textWrap) textBox.textWrap = textBody.textWrap;
2661
2714
  if (textBody.anchor) textBox.verticalAlign = textBody.anchor;
2662
2715
  if (textBody.wordArt) textBox.wordArt = textBody.wordArt;
2716
+ if (shape.groupChild) textBox.groupChild = shape.groupChild;
2663
2717
  return textBox;
2664
2718
  }
2665
2719
  /**
@@ -2672,6 +2726,7 @@ function convertTextBox(textBox, styleResolver, options) {
2672
2726
  const heightPx = textBoxSize?.height ? emuToPixels(textBoxSize.height) : void 0;
2673
2727
  let fillColor;
2674
2728
  if (textBox.fill?.color?.rgb) fillColor = `#${textBox.fill.color.rgb}`;
2729
+ const gradientFill = copiedGradientFill(textBox.fill);
2675
2730
  let outlineWidth;
2676
2731
  let outlineColor;
2677
2732
  let outlineStyle;
@@ -2762,6 +2817,7 @@ function convertTextBox(textBox, styleResolver, options) {
2762
2817
  alt: textBox.alt,
2763
2818
  title: textBox.title,
2764
2819
  fillColor,
2820
+ gradientFill,
2765
2821
  outlineWidth,
2766
2822
  outlineColor,
2767
2823
  outlineStyle,
@@ -2782,10 +2838,12 @@ function convertTextBox(textBox, styleResolver, options) {
2782
2838
  _docxPlacement: options.placement,
2783
2839
  _docxGroupId: options.groupId,
2784
2840
  _docxAnchorId: options.anchorId,
2841
+ _docxGroupChild: textBox.groupChild,
2785
2842
  _docxTextBodyContentState: textBox.content.length === 0 ? { type: "source-empty" } : { type: "authored" },
2786
2843
  _docxTrackedChange: options.trackedChange,
2787
2844
  _docxInlineSdts: options.inlineSdts.length > 0 ? options.inlineSdts : void 0,
2788
- _preservedAttributes: options.hostPreservedAttributes
2845
+ _preservedAttributes: options.hostPreservedAttributes,
2846
+ _docxHostParagraph: options.hostParagraph
2789
2847
  }, contentNodes);
2790
2848
  }
2791
2849
  /**
@@ -2809,7 +2867,8 @@ function headerFooterToProseDoc(content, options) {
2809
2867
  pageBreakRunSourceDescendants: buildPageBreakRunSourceDescendantIndex(content),
2810
2868
  storyRangedCommentIds: rangedCommentIds(content),
2811
2869
  openCommentIds: /* @__PURE__ */ new Set(),
2812
- warnPageBreakProjection: pageBreakProjectionWarn(options?.warn)
2870
+ warnPageBreakProjection: pageBreakProjectionWarn(options?.warn),
2871
+ createMark: createMarkInterner(schema)
2813
2872
  };
2814
2873
  const convertBlocks = (blocks) => {
2815
2874
  const out = [];
@@ -11,7 +11,8 @@ const DocExtension = createNodeExtension({
11
11
  attrs: {
12
12
  [PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR]: { default: null },
13
13
  _finalSectionStart: { default: null },
14
- _adjustLineHeightInTable: { default: false }
14
+ _adjustLineHeightInTable: { default: false },
15
+ _doNotUseIndentAsNumberingTabStop: { default: false }
15
16
  },
16
17
  content: "(paragraph | horizontalRule | pageBreak | table | textBox | blockSdt | preservedBlock | blockBookmarkBoundary)+"
17
18
  }
@@ -228,6 +228,7 @@ const paragraphNodeSpec = {
228
228
  listMarkerSecondSlotOffsetTwips: { default: null },
229
229
  listLevelNumFmts: { default: null },
230
230
  listLevelStarts: { default: null },
231
+ listLevelTabs: { default: null },
231
232
  listAbstractNumId: { default: null },
232
233
  listStartOverride: { default: null },
233
234
  styleId: { default: null },
@@ -8,13 +8,13 @@ declare const autoBidiDetectionKey: PluginKey<any>;
8
8
  * fire for the initial document, so seeded content needs this pass.
9
9
  *
10
10
  * Like the paraId allocator this is `ignoreTrackedChanges`, so a normalized
11
- * paragraph the user never edits is not in `changedParaIds`. Full save (the
12
- * default; and the only path for Markdown/template/new docs, which have no
13
- * original buffer) serializes the whole PM doc, so the flag is written. The
14
- * selective-save path (dark `selectiveSave` flag) intentionally preserves
15
- * untouched original paragraphs byte-for-byte, so an imported DOCX whose Arabic
16
- * arrived without `w:bidi` and is saved without any edit keeps the original
17
- * bytes; editing the paragraph tracks it and the patch then includes `w:bidi`.
11
+ * paragraph the user never edits is not in `changedParaIds`. An imported DOCX
12
+ * whose Arabic arrived without `w:bidi` gets `{ source: "auto" }` here purely
13
+ * for rendering; because `directionToAuthoredBidi` treats `"auto"` the same
14
+ * as undecided, neither a full-repack save nor the selective-save path (dark
15
+ * `selectiveSave` flag) writes `w:bidi` for it when the paragraph is not
16
+ * otherwise edited. A manual toggle, or a paragraph whose `w:bidi` the source
17
+ * document already carried, is unaffected — it always round-trips.
18
18
  */
19
19
  declare const ensureBaseDirectionInState: (state: EditorState) => EditorState;
20
20
  declare const AutoBidiDetectionExtension: (options?: Partial<{}> | undefined) => Extension;
@@ -80,13 +80,13 @@ const applyBidiUpdates = (state, updates) => {
80
80
  * fire for the initial document, so seeded content needs this pass.
81
81
  *
82
82
  * Like the paraId allocator this is `ignoreTrackedChanges`, so a normalized
83
- * paragraph the user never edits is not in `changedParaIds`. Full save (the
84
- * default; and the only path for Markdown/template/new docs, which have no
85
- * original buffer) serializes the whole PM doc, so the flag is written. The
86
- * selective-save path (dark `selectiveSave` flag) intentionally preserves
87
- * untouched original paragraphs byte-for-byte, so an imported DOCX whose Arabic
88
- * arrived without `w:bidi` and is saved without any edit keeps the original
89
- * bytes; editing the paragraph tracks it and the patch then includes `w:bidi`.
83
+ * paragraph the user never edits is not in `changedParaIds`. An imported DOCX
84
+ * whose Arabic arrived without `w:bidi` gets `{ source: "auto" }` here purely
85
+ * for rendering; because `directionToAuthoredBidi` treats `"auto"` the same
86
+ * as undecided, neither a full-repack save nor the selective-save path (dark
87
+ * `selectiveSave` flag) writes `w:bidi` for it when the paragraph is not
88
+ * otherwise edited. A manual toggle, or a paragraph whose `w:bidi` the source
89
+ * document already carried, is unaffected — it always round-trips.
90
90
  */
91
91
  const ensureBaseDirectionInState = (state) => {
92
92
  if (!autoBidiDetectionKey.get(state)) return state;
@@ -1,6 +1,6 @@
1
1
  import { document_d_exports } from "../../../types/document.js";
2
2
  import { Command, EditorState } from "prosemirror-state";
3
- import { Mark, MarkType, Schema } from "prosemirror-model";
3
+ import { Attrs, Mark, MarkType, Schema } from "prosemirror-model";
4
4
  //#region src/prosemirror/extensions/marks/markUtils.d.ts
5
5
  type MarkAttrs = Record<string, unknown>;
6
6
  declare function marksToTextFormatting(marks: readonly Mark[]): document_d_exports.TextFormatting;
@@ -23,6 +23,8 @@ declare function isMarkActive(state: EditorState, markType: MarkType, attrs?: Re
23
23
  */
24
24
  declare function getMarkAttr(state: EditorState, markType: MarkType, attr: string): unknown;
25
25
  type AuthoredRunFormattingCarrier = "preserve" | "reconstruct";
26
+ /** Builds a mark by type name; a conversion passes one that shares equal marks. */
27
+ type MarkFactory = (type: string, attrs?: Attrs | null) => Mark;
26
28
  /**
27
29
  * Convert TextFormatting to ProseMirror marks
28
30
  */
@@ -32,6 +34,8 @@ type TextFormattingToMarksOptions = {
32
34
  directFormatting?: document_d_exports.TextFormatting | undefined;
33
35
  /** Whether direct authorship is reconstructible from structural marks and the style context. */
34
36
  authoredCarrier?: AuthoredRunFormattingCarrier;
37
+ /** Builds each mark; defaults to `schema.mark`. */
38
+ createMark?: MarkFactory;
35
39
  };
36
40
  declare function textFormattingToMarks(formatting: document_d_exports.TextFormatting | undefined, schema: Schema, options?: TextFormattingToMarksOptions): Mark[];
37
41
  /**
@@ -47,4 +51,4 @@ declare function createSetMarkCommand(markType: MarkType, attrs?: Record<string,
47
51
  */
48
52
  declare function createRemoveMarkCommand(markType: MarkType): Command;
49
53
  //#endregion
50
- export { AuthoredRunFormattingCarrier, clearFontSizeForAllScripts, clearFormatting, createRemoveMarkCommand, createSetMarkCommand, getMarkAttr, isMarkActive, marksToTextFormatting, removeMark, setFontSizeForAllScripts, setMark, textFormattingToMarks, toggleMarkForAllScripts, toggleUnderlineMark };
54
+ export { AuthoredRunFormattingCarrier, MarkFactory, clearFontSizeForAllScripts, clearFormatting, createRemoveMarkCommand, createSetMarkCommand, getMarkAttr, isMarkActive, marksToTextFormatting, removeMark, setFontSizeForAllScripts, setMark, textFormattingToMarks, toggleMarkForAllScripts, toggleUnderlineMark };