@stll/folio-core 0.54.2 → 0.56.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 (267) hide show
  1. package/dist/ai-edits/apply.js +185 -33
  2. package/dist/ai-edits/headless.js +3 -2
  3. package/dist/ai-edits/types.d.ts +7 -1
  4. package/dist/compare/compare.js +1 -0
  5. package/dist/compare/content-types.d.ts +3 -15
  6. package/dist/compare/reproducible-package.d.ts +0 -17
  7. package/dist/compare/reproducible-package.js +12 -18
  8. package/dist/controller/canonicalClipboard.d.ts +23 -0
  9. package/dist/controller/canonicalClipboard.js +476 -0
  10. package/dist/controller/canonicalClipboardResources.d.ts +21 -0
  11. package/dist/controller/canonicalClipboardResources.js +382 -0
  12. package/dist/controller/canonicalComposition.d.ts +53 -0
  13. package/dist/controller/canonicalComposition.js +296 -0
  14. package/dist/controller/canonicalInlineProjection.d.ts +113 -0
  15. package/dist/controller/canonicalInlineProjection.js +393 -0
  16. package/dist/controller/canonicalInput.d.ts +54 -0
  17. package/dist/controller/canonicalInput.js +377 -0
  18. package/dist/controller/canonicalInputTimer.d.ts +7 -0
  19. package/dist/controller/canonicalInputTimer.js +11 -0
  20. package/dist/controller/canonicalOperations.d.ts +22 -0
  21. package/dist/controller/canonicalOperations.js +85 -0
  22. package/dist/controller/canonicalPublicOperations.d.ts +48 -0
  23. package/dist/controller/canonicalPublicOperations.js +556 -0
  24. package/dist/controller/canonicalReview.d.ts +12 -0
  25. package/dist/controller/canonicalReview.js +19 -0
  26. package/dist/controller/canonicalSession.d.ts +167 -0
  27. package/dist/controller/canonicalSession.js +1186 -0
  28. package/dist/controller/canonicalStoryEditor.d.ts +36 -0
  29. package/dist/controller/canonicalStoryEditor.js +87 -0
  30. package/dist/controller/canonicalStructure.d.ts +16 -0
  31. package/dist/controller/canonicalStructure.js +322 -0
  32. package/dist/controller/canonicalTocSelection.d.ts +11 -0
  33. package/dist/controller/canonicalTocSelection.js +43 -0
  34. package/dist/controller/folioEditor.d.ts +3 -10
  35. package/dist/controller/folioEditor.js +14 -4
  36. package/dist/controller/headerFooterEditorManager.d.ts +5 -0
  37. package/dist/controller/headerFooterEditorManager.js +72 -3
  38. package/dist/controller/hiddenEditorApi.d.ts +45 -0
  39. package/dist/controller/hiddenEditorApi.js +29 -8
  40. package/dist/controller/hiddenEditorManager.d.ts +13 -2
  41. package/dist/controller/hiddenEditorManager.js +639 -31
  42. package/dist/controller/layoutPipeline.d.ts +1 -1
  43. package/dist/controller/layoutPipeline.js +2 -0
  44. package/dist/controller/noteEditorManager.d.ts +5 -0
  45. package/dist/controller/noteEditorManager.js +114 -15
  46. package/dist/document-operations.d.ts +8 -1
  47. package/dist/document-operations.js +6 -4
  48. package/dist/docx/attributeRemainder.js +1 -0
  49. package/dist/docx/blockPlainText.d.ts +1 -1
  50. package/dist/docx/blockPlainText.js +11 -3
  51. package/dist/docx/canonicalResourceSave.d.ts +16 -0
  52. package/dist/docx/canonicalResourceSave.js +27 -0
  53. package/dist/docx/canonicalSave.d.ts +29 -0
  54. package/dist/docx/canonicalSave.js +101 -0
  55. package/dist/docx/canonicalSessionInput.d.ts +11 -0
  56. package/dist/docx/canonicalSessionInput.js +27 -0
  57. package/dist/docx/canonicalStoryRepack.d.ts +10 -0
  58. package/dist/docx/canonicalStoryRepack.js +74 -0
  59. package/dist/docx/contentTypeRegistry.d.ts +8 -0
  60. package/dist/docx/contentTypeRegistry.js +64 -0
  61. package/dist/docx/documentParser.d.ts +1 -13
  62. package/dist/docx/documentParser.js +1 -47
  63. package/dist/docx/ensureParaIds.d.ts +7 -1
  64. package/dist/docx/ensureParaIds.js +173 -215
  65. package/dist/docx/foldedListNumberFields.d.ts +85 -0
  66. package/dist/docx/foldedListNumberFields.js +267 -0
  67. package/dist/docx/footnoteParser.d.ts +1 -11
  68. package/dist/docx/footnoteParser.js +1 -16
  69. package/dist/docx/headerFooterParser.d.ts +1 -9
  70. package/dist/docx/headerFooterParser.js +1 -12
  71. package/dist/docx/headerFooterVerbatim.d.ts +39 -1
  72. package/dist/docx/headerFooterVerbatim.js +173 -2
  73. package/dist/docx/imageParser.d.ts +13 -1
  74. package/dist/docx/imageParser.js +20 -11
  75. package/dist/docx/metadataPrivacy.js +6 -1
  76. package/dist/docx/noteIds.d.ts +5 -0
  77. package/dist/docx/noteIds.js +6 -2
  78. package/dist/docx/noteReferenceMark.d.ts +3 -1
  79. package/dist/docx/noteReferenceMark.js +15 -14
  80. package/dist/docx/numberingParser.d.ts +3 -1
  81. package/dist/docx/numberingParser.js +17 -3
  82. package/dist/docx/packageParts.d.ts +3 -1
  83. package/dist/docx/packageParts.js +74 -19
  84. package/dist/docx/paragraphMarkPropertyPresence.d.ts +9 -0
  85. package/dist/docx/paragraphMarkPropertyPresence.js +21 -0
  86. package/dist/docx/paragraphParser.js +101 -53
  87. package/dist/docx/paragraphPropertySource.d.ts +15 -1
  88. package/dist/docx/paragraphPropertySource.js +77 -22
  89. package/dist/docx/parser.js +3 -1
  90. package/dist/docx/removeHeaderFooterParts.js +17 -6
  91. package/dist/docx/reviewHistoryNamespace.d.ts +4 -0
  92. package/dist/docx/reviewHistoryNamespace.js +4 -0
  93. package/dist/docx/reviewResolutionProvenance.d.ts +25 -0
  94. package/dist/docx/reviewResolutionProvenance.js +153 -0
  95. package/dist/docx/rezip.d.ts +54 -6
  96. package/dist/docx/rezip.js +835 -257
  97. package/dist/docx/runConsolidator.d.ts +2 -58
  98. package/dist/docx/runConsolidator.js +3 -175
  99. package/dist/docx/runParser.d.ts +2 -1
  100. package/dist/docx/runParser.js +156 -116
  101. package/dist/docx/saveDiagnostics.d.ts +22 -0
  102. package/dist/docx/saveDiagnostics.js +0 -0
  103. package/dist/docx/selectiveSave.d.ts +3 -1
  104. package/dist/docx/selectiveSave.js +36 -4
  105. package/dist/docx/selectiveXmlPatch.d.ts +16 -8
  106. package/dist/docx/selectiveXmlPatch.js +81 -7
  107. package/dist/docx/serializer/documentSerializer.d.ts +9 -2
  108. package/dist/docx/serializer/documentSerializer.js +29 -10
  109. package/dist/docx/serializer/headerFooterSerializer.d.ts +5 -1
  110. package/dist/docx/serializer/headerFooterSerializer.js +19 -11
  111. package/dist/docx/serializer/noteSerializer.d.ts +2 -2
  112. package/dist/docx/serializer/noteSerializer.js +24 -8
  113. package/dist/docx/serializer/paragraphSerializer.js +41 -4
  114. package/dist/docx/serializer/partNamespaces.js +2 -1
  115. package/dist/docx/serializer/runSerializer.js +3 -1
  116. package/dist/docx/server/applyDocxXmlPatchProposal.js +14 -9
  117. package/dist/docx/settingsHeaderFooterUpdate.d.ts +5 -0
  118. package/dist/docx/settingsHeaderFooterUpdate.js +90 -0
  119. package/dist/docx/settingsParser.d.ts +1 -2
  120. package/dist/docx/settingsParser.js +5 -6
  121. package/dist/docx/storyBlockReplay.d.ts +31 -0
  122. package/dist/docx/storyBlockReplay.js +471 -0
  123. package/dist/docx/storyPlainText.d.ts +20 -0
  124. package/dist/docx/storyPlainText.js +23 -0
  125. package/dist/docx/streamingXmlParser.d.ts +22 -1
  126. package/dist/docx/streamingXmlParser.js +49 -3
  127. package/dist/docx/structuralXmlPatch.js +18 -23
  128. package/dist/docx/styleParser.d.ts +5 -1
  129. package/dist/docx/styleParser.js +1 -1
  130. package/dist/docx/tableParser.d.ts +1 -8
  131. package/dist/docx/tableParser.js +1 -28
  132. package/dist/docx/textBoxParser.d.ts +1 -5
  133. package/dist/docx/textBoxParser.js +1 -20
  134. package/dist/docx/unzip.js +6 -1
  135. package/dist/docx/verbatimCapture.d.ts +3 -1
  136. package/dist/docx/verbatimCapture.js +49 -6
  137. package/dist/i18n/messages/ar.gen.d.ts +5 -0
  138. package/dist/i18n/messages/ar.gen.js +656 -0
  139. package/dist/i18n/messages/cs.gen.d.ts +5 -0
  140. package/dist/i18n/messages/cs.gen.js +656 -0
  141. package/dist/i18n/messages/de.gen.d.ts +5 -0
  142. package/dist/i18n/messages/de.gen.js +656 -0
  143. package/dist/i18n/messages/en.gen.d.ts +5 -0
  144. package/dist/i18n/messages/en.gen.js +656 -0
  145. package/dist/i18n/messages/es.gen.d.ts +5 -0
  146. package/dist/i18n/messages/es.gen.js +656 -0
  147. package/dist/i18n/messages/et.gen.d.ts +5 -0
  148. package/dist/i18n/messages/et.gen.js +656 -0
  149. package/dist/i18n/messages/fr.gen.d.ts +5 -0
  150. package/dist/i18n/messages/fr.gen.js +656 -0
  151. package/dist/i18n/messages/he.gen.d.ts +5 -0
  152. package/dist/i18n/messages/he.gen.js +656 -0
  153. package/dist/i18n/messages/hi.gen.d.ts +5 -0
  154. package/dist/i18n/messages/hi.gen.js +656 -0
  155. package/dist/i18n/messages/hu.gen.d.ts +5 -0
  156. package/dist/i18n/messages/hu.gen.js +656 -0
  157. package/dist/i18n/messages/locales.d.ts +5 -0
  158. package/dist/i18n/messages/locales.js +22 -0
  159. package/dist/i18n/messages/lt.gen.d.ts +5 -0
  160. package/dist/i18n/messages/lt.gen.js +656 -0
  161. package/dist/i18n/messages/lv.gen.d.ts +5 -0
  162. package/dist/i18n/messages/lv.gen.js +656 -0
  163. package/dist/i18n/messages/pl.gen.d.ts +5 -0
  164. package/dist/i18n/messages/pl.gen.js +656 -0
  165. package/dist/i18n/messages/pt-BR.gen.d.ts +5 -0
  166. package/dist/i18n/messages/pt-BR.gen.js +656 -0
  167. package/dist/i18n/messages/sk.gen.d.ts +5 -0
  168. package/dist/i18n/messages/sk.gen.js +656 -0
  169. package/dist/i18n/messages/tr.gen.d.ts +5 -0
  170. package/dist/i18n/messages/tr.gen.js +656 -0
  171. package/dist/i18n/messages/zh-CN.gen.d.ts +5 -0
  172. package/dist/i18n/messages/zh-CN.gen.js +656 -0
  173. package/dist/i18n/messages.d.ts +2 -3
  174. package/dist/i18n/messages.js +1 -19
  175. package/dist/internal/acceptedBlockProjection.d.ts +12 -0
  176. package/dist/internal/acceptedBlockProjection.js +45 -0
  177. package/dist/internal/noteMarkerAttrs.d.ts +8 -0
  178. package/dist/internal/noteMarkerAttrs.js +16 -0
  179. package/dist/internal/pageBreakRunSourceDescendantIndex.js +1 -0
  180. package/dist/internal/prosemirrorAttrBoundary.d.ts +21 -0
  181. package/dist/internal/prosemirrorAttrBoundary.js +50 -0
  182. package/dist/layout-bridge/convert/footnoteLayout.d.ts +1 -0
  183. package/dist/layout-bridge/convert/footnoteLayout.js +3 -3
  184. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -0
  185. package/dist/layout-bridge/convert/headerFooterLayout.js +1 -0
  186. package/dist/layout-bridge/convert/noteReferences.d.ts +1 -3
  187. package/dist/layout-bridge/convert/noteReferences.js +1 -6
  188. package/dist/layout-bridge/convert/paragraphRuns.js +2 -4
  189. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +2 -2
  190. package/dist/layout-bridge/convert/toFlowBlocks.js +2 -2
  191. package/dist/managers/DocumentLoaderManager.d.ts +1 -0
  192. package/dist/managers/DocumentLoaderManager.js +9 -1
  193. package/dist/markdown/escape.d.ts +3 -1
  194. package/dist/markdown/escape.js +9 -2
  195. package/dist/markdown/renderBlock.js +20 -121
  196. package/dist/markdown/renderParagraph.js +13 -15
  197. package/dist/markdown/renderRuns.d.ts +7 -1
  198. package/dist/markdown/renderRuns.js +35 -15
  199. package/dist/markdown/renderTable.js +2 -0
  200. package/dist/markdown/types.d.ts +3 -9
  201. package/dist/prosemirror/attrs/index.d.ts +2 -12
  202. package/dist/prosemirror/attrs/index.js +22 -48
  203. package/dist/prosemirror/bookmarkBoundaryAttrs.d.ts +2 -1
  204. package/dist/prosemirror/canonicalCommands.d.ts +121 -0
  205. package/dist/prosemirror/canonicalCommands.js +35 -0
  206. package/dist/prosemirror/canonicalSelectionRange.d.ts +9 -0
  207. package/dist/prosemirror/canonicalSelectionRange.js +15 -0
  208. package/dist/prosemirror/clipboardIntent.d.ts +7 -0
  209. package/dist/prosemirror/clipboardIntent.js +9 -0
  210. package/dist/prosemirror/commands/pageBreak.js +15 -1
  211. package/dist/prosemirror/commands/pastePlainText.js +2 -1
  212. package/dist/prosemirror/commentReferenceAttrs.d.ts +2 -1
  213. package/dist/prosemirror/conversion/fromProseDoc.js +91 -19
  214. package/dist/prosemirror/conversion/hyphenTextCarriers.d.ts +8 -0
  215. package/dist/prosemirror/conversion/hyphenTextCarriers.js +8 -0
  216. package/dist/prosemirror/conversion/listRenderingDefinition.d.ts +6 -0
  217. package/dist/prosemirror/conversion/listRenderingDefinition.js +97 -0
  218. package/dist/prosemirror/conversion/toProseDoc.d.ts +11 -4
  219. package/dist/prosemirror/conversion/toProseDoc.js +55 -14
  220. package/dist/prosemirror/executeEditorCommand.d.ts +11 -0
  221. package/dist/prosemirror/executeEditorCommand.js +26 -0
  222. package/dist/prosemirror/extensions/StarterKit.js +2 -0
  223. package/dist/prosemirror/extensions/core/ParagraphExtension.js +88 -48
  224. package/dist/prosemirror/extensions/features/ListExtension.js +18 -5
  225. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +5 -2
  226. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +13 -1
  227. package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +56 -28
  228. package/dist/prosemirror/extensions/marks/TextColorExtension.js +3 -2
  229. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +2 -0
  230. package/dist/prosemirror/extensions/marks/markUtils.js +72 -8
  231. package/dist/prosemirror/extensions/nodes/NoteMarkerExtension.d.ts +6 -0
  232. package/dist/prosemirror/extensions/nodes/NoteMarkerExtension.js +36 -0
  233. package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.js +4 -2
  234. package/dist/prosemirror/insertOperations.js +2 -1
  235. package/dist/prosemirror/listMarker.d.ts +1 -0
  236. package/dist/prosemirror/listMarker.js +16 -7
  237. package/dist/prosemirror/listNumbering.js +26 -5
  238. package/dist/prosemirror/listRenderingAttrs.d.ts +1 -0
  239. package/dist/prosemirror/listRenderingAttrs.js +3 -0
  240. package/dist/prosemirror/markupViewNotes.js +3 -2
  241. package/dist/prosemirror/moveRangeBoundaryAttrs.d.ts +2 -1
  242. package/dist/prosemirror/noteReferenceReview.js +5 -3
  243. package/dist/prosemirror/paragraphPropertyCarry.d.ts +7 -1
  244. package/dist/prosemirror/paragraphPropertyCarry.js +8 -3
  245. package/dist/prosemirror/plugins/suggestionMode.js +57 -7
  246. package/dist/prosemirror/rangeAnchorAttrs.d.ts +2 -1
  247. package/dist/prosemirror/runFormattingFromMarks.d.ts +4 -1
  248. package/dist/prosemirror/runFormattingFromMarks.js +15 -1
  249. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +2 -1
  250. package/dist/prosemirror/runFormattingInlineCarriers.js +4 -1
  251. package/dist/prosemirror/schema/marks.d.ts +2 -0
  252. package/dist/prosemirror/schema/nodes.d.ts +10 -2
  253. package/dist/prosemirror/textBoxAnchorAttrs.d.ts +2 -1
  254. package/dist/prosemirror/textInput.js +5 -1
  255. package/dist/prosemirror/trackedRevisionPath.js +2 -1
  256. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +1 -0
  257. package/dist/prosemirror/trackedRunInlineAtoms.js +1 -0
  258. package/dist/prosemirror/validation.js +4 -0
  259. package/dist/types/canonicalCapabilities.d.ts +215 -0
  260. package/dist/types/canonicalCapabilities.js +212 -0
  261. package/dist/types/canonicalSave.d.ts +11 -0
  262. package/dist/types/canonicalSave.js +0 -0
  263. package/dist/types/content.d.ts +2 -2
  264. package/dist/types/docxSerialization.d.ts +14 -0
  265. package/dist/types/docxSerialization.js +7 -0
  266. package/dist/utils/createDocument.js +2 -2
  267. package/package.json +16 -4
@@ -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 { withCanonicalCommand, withCanonicalParagraphFormatting, withCanonicalStartParagraphFormatting } 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,10 +693,10 @@ 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
- generateTOC: ({ title }) => (state, dispatch) => {
699
+ generateTOC: ({ title }) => withCanonicalCommand((state, dispatch) => {
669
700
  const builtInStyles = getDocumentBuiltInStyles(state);
670
701
  const headings = collectHeadings(state.doc, builtInStyles);
671
702
  if (headings.length === 0) return false;
@@ -742,44 +773,53 @@ const ParagraphExtension = createNodeExtension({
742
773
  tr.insert(insertPos, Fragment.from(tocNodes));
743
774
  dispatch(tr.scrollIntoView());
744
775
  return true;
745
- },
746
- toggleBidi: () => (state, dispatch) => {
747
- const { $from } = state.selection;
748
- const paragraph = $from.parent;
749
- if (paragraph.type.name !== "paragraph") return false;
750
- return setParagraphAttr("direction", directionIsRtl(paragraph.attrs["direction"]) ? {
776
+ }, (state) => [{
777
+ type: "generateTOC",
778
+ at: state.selection.from,
779
+ title
780
+ }]),
781
+ toggleBidi: () => {
782
+ const directionFor = (paragraph) => ({
751
783
  source: "manual",
752
- value: "ltr"
753
- } : {
754
- source: "manual",
755
- value: "rtl"
756
- })(state, dispatch);
784
+ value: directionIsRtl(expectParagraphAttrs(paragraph).direction) ? "ltr" : "rtl"
785
+ });
786
+ return withCanonicalStartParagraphFormatting((state, dispatch) => {
787
+ const paragraph = state.selection.$from.parent;
788
+ if (paragraph.type.name !== "paragraph") return false;
789
+ return setParagraphAttr("direction", directionFor(paragraph))(state, dispatch);
790
+ }, (paragraph) => ({ bidi: directionIsRtl(directionFor(paragraph)) }));
757
791
  },
758
- setRtl: () => setParagraphAttr("direction", {
792
+ setRtl: () => withCanonicalParagraphFormatting(setParagraphAttr("direction", {
759
793
  source: "manual",
760
794
  value: "rtl"
761
- }),
762
- setLtr: () => setParagraphAttr("direction", {
795
+ }), { bidi: true }),
796
+ setLtr: () => withCanonicalParagraphFormatting(setParagraphAttr("direction", {
763
797
  source: "manual",
764
798
  value: "ltr"
765
- }),
766
- setTabs: (tabs) => setParagraphAttr("tabs", tabs.length > 0 ? tabs : null),
767
- addTabStop: (position, alignment = "left", leader = "none") => (state, dispatch) => {
768
- const { $from } = state.selection;
769
- const paragraph = $from.parent;
770
- if (paragraph.type.name !== "paragraph") return false;
771
- return setParagraphAttr("tabs", [...(paragraph.attrs["tabs"] || []).filter((t) => t.position !== position), {
799
+ }), { bidi: false }),
800
+ setTabs: (tabs) => withCanonicalParagraphFormatting(setParagraphAttr("tabs", tabs.length > 0 ? tabs : null), { tabs: tabs.length > 0 ? tabs : null }),
801
+ addTabStop: (position, alignment = "left", leader = "none") => {
802
+ const tabsFor = (paragraph) => [...(expectParagraphAttrs(paragraph).tabs ?? []).filter((tab) => tab.position !== position), {
772
803
  position,
773
804
  alignment,
774
805
  leader
775
- }].toSorted((a, b) => a.position - b.position))(state, dispatch);
806
+ }].toSorted((a, b) => a.position - b.position);
807
+ return withCanonicalStartParagraphFormatting((state, dispatch) => {
808
+ const paragraph = state.selection.$from.parent;
809
+ if (paragraph.type.name !== "paragraph") return false;
810
+ return setParagraphAttr("tabs", tabsFor(paragraph))(state, dispatch);
811
+ }, (paragraph) => ({ tabs: tabsFor(paragraph) }));
776
812
  },
777
- removeTabStop: (position) => (state, dispatch) => {
778
- const { $from } = state.selection;
779
- const paragraph = $from.parent;
780
- if (paragraph.type.name !== "paragraph") return false;
781
- const newTabs = (paragraph.attrs["tabs"] || []).filter((t) => t.position !== position);
782
- return setParagraphAttr("tabs", newTabs.length > 0 ? newTabs : null)(state, dispatch);
813
+ removeTabStop: (position) => {
814
+ const tabsFor = (paragraph) => {
815
+ const tabs = (expectParagraphAttrs(paragraph).tabs ?? []).filter((tab) => tab.position !== position);
816
+ return tabs.length > 0 ? tabs : null;
817
+ };
818
+ return withCanonicalStartParagraphFormatting((state, dispatch) => {
819
+ const paragraph = state.selection.$from.parent;
820
+ if (paragraph.type.name !== "paragraph") return false;
821
+ return setParagraphAttr("tabs", tabsFor(paragraph))(state, dispatch);
822
+ }, (paragraph) => ({ tabs: tabsFor(paragraph) }));
783
823
  }
784
824
  } };
785
825
  }
@@ -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,6 +1,10 @@
1
+ import { BUILT_IN_STYLE_NAME } from "../../../docx/builtInStyles.js";
1
2
  import { anchorTargetAttrs, normalizeUserUrl, sanitizeExternalUrl } from "../../../utils/urlSecurity.js";
2
3
  import { expectHyperlinkMarkAttrs } from "../../attrs/index.js";
4
+ import { withCanonicalCommand } from "../../canonicalCommands.js";
5
+ import { canonicalSelectionRange } from "../../canonicalSelectionRange.js";
3
6
  import { removeHyperlinkInRange } from "../../hyperlinkRemoval.js";
7
+ import { getDocumentBuiltInStyles } from "../../plugins/documentStyleState.js";
4
8
  import { createMarkExtension } from "../create.js";
5
9
  import { isMarkActive } from "./markUtils.js";
6
10
  import { panic } from "better-result";
@@ -121,7 +125,7 @@ const HyperlinkExtension = createMarkExtension({
121
125
  onSchemaReady(ctx) {
122
126
  if (!ctx.schema.marks["hyperlink"]) panic("Missing mark type: hyperlink");
123
127
  const documentHyperlinkType = (state) => state.schema.marks["hyperlink"] ?? panic("Missing mark type: hyperlink");
124
- const setHyperlink = (href, tooltip) => (state, dispatch) => {
128
+ const setHyperlink = (href, tooltip) => withCanonicalCommand((state, dispatch) => {
125
129
  const hlType = documentHyperlinkType(state);
126
130
  const { from, to, empty } = state.selection;
127
131
  if (empty) return false;
@@ -136,34 +140,52 @@ const HyperlinkExtension = createMarkExtension({
136
140
  dispatch(tr.scrollIntoView());
137
141
  }
138
142
  return true;
139
- };
140
- const removeHyperlink = (state, dispatch) => {
143
+ }, (state) => state.selection.empty ? [] : [{
144
+ type: "setHyperlink",
145
+ ...canonicalSelectionRange(state),
146
+ href: normalizeHyperlinkInput(href),
147
+ ...tooltip ? { tooltip } : {}
148
+ }]);
149
+ const removalRange = (state) => {
150
+ const { empty, $from } = state.selection;
151
+ const { from, to } = canonicalSelectionRange(state);
152
+ if (!empty) return {
153
+ from,
154
+ to
155
+ };
141
156
  const hlType = documentHyperlinkType(state);
142
- const { from, to, empty } = state.selection;
143
- if (empty) {
144
- const $pos = state.selection.$from;
145
- if (!$pos.marks().find((m) => m.type === hlType)) return false;
146
- let start = $pos.pos;
147
- let end = $pos.pos;
148
- $pos.parent.forEach((node, offset) => {
149
- if (node.isText) {
150
- const nodeStart = $pos.start() + offset;
151
- const nodeEnd = nodeStart + node.nodeSize;
152
- if (nodeStart <= $pos.pos && $pos.pos <= nodeEnd) {
153
- if (node.marks.some((m) => m.type === hlType)) {
154
- start = Math.min(start, nodeStart);
155
- end = Math.max(end, nodeEnd);
156
- }
157
- }
158
- }
159
- });
160
- if (dispatch) dispatch(removeHyperlinkInRange(state, state.tr, start, end).scrollIntoView());
161
- return true;
162
- }
163
- if (dispatch) dispatch(removeHyperlinkInRange(state, state.tr, from, to).scrollIntoView());
164
- return true;
157
+ if (!$from.marks().some((mark) => mark.type === hlType)) return void 0;
158
+ let start = from;
159
+ let end = to;
160
+ $from.parent.forEach((node, offset) => {
161
+ const nodeStart = $from.start() + offset;
162
+ const nodeEnd = nodeStart + node.nodeSize;
163
+ if (node.isText && nodeStart <= from && from <= nodeEnd && node.marks.some((mark) => mark.type === hlType)) {
164
+ start = Math.min(start, nodeStart);
165
+ end = Math.max(end, nodeEnd);
166
+ }
167
+ });
168
+ return {
169
+ from: start,
170
+ to: end
171
+ };
165
172
  };
166
- const insertHyperlink = (text, href, tooltip) => (state, dispatch) => {
173
+ const removeHyperlink = withCanonicalCommand((state, dispatch) => {
174
+ const range = removalRange(state);
175
+ if (!range) return false;
176
+ if (dispatch) dispatch(removeHyperlinkInRange(state, state.tr, range.from, range.to).scrollIntoView());
177
+ return true;
178
+ }, (state) => {
179
+ const range = removalRange(state);
180
+ if (!range) return [];
181
+ const hyperlinkStyleId = getDocumentBuiltInStyles(state).styleIdForBuiltInName(BUILT_IN_STYLE_NAME.hyperlink);
182
+ return [{
183
+ type: "removeHyperlink",
184
+ ...range,
185
+ ...hyperlinkStyleId === void 0 ? {} : { hyperlinkStyleId }
186
+ }];
187
+ });
188
+ const insertHyperlink = (text, href, tooltip) => withCanonicalCommand((state, dispatch) => {
167
189
  const hlType = documentHyperlinkType(state);
168
190
  if (dispatch) {
169
191
  const mark = hlType.create({
@@ -174,7 +196,13 @@ const HyperlinkExtension = createMarkExtension({
174
196
  dispatch(state.tr.replaceSelectionWith(textNode, false).scrollIntoView());
175
197
  }
176
198
  return true;
177
- };
199
+ }, (state) => [{
200
+ type: "insertHyperlink",
201
+ ...canonicalSelectionRange(state),
202
+ text,
203
+ href: normalizeHyperlinkInput(href),
204
+ ...tooltip ? { tooltip } : {}
205
+ }]);
178
206
  return { commands: {
179
207
  setHyperlink,
180
208
  removeHyperlink: () => removeHyperlink,
@@ -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,