@stll/folio-core 0.54.2 → 0.55.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 (199) hide show
  1. package/dist/ai-edits/apply.js +22 -1
  2. package/dist/ai-edits/headless.js +1 -0
  3. package/dist/compare/content-types.d.ts +3 -15
  4. package/dist/controller/canonicalComposition.d.ts +36 -0
  5. package/dist/controller/canonicalComposition.js +168 -0
  6. package/dist/controller/canonicalInput.d.ts +45 -0
  7. package/dist/controller/canonicalInput.js +338 -0
  8. package/dist/controller/canonicalOperations.d.ts +22 -0
  9. package/dist/controller/canonicalOperations.js +85 -0
  10. package/dist/controller/canonicalReview.d.ts +12 -0
  11. package/dist/controller/canonicalReview.js +19 -0
  12. package/dist/controller/canonicalSession.d.ts +149 -0
  13. package/dist/controller/canonicalSession.js +1038 -0
  14. package/dist/controller/canonicalStoryEditor.d.ts +34 -0
  15. package/dist/controller/canonicalStoryEditor.js +82 -0
  16. package/dist/controller/canonicalStructure.d.ts +16 -0
  17. package/dist/controller/canonicalStructure.js +269 -0
  18. package/dist/controller/folioEditor.d.ts +1 -1
  19. package/dist/controller/folioEditor.js +9 -0
  20. package/dist/controller/headerFooterEditorManager.d.ts +4 -0
  21. package/dist/controller/headerFooterEditorManager.js +71 -3
  22. package/dist/controller/hiddenEditorApi.d.ts +35 -0
  23. package/dist/controller/hiddenEditorApi.js +25 -8
  24. package/dist/controller/hiddenEditorManager.d.ts +11 -2
  25. package/dist/controller/hiddenEditorManager.js +456 -30
  26. package/dist/controller/layoutPipeline.d.ts +1 -1
  27. package/dist/controller/layoutPipeline.js +2 -0
  28. package/dist/controller/noteEditorManager.d.ts +4 -0
  29. package/dist/controller/noteEditorManager.js +113 -15
  30. package/dist/docx/attributeRemainder.js +1 -0
  31. package/dist/docx/canonicalSessionInput.d.ts +11 -0
  32. package/dist/docx/canonicalSessionInput.js +27 -0
  33. package/dist/docx/canonicalStoryRepack.d.ts +10 -0
  34. package/dist/docx/canonicalStoryRepack.js +41 -0
  35. package/dist/docx/contentTypeRegistry.d.ts +8 -0
  36. package/dist/docx/contentTypeRegistry.js +64 -0
  37. package/dist/docx/ensureParaIds.d.ts +7 -1
  38. package/dist/docx/ensureParaIds.js +163 -211
  39. package/dist/docx/foldedListNumberFields.d.ts +85 -0
  40. package/dist/docx/foldedListNumberFields.js +267 -0
  41. package/dist/docx/headerFooterVerbatim.d.ts +14 -1
  42. package/dist/docx/headerFooterVerbatim.js +95 -2
  43. package/dist/docx/noteIds.d.ts +5 -0
  44. package/dist/docx/noteIds.js +6 -2
  45. package/dist/docx/noteReferenceMark.d.ts +3 -1
  46. package/dist/docx/noteReferenceMark.js +15 -14
  47. package/dist/docx/numberingParser.d.ts +3 -1
  48. package/dist/docx/numberingParser.js +17 -3
  49. package/dist/docx/packageParts.d.ts +3 -1
  50. package/dist/docx/packageParts.js +65 -16
  51. package/dist/docx/paragraphMarkPropertyPresence.d.ts +9 -0
  52. package/dist/docx/paragraphMarkPropertyPresence.js +21 -0
  53. package/dist/docx/paragraphParser.js +101 -53
  54. package/dist/docx/paragraphPropertySource.d.ts +15 -1
  55. package/dist/docx/paragraphPropertySource.js +76 -22
  56. package/dist/docx/parser.js +2 -1
  57. package/dist/docx/reviewHistoryNamespace.d.ts +4 -0
  58. package/dist/docx/reviewHistoryNamespace.js +4 -0
  59. package/dist/docx/reviewResolutionProvenance.d.ts +25 -0
  60. package/dist/docx/reviewResolutionProvenance.js +153 -0
  61. package/dist/docx/rezip.d.ts +7 -3
  62. package/dist/docx/rezip.js +107 -45
  63. package/dist/docx/runConsolidator.d.ts +2 -58
  64. package/dist/docx/runConsolidator.js +3 -175
  65. package/dist/docx/runParser.d.ts +2 -1
  66. package/dist/docx/runParser.js +156 -116
  67. package/dist/docx/saveDiagnostics.d.ts +11 -0
  68. package/dist/docx/saveDiagnostics.js +0 -0
  69. package/dist/docx/selectiveSave.d.ts +2 -1
  70. package/dist/docx/selectiveSave.js +4 -1
  71. package/dist/docx/selectiveXmlPatch.d.ts +16 -8
  72. package/dist/docx/selectiveXmlPatch.js +74 -2
  73. package/dist/docx/serializer/headerFooterSerializer.d.ts +5 -1
  74. package/dist/docx/serializer/headerFooterSerializer.js +19 -11
  75. package/dist/docx/serializer/noteSerializer.d.ts +2 -2
  76. package/dist/docx/serializer/noteSerializer.js +24 -8
  77. package/dist/docx/serializer/paragraphSerializer.js +41 -4
  78. package/dist/docx/serializer/partNamespaces.js +2 -1
  79. package/dist/docx/serializer/runSerializer.js +3 -1
  80. package/dist/docx/settingsHeaderFooterUpdate.d.ts +5 -0
  81. package/dist/docx/settingsHeaderFooterUpdate.js +90 -0
  82. package/dist/docx/settingsParser.d.ts +1 -2
  83. package/dist/docx/settingsParser.js +5 -6
  84. package/dist/docx/storyBlockReplay.d.ts +11 -0
  85. package/dist/docx/storyBlockReplay.js +367 -0
  86. package/dist/docx/streamingXmlParser.d.ts +22 -1
  87. package/dist/docx/streamingXmlParser.js +49 -3
  88. package/dist/docx/structuralXmlPatch.js +8 -1
  89. package/dist/docx/verbatimCapture.d.ts +3 -1
  90. package/dist/docx/verbatimCapture.js +49 -6
  91. package/dist/i18n/messages/ar.gen.d.ts +5 -0
  92. package/dist/i18n/messages/ar.gen.js +656 -0
  93. package/dist/i18n/messages/cs.gen.d.ts +5 -0
  94. package/dist/i18n/messages/cs.gen.js +656 -0
  95. package/dist/i18n/messages/de.gen.d.ts +5 -0
  96. package/dist/i18n/messages/de.gen.js +656 -0
  97. package/dist/i18n/messages/en.gen.d.ts +5 -0
  98. package/dist/i18n/messages/en.gen.js +656 -0
  99. package/dist/i18n/messages/es.gen.d.ts +5 -0
  100. package/dist/i18n/messages/es.gen.js +656 -0
  101. package/dist/i18n/messages/et.gen.d.ts +5 -0
  102. package/dist/i18n/messages/et.gen.js +656 -0
  103. package/dist/i18n/messages/fr.gen.d.ts +5 -0
  104. package/dist/i18n/messages/fr.gen.js +656 -0
  105. package/dist/i18n/messages/he.gen.d.ts +5 -0
  106. package/dist/i18n/messages/he.gen.js +656 -0
  107. package/dist/i18n/messages/hi.gen.d.ts +5 -0
  108. package/dist/i18n/messages/hi.gen.js +656 -0
  109. package/dist/i18n/messages/hu.gen.d.ts +5 -0
  110. package/dist/i18n/messages/hu.gen.js +656 -0
  111. package/dist/i18n/messages/locales.d.ts +5 -0
  112. package/dist/i18n/messages/locales.js +22 -0
  113. package/dist/i18n/messages/lt.gen.d.ts +5 -0
  114. package/dist/i18n/messages/lt.gen.js +656 -0
  115. package/dist/i18n/messages/lv.gen.d.ts +5 -0
  116. package/dist/i18n/messages/lv.gen.js +656 -0
  117. package/dist/i18n/messages/pl.gen.d.ts +5 -0
  118. package/dist/i18n/messages/pl.gen.js +656 -0
  119. package/dist/i18n/messages/pt-BR.gen.d.ts +5 -0
  120. package/dist/i18n/messages/pt-BR.gen.js +656 -0
  121. package/dist/i18n/messages/sk.gen.d.ts +5 -0
  122. package/dist/i18n/messages/sk.gen.js +656 -0
  123. package/dist/i18n/messages/tr.gen.d.ts +5 -0
  124. package/dist/i18n/messages/tr.gen.js +656 -0
  125. package/dist/i18n/messages/zh-CN.gen.d.ts +5 -0
  126. package/dist/i18n/messages/zh-CN.gen.js +656 -0
  127. package/dist/i18n/messages.d.ts +2 -3
  128. package/dist/i18n/messages.js +1 -19
  129. package/dist/internal/noteMarkerAttrs.d.ts +8 -0
  130. package/dist/internal/noteMarkerAttrs.js +16 -0
  131. package/dist/internal/pageBreakRunSourceDescendantIndex.js +1 -0
  132. package/dist/internal/prosemirrorAttrBoundary.d.ts +21 -0
  133. package/dist/internal/prosemirrorAttrBoundary.js +50 -0
  134. package/dist/layout-bridge/convert/footnoteLayout.d.ts +1 -0
  135. package/dist/layout-bridge/convert/footnoteLayout.js +3 -3
  136. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -0
  137. package/dist/layout-bridge/convert/headerFooterLayout.js +1 -0
  138. package/dist/layout-bridge/convert/noteReferences.d.ts +1 -3
  139. package/dist/layout-bridge/convert/noteReferences.js +1 -6
  140. package/dist/layout-bridge/convert/paragraphRuns.js +2 -4
  141. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +2 -2
  142. package/dist/layout-bridge/convert/toFlowBlocks.js +2 -2
  143. package/dist/managers/DocumentLoaderManager.d.ts +1 -0
  144. package/dist/managers/DocumentLoaderManager.js +8 -1
  145. package/dist/markdown/renderBlock.js +15 -1
  146. package/dist/markdown/renderParagraph.js +9 -13
  147. package/dist/markdown/renderRuns.js +3 -2
  148. package/dist/markdown/renderTable.js +2 -0
  149. package/dist/markdown/types.d.ts +3 -9
  150. package/dist/prosemirror/attrs/index.d.ts +2 -12
  151. package/dist/prosemirror/attrs/index.js +22 -48
  152. package/dist/prosemirror/bookmarkBoundaryAttrs.d.ts +2 -1
  153. package/dist/prosemirror/canonicalCommands.d.ts +97 -0
  154. package/dist/prosemirror/canonicalCommands.js +28 -0
  155. package/dist/prosemirror/commands/pageBreak.js +15 -1
  156. package/dist/prosemirror/commentReferenceAttrs.d.ts +2 -1
  157. package/dist/prosemirror/conversion/fromProseDoc.js +91 -19
  158. package/dist/prosemirror/conversion/listRenderingDefinition.d.ts +6 -0
  159. package/dist/prosemirror/conversion/listRenderingDefinition.js +97 -0
  160. package/dist/prosemirror/conversion/toProseDoc.d.ts +4 -3
  161. package/dist/prosemirror/conversion/toProseDoc.js +51 -11
  162. package/dist/prosemirror/executeEditorCommand.d.ts +11 -0
  163. package/dist/prosemirror/executeEditorCommand.js +26 -0
  164. package/dist/prosemirror/extensions/StarterKit.js +2 -0
  165. package/dist/prosemirror/extensions/core/ParagraphExtension.js +50 -19
  166. package/dist/prosemirror/extensions/features/ListExtension.js +18 -5
  167. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +5 -2
  168. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +13 -1
  169. package/dist/prosemirror/extensions/marks/TextColorExtension.js +3 -2
  170. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +2 -0
  171. package/dist/prosemirror/extensions/marks/markUtils.js +70 -8
  172. package/dist/prosemirror/extensions/nodes/NoteMarkerExtension.d.ts +6 -0
  173. package/dist/prosemirror/extensions/nodes/NoteMarkerExtension.js +36 -0
  174. package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.js +4 -2
  175. package/dist/prosemirror/listMarker.d.ts +1 -0
  176. package/dist/prosemirror/listMarker.js +16 -7
  177. package/dist/prosemirror/listNumbering.js +26 -5
  178. package/dist/prosemirror/listRenderingAttrs.d.ts +1 -0
  179. package/dist/prosemirror/listRenderingAttrs.js +3 -0
  180. package/dist/prosemirror/markupViewNotes.js +3 -2
  181. package/dist/prosemirror/moveRangeBoundaryAttrs.d.ts +2 -1
  182. package/dist/prosemirror/noteReferenceReview.js +5 -3
  183. package/dist/prosemirror/plugins/suggestionMode.js +50 -2
  184. package/dist/prosemirror/rangeAnchorAttrs.d.ts +2 -1
  185. package/dist/prosemirror/runFormattingFromMarks.d.ts +4 -1
  186. package/dist/prosemirror/runFormattingFromMarks.js +15 -1
  187. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +2 -1
  188. package/dist/prosemirror/runFormattingInlineCarriers.js +4 -1
  189. package/dist/prosemirror/schema/marks.d.ts +2 -0
  190. package/dist/prosemirror/schema/nodes.d.ts +10 -2
  191. package/dist/prosemirror/textBoxAnchorAttrs.d.ts +2 -1
  192. package/dist/prosemirror/textInput.js +5 -1
  193. package/dist/prosemirror/trackedRevisionPath.js +2 -1
  194. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +1 -0
  195. package/dist/prosemirror/trackedRunInlineAtoms.js +1 -0
  196. package/dist/prosemirror/validation.js +4 -0
  197. package/dist/types/content.d.ts +2 -2
  198. package/dist/utils/createDocument.js +2 -2
  199. package/package.json +14 -2
@@ -0,0 +1,97 @@
1
+ import { canonicalJson } from "../../utils/canonicalJson.js";
2
+ //#region src/prosemirror/conversion/listRenderingDefinition.ts
3
+ const DEFINITION_FIELDS = Object.values({
4
+ marker: {
5
+ key: "marker",
6
+ source: "paragraph"
7
+ },
8
+ foldedMarkerSuffix: {
9
+ key: "foldedMarkerSuffix",
10
+ source: "paragraph"
11
+ },
12
+ implicitChildLevelAdvances: {
13
+ key: "implicitChildLevelAdvances",
14
+ source: "paragraph"
15
+ },
16
+ markerSecondSlotOffsetTwips: {
17
+ key: "markerSecondSlotOffsetTwips",
18
+ source: "paragraph"
19
+ },
20
+ markerTemplate: {
21
+ key: "markerTemplate",
22
+ source: "definition"
23
+ },
24
+ level: {
25
+ key: "level",
26
+ source: "definition"
27
+ },
28
+ numId: {
29
+ key: "numId",
30
+ source: "definition"
31
+ },
32
+ isBullet: {
33
+ key: "isBullet",
34
+ source: "definition"
35
+ },
36
+ isLegal: {
37
+ key: "isLegal",
38
+ source: "definition"
39
+ },
40
+ numFmt: {
41
+ key: "numFmt",
42
+ source: "definition"
43
+ },
44
+ markerHidden: {
45
+ key: "markerHidden",
46
+ source: "definition"
47
+ },
48
+ markerFormatting: {
49
+ key: "markerFormatting",
50
+ source: "definition"
51
+ },
52
+ markerAlignment: {
53
+ key: "markerAlignment",
54
+ source: "definition"
55
+ },
56
+ markerAllCaps: {
57
+ key: "markerAllCaps",
58
+ source: "definition"
59
+ },
60
+ markerSuffix: {
61
+ key: "markerSuffix",
62
+ source: "definition"
63
+ },
64
+ levelTabs: {
65
+ key: "levelTabs",
66
+ source: "definition"
67
+ },
68
+ levelNumFmts: {
69
+ key: "levelNumFmts",
70
+ source: "definition"
71
+ },
72
+ levelStarts: {
73
+ key: "levelStarts",
74
+ source: "definition"
75
+ },
76
+ abstractNumId: {
77
+ key: "abstractNumId",
78
+ source: "definition"
79
+ },
80
+ startOverride: {
81
+ key: "startOverride",
82
+ source: "definition"
83
+ }
84
+ }).filter((field) => field.source === "definition");
85
+ /** Compare scalar fields directly; only nested records need canonical ordering. */
86
+ const listRenderingDefinitionsMatch = (left, right) => {
87
+ for (const { key } of DEFINITION_FIELDS) {
88
+ const before = left[key];
89
+ const after = right[key];
90
+ if (before === after) continue;
91
+ if (typeof before !== "object" || typeof after !== "object") return false;
92
+ if (canonicalJson(before) !== canonicalJson(after)) return false;
93
+ }
94
+ return true;
95
+ };
96
+ //#endregion
97
+ export { listRenderingDefinitionsMatch };
@@ -8,6 +8,8 @@ import { Node } from "prosemirror-model";
8
8
  type ToProseDocOptions = {
9
9
  /** Style definitions for resolving paragraph styles */
10
10
  styles?: document_d_exports.StyleDefinitions;
11
+ /** Package definitions used to recompute secondary-story list rendering. */
12
+ numbering?: document_d_exports.NumberingDefinitions;
11
13
  /** Theme used when converting themed table/cell values in nested content. */
12
14
  theme?: document_d_exports.Theme | null;
13
15
  /**
@@ -28,9 +30,8 @@ declare function standaloneTableCellToProseMirror(cell: document_d_exports.Table
28
30
  * Convert HeaderFooter content (array of Paragraph/Table blocks) to a ProseMirror document.
29
31
  * Used for editing headers/footers in their own ProseMirror editor and for
30
32
  * the unified header/footer render pipeline (see
31
- * `core/layout-bridge/headerFooterLayout.ts`). `theme` lives in
32
- * `ToProseDocOptions` for future themeColor cell-shading resolution; folio's
33
- * `convertTable` does not yet thread it (orthogonal upstream divergence).
33
+ * `core/layout-bridge/headerFooterLayout.ts`). Package numbering definitions
34
+ * recompute list rendering for direct paragraphs and nested table content.
34
35
  */
35
36
  declare function headerFooterToProseDoc(content: document_d_exports.BlockContent[], options?: ToProseDocOptions): Node;
36
37
  declare function footnoteToProseDoc(content: document_d_exports.BlockContent[], options?: ToProseDocOptions): Node;
@@ -1,6 +1,7 @@
1
1
  import { rangedCommentIds } from "../../docx/commentAnchorIndex.js";
2
2
  import { resolveColorValueToHex } from "../../docx/drawingUtils.js";
3
3
  import { isInlineSdtContent, isTrackedChangeWrapperChild } from "../../docx/inlineWrapperContent.js";
4
+ import { computeListRendering, getCachedNumberingMap } from "../../docx/numberingParser.js";
4
5
  import { PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, createProseParagraphWithPropertySource, getDocumentParagraphPropertySourceContract, proseParagraphAttrsWithoutPropertySource, recreateProseNodeWithParagraphPropertySource, transportTableCellsWithParagraphPropertySources } from "../../docx/paragraphPropertySource.js";
5
6
  import { isBaselineVertAlign } from "../../docx/runParser.js";
6
7
  import { replayableShapeAlternateContent } from "../../docx/shapeAlternateContent.js";
@@ -30,6 +31,7 @@ import { MOVE_RANGE_BOUNDARY_NODE_NAME } from "../extensions/nodes/MoveRangeBoun
30
31
  import { RANGE_ANCHOR_NODE_NAME } from "../extensions/nodes/RangeAnchorExtension.js";
31
32
  import "../extensions/nodes/SdtExtension.js";
32
33
  import { inlineWrapperLayer } from "../inlineWrapperStack.js";
34
+ import { CLEARED_LIST_RENDERING_ATTRS } from "../listMarker.js";
33
35
  import { listRenderingAttrPatch } from "../listRenderingAttrs.js";
34
36
  import { stampNumberedRefFieldBaselines } from "../numberedRefFields.js";
35
37
  import { paragraphNumberingAttr } from "../numberingAttr.js";
@@ -47,11 +49,12 @@ import { tableCellStyleRegions, tableRowBand } from "../styles/tableStyleRegions
47
49
  import { canCarryTrackedRunMark, trackedRunInlineAtomDisposition } from "../trackedRunInlineAtoms.js";
48
50
  import { assertValidProseMirrorDocument } from "../validation.js";
49
51
  import { resolveEffectiveTableCellFormatting } from "./effectiveTableCellFormatting.js";
52
+ import { listRenderingDefinitionsMatch } from "./listRenderingDefinition.js";
50
53
  import { createMarkInterner } from "./markInterner.js";
51
54
  import { hasSinkChildren } from "./preservedSinkCarriers.js";
52
55
  import { sdtAttrsFromProperties } from "./sdtAttrs.js";
53
56
  import { panic } from "better-result";
54
- import { DRAWING_RAW_XML_MODES, PARSE_WARNING_CODES } from "@stll/docx-core/model";
57
+ import { DRAWING_RAW_XML_MODES, PARSE_WARNING_CODES, mergeParagraphNumbering } from "@stll/docx-core/model";
55
58
  //#region src/prosemirror/conversion/toProseDoc.ts
56
59
  const DETACHED_WATERMARK_HOST = Symbol.for("stll.detachedWatermarkHost");
57
60
  const noPageBreakProjectionWarning = () => {};
@@ -227,11 +230,15 @@ function toProseDoc(document, options) {
227
230
  const styleResolver = createStyleEngine(options?.styles ?? document.package.styles);
228
231
  const theme = options?.theme ?? document.package.theme ?? null;
229
232
  const nextTextBoxGroupId = createTextBoxGroupIdFactory();
233
+ const nextHyperlinkInstanceIndex = createHyperlinkInstanceIndexAllocator();
234
+ const pairedBookmarkIds = collectPairedBookmarkIds(paragraphs);
230
235
  const conversionContext = {
236
+ listRenderings: /* @__PURE__ */ new Map(),
237
+ numbering: document.package.numbering === void 0 ? void 0 : getCachedNumberingMap(document.package.numbering),
231
238
  theme,
232
239
  nextTextBoxGroupId,
233
- nextHyperlinkInstanceIndex: createHyperlinkInstanceIndexAllocator(),
234
- pairedBookmarkIds: collectPairedBookmarkIds(paragraphs),
240
+ nextHyperlinkInstanceIndex,
241
+ pairedBookmarkIds,
235
242
  pageBreakRunSourceDescendants: buildPageBreakRunSourceDescendantIndex(paragraphs),
236
243
  storyRangedCommentIds: rangedCommentIds(paragraphs),
237
244
  openCommentIds: /* @__PURE__ */ new Set(),
@@ -328,7 +335,8 @@ function preservedInlineNode(content) {
328
335
  return schema.node("preservedXml", {
329
336
  xml: content.xml,
330
337
  text: content.text,
331
- level: PRESERVED_XML_LEVELS.inline
338
+ level: PRESERVED_XML_LEVELS.inline,
339
+ ...content.foldedListNumber ? { foldedListNumber: content.foldedListNumber } : {}
332
340
  });
333
341
  }
334
342
  /**
@@ -372,6 +380,20 @@ function convertBlockCustomXml(block, convertBlocks) {
372
380
  _originallyEmpty: block.content.length === 0
373
381
  }, children);
374
382
  }
383
+ const resolveListRendering = (numPr, context) => {
384
+ const key = `${numPr.numId}:${numPr.ilvl ?? 0}`;
385
+ const cached = context.listRenderings.get(key);
386
+ if (cached !== void 0) return cached;
387
+ const numbering = context.numbering;
388
+ const rendering = numbering === void 0 ? null : computeListRendering(numPr, numbering);
389
+ const nextLevel = numbering?.getLevel(numPr.numId, (numPr.ilvl ?? 0) + 1);
390
+ const resolved = {
391
+ rendering,
392
+ nextSlotOffset: nextLevel?.pPr?.hangingIndent === true && nextLevel.pPr.indentFirstLine !== void 0 && nextLevel.pPr.indentFirstLine < 0 ? -nextLevel.pPr.indentFirstLine : void 0
393
+ };
394
+ context.listRenderings.set(key, resolved);
395
+ return resolved;
396
+ };
375
397
  /**
376
398
  * Convert a Paragraph to a ProseMirror paragraph node
377
399
  *
@@ -386,6 +408,15 @@ function convertParagraph(paragraph, styleResolver, context, extraRunFormatting,
386
408
  createMark: context.createMark
387
409
  };
388
410
  const { attrs, effectiveFrame } = paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOverlay);
411
+ const numPr = mergeParagraphNumbering(attrs.numPrFromStyle ?? void 0, attrs.numPr ?? void 0);
412
+ if (numPr?.kind === "none") Object.assign(attrs, CLEARED_LIST_RENDERING_ATTRS);
413
+ else if (context.numbering !== void 0 && numPr?.kind === "reference") {
414
+ const { rendering, nextSlotOffset } = resolveListRendering(numPr, context);
415
+ if (rendering !== null) {
416
+ const cached = paragraph.listRendering;
417
+ if (!(cached !== void 0 && listRenderingDefinitionsMatch(cached, rendering) && (cached.markerSecondSlotOffsetTwips === void 0 || cached.markerSecondSlotOffsetTwips === nextSlotOffset))) Object.assign(attrs, CLEARED_LIST_RENDERING_ATTRS, listRenderingAttrPatch(rendering));
418
+ } else Object.assign(attrs, CLEARED_LIST_RENDERING_ATTRS);
419
+ }
389
420
  reportParagraphPageBreakProjection({
390
421
  paragraph,
391
422
  attrs,
@@ -724,6 +755,7 @@ function convertTrackedChange(change, markType, nextHyperlinkInstanceIndex, runS
724
755
  initials: change.info.initials ?? null,
725
756
  moveKind,
726
757
  _docxOuterWrapperCount: wrappedBy.length,
758
+ _docxResolutionJoins: change.resolutionJoins ?? null,
727
759
  ...markType === "deletion" ? { _historicalFormatting: true } : {}
728
760
  });
729
761
  const ancestor = {
@@ -733,7 +765,8 @@ function convertTrackedChange(change, markType, nextHyperlinkInstanceIndex, runS
733
765
  ...change.info.date ? { date: change.info.date } : {},
734
766
  ...change.info.utcDate ? { utcDate: change.info.utcDate.value } : {},
735
767
  ...change.info.initials ? { initials: change.info.initials } : {},
736
- outerWrapperCount: wrappedBy.length
768
+ outerWrapperCount: wrappedBy.length,
769
+ ...change.resolutionJoins === void 0 ? {} : { resolutionJoins: change.resolutionJoins }
737
770
  };
738
771
  return nodes.map((node) => withTrackedRunMark(node, mark, ancestor));
739
772
  }
@@ -753,7 +786,7 @@ function paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOver
753
786
  if (tableOfContentsLevel !== void 0) attrs._tableOfContentsLevel = tableOfContentsLevel;
754
787
  if (formatting?.numPr) attrs.numPr = paragraphNumberingAttr(formatting.numPr);
755
788
  if (formatting?.numPrFromStyle) attrs.numPrFromStyle = paragraphNumberingAttr(formatting.numPrFromStyle);
756
- if (paragraph.listRendering) Object.assign(attrs, listRenderingAttrPatch(paragraph.listRendering));
789
+ if (paragraph.listRendering && formatting?.numPr?.kind !== "none") Object.assign(attrs, listRenderingAttrPatch(paragraph.listRendering));
757
790
  if (formatting) attrs._originalFormatting = formatting;
758
791
  if (paragraph.propertyChanges && paragraph.propertyChanges.length > 0) attrs._propertyChanges = paragraph.propertyChanges.map(({ previousFormatting, ...change }) => {
759
792
  if (previousFormatting === void 0) return change;
@@ -1262,7 +1295,9 @@ function standaloneTableCellToProseMirror(cell, nodeType) {
1262
1295
  cell,
1263
1296
  styleResolver: null,
1264
1297
  context: {
1298
+ listRenderings: /* @__PURE__ */ new Map(),
1265
1299
  theme: null,
1300
+ numbering: void 0,
1266
1301
  nextTextBoxGroupId,
1267
1302
  nextHyperlinkInstanceIndex,
1268
1303
  pairedBookmarkIds: collectPairedBookmarkIds(cell.content),
@@ -1725,6 +1760,7 @@ function reportRunContentBesidePageBreak(run, owner, warn) {
1725
1760
  case "drawing":
1726
1761
  case "endnoteRef":
1727
1762
  case "footnoteRef":
1763
+ case "noteMarker":
1728
1764
  case "preservedXml":
1729
1765
  case "renderedPageBreak":
1730
1766
  case "symbol":
@@ -1938,6 +1974,7 @@ const carriedRunFormatting = (formatting) => formatting && Object.keys(formattin
1938
1974
  */
1939
1975
  function convertRunContent(content, marks, formatting, textBoxAnchors, authoredFormatting) {
1940
1976
  switch (content.type) {
1977
+ case "noteMarker": return [schema.node("noteMarker", { kind: content.kind }).mark(marks)];
1941
1978
  case "text":
1942
1979
  if (content.text) return [schema.text(content.text, marks)];
1943
1980
  return [];
@@ -2648,20 +2685,23 @@ function convertTextBox(textBox, styleResolver, options) {
2648
2685
  * Convert HeaderFooter content (array of Paragraph/Table blocks) to a ProseMirror document.
2649
2686
  * Used for editing headers/footers in their own ProseMirror editor and for
2650
2687
  * the unified header/footer render pipeline (see
2651
- * `core/layout-bridge/headerFooterLayout.ts`). `theme` lives in
2652
- * `ToProseDocOptions` for future themeColor cell-shading resolution; folio's
2653
- * `convertTable` does not yet thread it (orthogonal upstream divergence).
2688
+ * `core/layout-bridge/headerFooterLayout.ts`). Package numbering definitions
2689
+ * recompute list rendering for direct paragraphs and nested table content.
2654
2690
  */
2655
2691
  function headerFooterToProseDoc(content, options) {
2656
2692
  const nodes = [];
2657
2693
  const styleResolver = options?.styles ? createStyleEngine(options.styles) : null;
2658
2694
  const theme = options?.theme ?? null;
2659
2695
  const nextTextBoxGroupId = createTextBoxGroupIdFactory();
2696
+ const nextHyperlinkInstanceIndex = createHyperlinkInstanceIndexAllocator();
2697
+ const pairedBookmarkIds = collectPairedBookmarkIds(content);
2660
2698
  const conversionContext = {
2699
+ listRenderings: /* @__PURE__ */ new Map(),
2661
2700
  theme,
2701
+ numbering: options?.numbering === void 0 ? void 0 : getCachedNumberingMap(options.numbering),
2662
2702
  nextTextBoxGroupId,
2663
- nextHyperlinkInstanceIndex: createHyperlinkInstanceIndexAllocator(),
2664
- pairedBookmarkIds: collectPairedBookmarkIds(content),
2703
+ nextHyperlinkInstanceIndex,
2704
+ pairedBookmarkIds,
2665
2705
  pageBreakRunSourceDescendants: buildPageBreakRunSourceDescendantIndex(content),
2666
2706
  storyRangedCommentIds: rangedCommentIds(content),
2667
2707
  openCommentIds: /* @__PURE__ */ new Set(),
@@ -0,0 +1,11 @@
1
+ import { Command } from "prosemirror-state";
2
+ import { EditorView } from "prosemirror-view";
3
+ //#region src/prosemirror/executeEditorCommand.d.ts
4
+ /** The view's controller owns canonical command interpretation. */
5
+ declare const registerEditorCommandOwner: (view: EditorView, execute: (command: Command) => boolean | undefined) => () => void;
6
+ /** Keep commands on their selected view; a handled refusal must not fall through. */
7
+ declare const executeEditorCommand: (view: EditorView, command: Command) => boolean;
8
+ /** Legacy command chains stop at the first owner decision, including refusal. */
9
+ declare const executeFirstEditorCommand: (view: EditorView, commands: readonly Command[]) => boolean;
10
+ //#endregion
11
+ export { executeEditorCommand, executeFirstEditorCommand, registerEditorCommandOwner };
@@ -0,0 +1,26 @@
1
+ //#region src/prosemirror/executeEditorCommand.ts
2
+ const owners = /* @__PURE__ */ new WeakMap();
3
+ /** The view's controller owns canonical command interpretation. */
4
+ const registerEditorCommandOwner = (view, execute) => {
5
+ owners.set(view, execute);
6
+ return () => {
7
+ owners.delete(view);
8
+ };
9
+ };
10
+ /** Keep commands on their selected view; a handled refusal must not fall through. */
11
+ const executeEditorCommand = (view, command) => {
12
+ const handled = owners.get(view)?.(command);
13
+ if (handled !== void 0) return handled;
14
+ return command(view.state, (transaction) => view.dispatch(transaction), view);
15
+ };
16
+ /** Legacy command chains stop at the first owner decision, including refusal. */
17
+ const executeFirstEditorCommand = (view, commands) => {
18
+ for (const command of commands) {
19
+ const handled = owners.get(view)?.(command);
20
+ if (handled !== void 0) return handled;
21
+ if (command(view.state, (transaction) => view.dispatch(transaction), view)) return true;
22
+ }
23
+ return false;
24
+ };
25
+ //#endregion
26
+ export { executeEditorCommand, executeFirstEditorCommand, registerEditorCommandOwner };
@@ -30,6 +30,7 @@ import { HorizontalRuleExtension } from "./nodes/HorizontalRuleExtension.js";
30
30
  import { ImageExtension } from "./nodes/ImageExtension.js";
31
31
  import { MathExtension } from "./nodes/MathExtension.js";
32
32
  import { MoveRangeBoundaryExtension } from "./nodes/MoveRangeBoundaryExtension.js";
33
+ import { NoteMarkerExtension } from "./nodes/NoteMarkerExtension.js";
33
34
  import { PageBreakExtension } from "./nodes/PageBreakExtension.js";
34
35
  import { PageBreakRunExtension } from "./nodes/PageBreakRunExtension.js";
35
36
  import { PreservedBlockExtension } from "./nodes/PreservedBlockExtension.js";
@@ -76,6 +77,7 @@ function createStarterKit(options = {}) {
76
77
  add("tab", TabExtension());
77
78
  add("symbol", SymbolExtension());
78
79
  add("preservedXml", PreservedXmlExtension());
80
+ add("noteMarker", NoteMarkerExtension());
79
81
  add("image", ImageExtension());
80
82
  add("textBox", TextBoxExtension());
81
83
  add("textBoxAnchor", TextBoxAnchorExtension({ getInternalClipboardToken }));
@@ -8,6 +8,7 @@ import { collectHeadings } from "../../../utils/headingCollector.js";
8
8
  import { tableOfContentsStyleLevel } from "../../../utils/tableOfContentsStyle.js";
9
9
  import { expectParagraphAttrs } from "../../attrs/index.js";
10
10
  import { autospacingMatchesBase } from "../../autospacingBase.js";
11
+ import { withCanonicalParagraphFormatting } from "../../canonicalCommands.js";
11
12
  import { removeSectionBreakAtSelection, setSectionBreakType } from "../../commands/sectionBreak.js";
12
13
  import { CLEARED_LIST_RENDERING_ATTRS } from "../../listMarker.js";
13
14
  import { directParagraphAlignment } from "../../paragraphAlignment.js";
@@ -232,6 +233,7 @@ const paragraphNodeSpec = {
232
233
  listMarkerSuffix: { default: null },
233
234
  listMarkerAllCaps: { default: null },
234
235
  listImplicitChildLevelAdvances: { default: null },
236
+ listFoldedMarkerSuffix: { default: void 0 },
235
237
  listMarkerSecondSlotOffsetTwips: { default: null },
236
238
  listLevelNumFmts: { default: null },
237
239
  listLevelStarts: { default: null },
@@ -631,27 +633,56 @@ const ParagraphExtension = createNodeExtension({
631
633
  onSchemaReady() {
632
634
  const applyStyleFn = makeApplyStyle();
633
635
  return { commands: {
634
- setAlignment: (alignment) => makeSetAlignment(alignment),
635
- alignLeft: () => makeSetAlignment("left"),
636
- alignCenter: () => makeSetAlignment("center"),
637
- alignRight: () => makeSetAlignment("right"),
638
- alignJustify: () => makeSetAlignment("both"),
639
- setLineSpacing: (value, rule) => makeSetLineSpacing(value, rule),
640
- singleSpacing: () => makeSetLineSpacing(240),
641
- oneAndHalfSpacing: () => makeSetLineSpacing(360),
642
- doubleSpacing: () => makeSetLineSpacing(480),
643
- setSpaceBefore: (twips) => setParagraphSpacingAttr("before", twips),
644
- setSpaceAfter: (twips) => setParagraphSpacingAttr("after", twips),
645
- increaseIndent: (amount) => makeIncreaseIndent(amount),
646
- decreaseIndent: (amount) => makeDecreaseIndent(amount),
647
- setIndentLeft: (twips) => setParagraphAttr("indentLeft", twips > 0 ? twips : null),
648
- setIndentRight: (twips) => setParagraphAttr("indentRight", twips > 0 ? twips : null),
649
- setIndentFirstLine: (twips, hanging) => setParagraphAttrsCmd({
636
+ setAlignment: (alignment) => withCanonicalParagraphFormatting(makeSetAlignment(alignment), { alignment }),
637
+ alignLeft: () => withCanonicalParagraphFormatting(makeSetAlignment("left"), { alignment: "left" }),
638
+ alignCenter: () => withCanonicalParagraphFormatting(makeSetAlignment("center"), { alignment: "center" }),
639
+ alignRight: () => withCanonicalParagraphFormatting(makeSetAlignment("right"), { alignment: "right" }),
640
+ alignJustify: () => withCanonicalParagraphFormatting(makeSetAlignment("both"), { alignment: "both" }),
641
+ setLineSpacing: (value, rule) => withCanonicalParagraphFormatting(makeSetLineSpacing(value, rule), {
642
+ lineSpacing: value,
643
+ lineSpacingRule: rule ?? "auto"
644
+ }),
645
+ singleSpacing: () => withCanonicalParagraphFormatting(makeSetLineSpacing(240), {
646
+ lineSpacing: 240,
647
+ lineSpacingRule: "auto"
648
+ }),
649
+ oneAndHalfSpacing: () => withCanonicalParagraphFormatting(makeSetLineSpacing(360), {
650
+ lineSpacing: 360,
651
+ lineSpacingRule: "auto"
652
+ }),
653
+ doubleSpacing: () => withCanonicalParagraphFormatting(makeSetLineSpacing(480), {
654
+ lineSpacing: 480,
655
+ lineSpacingRule: "auto"
656
+ }),
657
+ setSpaceBefore: (twips) => withCanonicalParagraphFormatting(setParagraphSpacingAttr("before", twips), { spaceBefore: twips }),
658
+ setSpaceAfter: (twips) => withCanonicalParagraphFormatting(setParagraphSpacingAttr("after", twips), { spaceAfter: twips }),
659
+ increaseIndent: (amount) => withCanonicalParagraphFormatting(makeIncreaseIndent(amount), (node) => ({ indentLeft: (expectParagraphAttrs(node).indentLeft ?? 0) + (amount ?? 720) })),
660
+ decreaseIndent: (amount) => withCanonicalParagraphFormatting(makeDecreaseIndent(amount), (node) => {
661
+ const attrs = expectParagraphAttrs(node);
662
+ const indentLeft = Math.max(0, (attrs.indentLeft ?? 0) - (amount ?? 720));
663
+ return { indentLeft: indentLeft > 0 || paragraphNumberingReferenceId(attrs.numPr ?? void 0) !== void 0 ? indentLeft : null };
664
+ }),
665
+ setIndentLeft: (twips) => withCanonicalParagraphFormatting(setParagraphAttr("indentLeft", twips > 0 ? twips : null), { indentLeft: twips > 0 ? twips : null }),
666
+ setIndentRight: (twips) => withCanonicalParagraphFormatting(setParagraphAttr("indentRight", twips > 0 ? twips : null), { indentRight: twips > 0 ? twips : null }),
667
+ setIndentFirstLine: (twips, hanging) => withCanonicalParagraphFormatting(setParagraphAttrsCmd({
668
+ indentFirstLine: twips > 0 ? twips : null,
669
+ hangingIndent: hanging ?? false
670
+ }), {
650
671
  indentFirstLine: twips > 0 ? twips : null,
651
672
  hangingIndent: hanging ?? false
652
673
  }),
653
- applyStyle: (styleId, resolvedAttrs) => applyStyleFn(styleId, resolvedAttrs),
654
- clearStyle: () => (state, dispatch) => {
674
+ applyStyle: (styleId, resolvedAttrs) => withCanonicalParagraphFormatting(applyStyleFn(styleId, resolvedAttrs), {
675
+ styleId,
676
+ ...resolvedAttrs ? {
677
+ alignment: null,
678
+ outlineLevel: null,
679
+ spaceBefore: null,
680
+ spaceAfter: null,
681
+ lineSpacing: null,
682
+ lineSpacingRule: null
683
+ } : {}
684
+ }),
685
+ clearStyle: () => withCanonicalParagraphFormatting((state, dispatch) => {
655
686
  const resolver = getDocumentStyleResolver(state);
656
687
  if (!resolver) return applyStyleFn(null)(state, dispatch);
657
688
  const resolved = resolver.resolveParagraphStyle(null);
@@ -662,7 +693,7 @@ const ParagraphExtension = createNodeExtension({
662
693
  ...styleName && { styleName },
663
694
  numbering: getDocumentNumbering(state)
664
695
  })(state, dispatch);
665
- },
696
+ }, { styleId: null }),
666
697
  insertSectionBreak: (breakType) => setSectionBreakType(breakType),
667
698
  removeSectionBreak: () => removeSectionBreakAtSelection,
668
699
  generateTOC: ({ title }) => (state, dispatch) => {
@@ -1,5 +1,6 @@
1
1
  import { paragraphNumberingLevel, paragraphNumberingReferenceId } from "../../../docx/numberingReference.js";
2
2
  import { expectParagraphAttrs } from "../../attrs/index.js";
3
+ import { withCanonicalCommand } from "../../canonicalCommands.js";
3
4
  import { LIST_MARKER_PATTERN, listRequestsForMarker } from "../../listAutoformatMarkers.js";
4
5
  import { CLEARED_LIST_RENDERING_ATTRS } from "../../listMarker.js";
5
6
  import { applyParagraphUpdates, continueNumbering, listItemAttrs, resolveListTarget, restartNumbering, setNumberingValue } from "../../listNumbering.js";
@@ -107,8 +108,14 @@ function toggleList(intent) {
107
108
  return true;
108
109
  };
109
110
  }
110
- const toggleBulletList = (state, dispatch) => toggleList("bullet")(state, dispatch);
111
- const toggleNumberedList = (state, dispatch) => toggleList("numbered")(state, dispatch);
111
+ const toggleBulletList = withCanonicalCommand((state, dispatch) => toggleList("bullet")(state, dispatch), () => [{
112
+ type: "toggleList",
113
+ kind: "bullet"
114
+ }]);
115
+ const toggleNumberedList = withCanonicalCommand((state, dispatch) => toggleList("numbered")(state, dispatch), () => [{
116
+ type: "toggleList",
117
+ kind: "decimal"
118
+ }]);
112
119
  const attrsForListLevel = (state, attrs, level) => {
113
120
  if (!hasActiveListNumbering(attrs)) panic("Cannot change the level of a list without a numbering id");
114
121
  return {
@@ -394,9 +401,15 @@ const ListExtension = createExtension({
394
401
  commands: {
395
402
  toggleBulletList: () => toggleBulletList,
396
403
  toggleNumberedList: () => toggleNumberedList,
397
- increaseListLevel: () => increaseListLevel,
398
- decreaseListLevel: () => decreaseListLevel,
399
- removeList: () => removeList,
404
+ increaseListLevel: () => withCanonicalCommand(increaseListLevel, () => [{
405
+ type: "changeListLevel",
406
+ direction: "increase"
407
+ }]),
408
+ decreaseListLevel: () => withCanonicalCommand(decreaseListLevel, () => [{
409
+ type: "changeListLevel",
410
+ direction: "decrease"
411
+ }]),
412
+ removeList: () => withCanonicalCommand(removeList, () => [{ type: "removeList" }]),
400
413
  restartNumbering: () => restartNumbering,
401
414
  continueNumbering: () => continueNumbering,
402
415
  setNumberingValue: (value) => setNumberingValue(value)
@@ -2,7 +2,7 @@ import { document_d_exports } from "../../../types/document.js";
2
2
  import { Extension } from "../types.js";
3
3
  import { RemovedSectionReference, TrackedSectionEndpointRemoval } from "../../../internal/sectionEndpointResolution.js";
4
4
  import { Node } from "prosemirror-model";
5
- import { EditorState, PluginKey, Transaction } from "prosemirror-state";
5
+ import { EditorState, Plugin, PluginKey, Transaction } from "prosemirror-state";
6
6
  //#region src/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts
7
7
  declare const paragraphChangeTrackerKey: PluginKey<InternalParagraphChangeTrackerState>;
8
8
  type ParagraphChangeTrackerState = {
@@ -30,6 +30,7 @@ type InternalParagraphChangeTrackerState = ParagraphChangeTrackerState & {
30
30
  /** The section records themselves, by identity. */
31
31
  sectionRecords: ReadonlySet<document_d_exports.SectionProperties>;
32
32
  };
33
+ declare function createParagraphChangeTrackerPlugin(): Plugin<InternalParagraphChangeTrackerState>;
33
34
  /**
34
35
  * Get the change tracker state from an EditorState
35
36
  */
@@ -85,6 +86,8 @@ declare function markSectionBreakRemoval(tr: Transaction, sourceDoc: Node): Tran
85
86
  */
86
87
  declare function clearTrackedChanges(state: EditorState): Transaction;
87
88
  declare function ignoreTrackedChanges(tr: Transaction): Transaction;
89
+ /** A committed package-story/property edit requires the full package serializer. */
90
+ declare const markPackageChange: (tr: Transaction) => Transaction;
88
91
  declare function markStructuralChange(tr: Transaction): Transaction;
89
92
  type MarkChangedParagraphRangesOptions = {
90
93
  ranges: readonly {
@@ -98,4 +101,4 @@ type MarkChangedParagraphRangesOptions = {
98
101
  declare function markChangedParagraphRanges(tr: Transaction, batch: MarkChangedParagraphRangesOptions): Transaction;
99
102
  declare const ParagraphChangeTrackerExtension: (options?: Partial<{}> | undefined) => Extension;
100
103
  //#endregion
101
- export { ParagraphChangeTrackerExtension, ParagraphChangeTrackerState, clearTrackedChanges, getChangeTrackerState, getChangedParagraphIds, getTrackedSectionEndpointRemoval, hasStructuralChanges, hasUntrackedChanges, ignoreTrackedChanges, markChangedParagraphRanges, markSectionBreakRemoval, markStructuralChange, markTrackedSectionEndpointRemoval, paragraphChangeTrackerKey, repackWithEditorSectionRemovals };
104
+ export { ParagraphChangeTrackerExtension, ParagraphChangeTrackerState, clearTrackedChanges, createParagraphChangeTrackerPlugin, getChangeTrackerState, getChangedParagraphIds, getTrackedSectionEndpointRemoval, hasStructuralChanges, hasUntrackedChanges, ignoreTrackedChanges, markChangedParagraphRanges, markPackageChange, markSectionBreakRemoval, markStructuralChange, markTrackedSectionEndpointRemoval, paragraphChangeTrackerKey, repackWithEditorSectionRemovals };
@@ -13,6 +13,7 @@ const paragraphChangeTrackerKey = new PluginKey("paragraphChangeTracker");
13
13
  const CLEAR_META = "clear";
14
14
  const IGNORE_META = "ignore";
15
15
  const STRUCTURAL_META = "structural";
16
+ const PACKAGE_CHANGE_META = "package-change";
16
17
  const CHANGED_PARAGRAPH_RANGES_META = "folioChangedParagraphRanges";
17
18
  const SECTION_ENDPOINT_REMOVAL_META = "folioSectionEndpointRemoval";
18
19
  const SECTION_EDIT_META = "folioSectionEdit";
@@ -258,6 +259,11 @@ function createParagraphChangeTrackerPlugin() {
258
259
  sectionRecords: counts.sectionRecords
259
260
  };
260
261
  }
262
+ if (meta === PACKAGE_CHANGE_META && !tr.docChanged) return {
263
+ ...prevState,
264
+ hasUntrackedSourceChanges: true,
265
+ hasUntrackedChanges: true
266
+ };
261
267
  if (!tr.docChanged) return isSectionEditMeta(sectionEditMeta) && sectionEditMeta.expectedEndpointFingerprint === prevState.sectionEndpointFingerprint ? {
262
268
  ...prevState,
263
269
  sectionEndpointRemoval: sectionEditMeta.authorization
@@ -326,6 +332,10 @@ function createParagraphChangeTrackerPlugin() {
326
332
  newState.hasUntrackedChanges = true;
327
333
  }
328
334
  }
335
+ if (meta === PACKAGE_CHANGE_META) {
336
+ newState.hasUntrackedSourceChanges = true;
337
+ newState.hasUntrackedChanges = true;
338
+ }
329
339
  return newState;
330
340
  }
331
341
  },
@@ -503,6 +513,8 @@ function clearTrackedChanges(state) {
503
513
  function ignoreTrackedChanges(tr) {
504
514
  return tr.setMeta(paragraphChangeTrackerKey, IGNORE_META);
505
515
  }
516
+ /** A committed package-story/property edit requires the full package serializer. */
517
+ const markPackageChange = (tr) => tr.setMeta(paragraphChangeTrackerKey, PACKAGE_CHANGE_META);
506
518
  function markStructuralChange(tr) {
507
519
  return tr.setMeta(paragraphChangeTrackerKey, STRUCTURAL_META);
508
520
  }
@@ -523,4 +535,4 @@ const ParagraphChangeTrackerExtension = createExtension({
523
535
  }
524
536
  });
525
537
  //#endregion
526
- export { ParagraphChangeTrackerExtension, clearTrackedChanges, getChangeTrackerState, getChangedParagraphIds, getTrackedSectionEndpointRemoval, hasStructuralChanges, hasUntrackedChanges, ignoreTrackedChanges, markChangedParagraphRanges, markSectionBreakRemoval, markStructuralChange, markTrackedSectionEndpointRemoval, paragraphChangeTrackerKey, repackWithEditorSectionRemovals };
538
+ export { ParagraphChangeTrackerExtension, clearTrackedChanges, createParagraphChangeTrackerPlugin, getChangeTrackerState, getChangedParagraphIds, getTrackedSectionEndpointRemoval, hasStructuralChanges, hasUntrackedChanges, ignoreTrackedChanges, markChangedParagraphRanges, markPackageChange, markSectionBreakRemoval, markStructuralChange, markTrackedSectionEndpointRemoval, paragraphChangeTrackerKey, repackWithEditorSectionRemovals };
@@ -1,5 +1,6 @@
1
1
  import { textToStyle } from "../../../utils/formatToStyle.js";
2
2
  import { expectTextColorMarkAttrs } from "../../attrs/index.js";
3
+ import { canonicalRunFormatting, withCanonicalCommand } from "../../canonicalCommands.js";
3
4
  import { clearRunColor } from "../../clearRunColor.js";
4
5
  import { createMarkExtension } from "../create.js";
5
6
  import { setMark } from "./markUtils.js";
@@ -40,10 +41,10 @@ const TextColorExtension = createMarkExtension({
40
41
  if (!textColorType) panic("Missing mark type: textColor");
41
42
  return { commands: {
42
43
  setTextColor: (attrs) => {
43
- if (!attrs.rgb && !attrs.themeColor) return clearRunColor();
44
+ if (!attrs.rgb && !attrs.themeColor) return withCanonicalCommand(clearRunColor(), (state) => canonicalRunFormatting(state, { color: null }));
44
45
  return setMark(textColorType, attrs);
45
46
  },
46
- clearTextColor: () => clearRunColor()
47
+ clearTextColor: () => withCanonicalCommand(clearRunColor(), (state) => canonicalRunFormatting(state, { color: null }))
47
48
  } };
48
49
  }
49
50
  });
@@ -58,6 +58,7 @@ const InsertionExtension = createMarkExtension({
58
58
  provenance: { default: "user" },
59
59
  suggestionId: { default: null },
60
60
  _docxOuterWrapperCount: { default: null },
61
+ _docxResolutionJoins: { default: null },
61
62
  _docxRevisionAncestors: { default: null }
62
63
  },
63
64
  inclusive: false,
@@ -120,6 +121,7 @@ const DeletionExtension = createMarkExtension({
120
121
  suggestionId: { default: null },
121
122
  _historicalFormatting: { default: null },
122
123
  _docxOuterWrapperCount: { default: null },
124
+ _docxResolutionJoins: { default: null },
123
125
  _docxRevisionAncestors: { default: null }
124
126
  },
125
127
  inclusive: false,