@stll/folio-core 0.35.1 → 0.37.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 (236) hide show
  1. package/README.md +59 -1
  2. package/dist/ai-edits/apply.js +878 -377
  3. package/dist/ai-edits/block-identity.d.ts +4 -1
  4. package/dist/ai-edits/block-identity.js +4 -1
  5. package/dist/ai-edits/blockRange.js +14 -14
  6. package/dist/ai-edits/clean-text.d.ts +40 -1
  7. package/dist/ai-edits/clean-text.js +52 -2
  8. package/dist/ai-edits/headless.d.ts +3 -1
  9. package/dist/ai-edits/headless.js +141 -73
  10. package/dist/ai-edits/index.d.ts +3 -3
  11. package/dist/ai-edits/index.js +2 -2
  12. package/dist/ai-edits/read.js +38 -20
  13. package/dist/ai-edits/snapshot.d.ts +14 -6
  14. package/dist/ai-edits/snapshot.js +105 -20
  15. package/dist/ai-edits/table-cell-mutations.js +1 -1
  16. package/dist/ai-edits/table-row-column-mutations.js +7 -0
  17. package/dist/ai-edits/table-template.d.ts +11 -1
  18. package/dist/ai-edits/table-template.js +49 -17
  19. package/dist/ai-edits/types.d.ts +62 -61
  20. package/dist/ai-edits/word-diff.d.ts +18 -3
  21. package/dist/ai-edits/word-diff.js +556 -67
  22. package/dist/ai-suggestions/conflict.js +1 -4
  23. package/dist/ai-suggestions/text-positions.d.ts +8 -0
  24. package/dist/ai-suggestions/text-positions.js +27 -5
  25. package/dist/compare/__fixtures__/body-sequence.js +3 -4
  26. package/dist/compare/column-alignment.d.ts +13 -13
  27. package/dist/compare/column-alignment.js +78 -39
  28. package/dist/compare/compare.d.ts +4 -3
  29. package/dist/compare/compare.js +48 -21
  30. package/dist/compare/content-alignment.d.ts +95 -0
  31. package/dist/compare/content-alignment.js +1450 -0
  32. package/dist/compare/content-types.d.ts +100 -0
  33. package/dist/compare/content-types.js +0 -0
  34. package/dist/compare/content.d.ts +209 -0
  35. package/dist/compare/content.js +885 -0
  36. package/dist/compare/formatting.d.ts +5 -5
  37. package/dist/compare/formatting.js +6 -4
  38. package/dist/compare/plan.d.ts +6 -1
  39. package/dist/compare/plan.js +171 -566
  40. package/dist/compare/scenario.d.ts +2 -2
  41. package/dist/compare/types.d.ts +3 -3
  42. package/dist/compare/verification.d.ts +8 -9
  43. package/dist/compare/verification.js +72 -50
  44. package/dist/compat/eigenpal.d.ts +5 -3
  45. package/dist/compat/eigenpal.js +3 -2
  46. package/dist/controller/headerFooterEditorManager.js +18 -10
  47. package/dist/controller/hiddenEditorApi.js +1 -1
  48. package/dist/controller/hiddenEditorManager.d.ts +7 -2
  49. package/dist/controller/hiddenEditorManager.js +15 -6
  50. package/dist/controller/layoutPipeline.js +5 -3
  51. package/dist/controller/noteEditorManager.js +12 -7
  52. package/dist/display-list/build/headerFooterPrimitives.js +1 -0
  53. package/dist/display-list/build/storyPrimitives.d.ts +5 -2
  54. package/dist/display-list/build/storyPrimitives.js +60 -3
  55. package/dist/display-list/build/tablePrimitives.js +30 -0
  56. package/dist/display-list/primitives.d.ts +1 -1
  57. package/dist/document-operations.d.ts +8 -4
  58. package/dist/document-operations.js +104 -12
  59. package/dist/docx/blockContentParser.js +6 -27
  60. package/dist/docx/commentParser.js +2 -4
  61. package/dist/docx/commentRangeIntegrity.js +2 -4
  62. package/dist/docx/documentClone.d.ts +2 -0
  63. package/dist/docx/documentClone.js +2 -0
  64. package/dist/docx/ensureParaIds.js +9 -4
  65. package/dist/docx/headerFooterParser.js +2 -4
  66. package/dist/docx/normalizeBaseDirection.js +5 -7
  67. package/dist/docx/numberingParser.d.ts +3 -1
  68. package/dist/docx/numberingParser.js +4 -1
  69. package/dist/docx/paragraphParser.js +34 -35
  70. package/dist/docx/paragraphPropertySource.d.ts +49 -0
  71. package/dist/docx/paragraphPropertySource.js +113 -0
  72. package/dist/docx/paragraphTraversal.js +30 -34
  73. package/dist/docx/rezip.d.ts +0 -8
  74. package/dist/docx/rezip.js +41 -16
  75. package/dist/docx/runConsolidator.js +2 -4
  76. package/dist/docx/runParser.js +6 -17
  77. package/dist/docx/sectionParser.js +1 -15
  78. package/dist/docx/serializer/paragraphSerializer.js +289 -30
  79. package/dist/docx/serializer/runSerializer.js +6 -12
  80. package/dist/docx/serializer/sectionPropertiesSerializer.js +2 -10
  81. package/dist/docx/serializer/tableSerializer.js +4 -23
  82. package/dist/docx/serializer/trackedChangeAttributes.d.ts +11 -0
  83. package/dist/docx/serializer/trackedChangeAttributes.js +31 -0
  84. package/dist/docx/server/build.d.ts +1 -1
  85. package/dist/docx/server/createBilingualDocument.js +8 -10
  86. package/dist/docx/server/evaluateDocxXmlPatchProposal.js +22 -13
  87. package/dist/docx/server/validateDocxConformance.js +17 -13
  88. package/dist/docx/tableParser.js +1 -37
  89. package/dist/docx/trackedChangeInfo.d.ts +11 -0
  90. package/dist/docx/trackedChangeInfo.js +38 -0
  91. package/dist/docx/verbatimCapture.d.ts +20 -9
  92. package/dist/docx/verbatimCapture.js +208 -8
  93. package/dist/docx/xmlParser.d.ts +3 -1
  94. package/dist/docx/xmlParser.js +6 -1
  95. package/dist/docx/xmlSafety.d.ts +1 -1
  96. package/dist/docx/xmlSafety.js +157 -0
  97. package/dist/headless-layout.js +5 -4
  98. package/dist/index.d.ts +5 -3
  99. package/dist/index.js +3 -2
  100. package/dist/internal/headlessRevisionResolution.d.ts +23 -0
  101. package/dist/internal/headlessRevisionResolution.js +155 -0
  102. package/dist/internal/headlessRevisionResolutionGuard.d.ts +12 -0
  103. package/dist/internal/headlessRevisionResolutionGuard.js +28 -0
  104. package/dist/internal/pageBreakRunDescendantIndex.d.ts +9 -0
  105. package/dist/internal/pageBreakRunDescendantIndex.js +27 -0
  106. package/dist/internal/pageBreakRunPartition.d.ts +26 -0
  107. package/dist/internal/pageBreakRunPartition.js +35 -0
  108. package/dist/internal/pageBreakRunSourceDescendantIndex.d.ts +15 -0
  109. package/dist/internal/pageBreakRunSourceDescendantIndex.js +126 -0
  110. package/dist/internal/sectionEndpointResolution.d.ts +32 -0
  111. package/dist/internal/sectionEndpointResolution.js +38 -0
  112. package/dist/layout-bridge/convert/footnoteLayout.js +1 -0
  113. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +16 -4
  114. package/dist/layout-bridge/convert/headerFooterLayout.js +52 -9
  115. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +4 -0
  116. package/dist/layout-bridge/convert/toFlowBlocks.js +391 -82
  117. package/dist/layout-bridge/dom/clickToPositionDom.d.ts +8 -1
  118. package/dist/layout-bridge/dom/clickToPositionDom.js +114 -40
  119. package/dist/layout-bridge/dom/textStreamDom.d.ts +24 -0
  120. package/dist/layout-bridge/dom/textStreamDom.js +75 -0
  121. package/dist/layout-bridge/headerFooterLayout.js +16 -30
  122. package/dist/layout-engine/index.js +12 -3
  123. package/dist/layout-engine/measure/tableFragmentBorderGeometry.d.ts +17 -0
  124. package/dist/layout-engine/measure/tableFragmentBorderGeometry.js +24 -0
  125. package/dist/layout-engine/renderedBreakReconciliation.js +1 -1
  126. package/dist/layout-engine/types.d.ts +7 -0
  127. package/dist/layout-painter/imageLayout.d.ts +1 -1
  128. package/dist/layout-painter/renderTable.js +20 -0
  129. package/dist/markdown/renderBlock.js +7 -10
  130. package/dist/model.d.ts +1 -1
  131. package/dist/paged-layout/rangeProjection.js +6 -9
  132. package/dist/paged-layout/transactionDirtyRange.d.ts +3 -1
  133. package/dist/paged-layout/transactionDirtyRange.js +23 -1
  134. package/dist/prosemirror/attrs/index.d.ts +7 -3
  135. package/dist/prosemirror/attrs/index.js +128 -7
  136. package/dist/prosemirror/bookmarkBoundaryIntegrity.d.ts +9 -0
  137. package/dist/prosemirror/bookmarkBoundaryIntegrity.js +22 -0
  138. package/dist/prosemirror/commands/comments.d.ts +10 -1
  139. package/dist/prosemirror/commands/comments.js +551 -87
  140. package/dist/prosemirror/commands/formatPainter.d.ts +45 -10
  141. package/dist/prosemirror/commands/formatPainter.js +319 -63
  142. package/dist/prosemirror/commands/index.d.ts +2 -2
  143. package/dist/prosemirror/commands/pageBreak.d.ts +5 -2
  144. package/dist/prosemirror/commands/pageBreak.js +18 -36
  145. package/dist/prosemirror/commands/propertyChangeScope.d.ts +27 -3
  146. package/dist/prosemirror/commands/propertyChangeScope.js +85 -14
  147. package/dist/prosemirror/conversion/fromProseDoc.d.ts +8 -5
  148. package/dist/prosemirror/conversion/fromProseDoc.js +935 -223
  149. package/dist/prosemirror/conversion/runShadingMark.js +2 -2
  150. package/dist/prosemirror/conversion/toProseDoc.d.ts +26 -1
  151. package/dist/prosemirror/conversion/toProseDoc.js +439 -291
  152. package/dist/prosemirror/extensions/StarterKit.js +4 -0
  153. package/dist/prosemirror/extensions/core/ParagraphExtension.js +54 -6
  154. package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +7 -1
  155. package/dist/prosemirror/extensions/features/ListExtension.js +95 -123
  156. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +19 -6
  157. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +27 -1
  158. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +134 -30
  159. package/dist/prosemirror/extensions/features/pasteCleanup.js +9 -15
  160. package/dist/prosemirror/extensions/marks/BoldExtension.js +4 -3
  161. package/dist/prosemirror/extensions/marks/CharacterStyleExtension.d.ts +4 -7
  162. package/dist/prosemirror/extensions/marks/CharacterStyleExtension.js +5 -11
  163. package/dist/prosemirror/extensions/marks/FontSizeExtension.js +3 -3
  164. package/dist/prosemirror/extensions/marks/ItalicExtension.js +4 -3
  165. package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.d.ts +13 -0
  166. package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.js +39 -0
  167. package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.d.ts +7 -1
  168. package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.js +67 -21
  169. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +2 -0
  170. package/dist/prosemirror/extensions/marks/markUtils.d.ts +8 -1
  171. package/dist/prosemirror/extensions/marks/markUtils.js +88 -2
  172. package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.js +44 -3
  173. package/dist/prosemirror/extensions/nodes/FieldExtension.js +1 -1
  174. package/dist/prosemirror/extensions/nodes/HardBreakExtension.js +15 -4
  175. package/dist/prosemirror/extensions/nodes/PageBreakExtension.d.ts +6 -0
  176. package/dist/prosemirror/extensions/nodes/PageBreakExtension.js +6 -0
  177. package/dist/prosemirror/extensions/nodes/PageBreakRunExtension.d.ts +6 -0
  178. package/dist/prosemirror/extensions/nodes/PageBreakRunExtension.js +36 -0
  179. package/dist/prosemirror/findReplaceSelection.js +8 -3
  180. package/dist/prosemirror/index.d.ts +3 -3
  181. package/dist/prosemirror/listMarker.d.ts +26 -1
  182. package/dist/prosemirror/listMarker.js +108 -14
  183. package/dist/prosemirror/pageBreakRunProjection.d.ts +28 -0
  184. package/dist/prosemirror/pageBreakRunProjection.js +47 -0
  185. package/dist/prosemirror/paraText.js +6 -0
  186. package/dist/prosemirror/paragraphAlignment.d.ts +12 -0
  187. package/dist/prosemirror/paragraphAlignment.js +13 -0
  188. package/dist/prosemirror/paragraphSpacing.d.ts +29 -0
  189. package/dist/prosemirror/paragraphSpacing.js +125 -0
  190. package/dist/prosemirror/plugins/documentNumbering.d.ts +8 -0
  191. package/dist/prosemirror/plugins/documentNumbering.js +18 -0
  192. package/dist/prosemirror/plugins/pmTextScan.d.ts +3 -2
  193. package/dist/prosemirror/plugins/pmTextScan.js +14 -4
  194. package/dist/prosemirror/plugins/suggestionMode.js +9 -11
  195. package/dist/prosemirror/rebaseParagraphRunFormatting.d.ts +16 -0
  196. package/dist/prosemirror/rebaseParagraphRunFormatting.js +61 -0
  197. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +64 -0
  198. package/dist/prosemirror/runFormattingInlineCarriers.js +121 -0
  199. package/dist/prosemirror/runFormattingProvenance.d.ts +12 -0
  200. package/dist/prosemirror/runFormattingProvenance.js +48 -0
  201. package/dist/prosemirror/runFormattingReconciliation.d.ts +25 -0
  202. package/dist/prosemirror/runFormattingReconciliation.js +54 -0
  203. package/dist/prosemirror/runPropertyChangeResolution.d.ts +18 -0
  204. package/dist/prosemirror/runPropertyChangeResolution.js +18 -0
  205. package/dist/prosemirror/runStyleFormatting.d.ts +50 -0
  206. package/dist/prosemirror/runStyleFormatting.js +105 -0
  207. package/dist/prosemirror/schema/index.d.ts +3 -3
  208. package/dist/prosemirror/schema/marks.d.ts +84 -9
  209. package/dist/prosemirror/schema/marks.js +73 -1
  210. package/dist/prosemirror/schema/nodes.d.ts +30 -6
  211. package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +14 -2
  212. package/dist/prosemirror/styles/resolvedStyleAttrs.js +45 -23
  213. package/dist/prosemirror/styles/styleResolver.d.ts +10 -13
  214. package/dist/prosemirror/styles/styleResolver.js +3 -3
  215. package/dist/prosemirror/styles/styleToggleCascade.d.ts +8 -1
  216. package/dist/prosemirror/styles/styleToggleCascade.js +24 -1
  217. package/dist/prosemirror/tableGridMutation.d.ts +20 -0
  218. package/dist/prosemirror/tableGridMutation.js +30 -0
  219. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +31 -0
  220. package/dist/prosemirror/trackedRunInlineAtoms.js +39 -0
  221. package/dist/prosemirror/utils/visualLineNavigation.js +27 -31
  222. package/dist/prosemirror/validation.js +23 -4
  223. package/dist/redline.js +4 -1
  224. package/dist/render-dom/HeaderFooterSelectionOverlay.js +20 -20
  225. package/dist/render-dom/RenderedDomContext.js +17 -34
  226. package/dist/server.d.ts +4 -4
  227. package/dist/server.js +2 -2
  228. package/dist/style-engine/styleEngine.d.ts +1 -1
  229. package/dist/utils/clipboard.js +1 -1
  230. package/dist/utils/findReplace.js +38 -21
  231. package/dist/utils/mergeDocumentContent.js +3 -3
  232. package/dist/utils/replaceText.js +2 -1
  233. package/dist/version-comparison.d.ts +38 -44
  234. package/dist/version-comparison.js +270 -399
  235. package/dist/watermark/index.js +2 -4
  236. package/package.json +8 -2
@@ -43,6 +43,7 @@ const InsertionExtension = createMarkExtension({
43
43
  revisionId: { default: 0 },
44
44
  author: { default: "" },
45
45
  date: { default: null },
46
+ utcDate: { default: null },
46
47
  moveKind: { default: null },
47
48
  initials: { default: null },
48
49
  provenance: { default: "user" },
@@ -95,6 +96,7 @@ const DeletionExtension = createMarkExtension({
95
96
  revisionId: { default: 0 },
96
97
  author: { default: "" },
97
98
  date: { default: null },
99
+ utcDate: { default: null },
98
100
  moveKind: { default: null },
99
101
  initials: { default: null },
100
102
  provenance: { default: "user" },
@@ -4,6 +4,13 @@ import { 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 setMark(markType: MarkType, attrs: MarkAttrs): Command;
7
+ type PairedToggleProperty = "bold" | "italic";
8
+ /** UI toggle whose direct-formatting contract explicitly targets both script families. */
9
+ declare const toggleMarkForAllScripts: (markType: MarkType, property: PairedToggleProperty) => Command;
10
+ /** UI size command whose direct-formatting contract explicitly targets both script families. */
11
+ declare const setFontSizeForAllScripts: (markType: MarkType, size: number) => Command;
12
+ /** Clears both ordinary and complex-script direct size through the UI command boundary. */
13
+ declare const clearFontSizeForAllScripts: (markType: MarkType) => Command;
7
14
  declare function toggleUnderlineMark(markType: MarkType): Command;
8
15
  declare function removeMark(markType: MarkType): Command;
9
16
  /**
@@ -31,4 +38,4 @@ declare function createSetMarkCommand(markType: MarkType, attrs?: Record<string,
31
38
  */
32
39
  declare function createRemoveMarkCommand(markType: MarkType): Command;
33
40
  //#endregion
34
- export { clearFormatting, createRemoveMarkCommand, createSetMarkCommand, getMarkAttr, isMarkActive, removeMark, setMark, textFormattingToMarks, toggleUnderlineMark };
41
+ export { clearFontSizeForAllScripts, clearFormatting, createRemoveMarkCommand, createSetMarkCommand, getMarkAttr, isMarkActive, removeMark, setFontSizeForAllScripts, setMark, textFormattingToMarks, toggleMarkForAllScripts, toggleUnderlineMark };
@@ -1,7 +1,10 @@
1
1
  import { FONT_THEME_VALUES } from "../../../types/documentEnumValues.js";
2
2
  import { mergeFontFamily } from "../../../utils/fontFamilyMerge.js";
3
- import { expectFontFamilyMarkAttrs } from "../../attrs/index.js";
3
+ import { expectFontFamilyMarkAttrs, expectRunFormattingOverrideMarkAttrs } from "../../attrs/index.js";
4
+ import { selectRunFormattingCarrierRepresentations } from "../../runFormattingInlineCarriers.js";
5
+ import { hasRunFormattingOverrideAttrs } from "../../runFormattingProvenance.js";
4
6
  import { applyRunFormattingOverrideMark, buildRunFormattingOverrideAttrs } from "./RunFormattingOverrideExtension.js";
7
+ import { toggleMark } from "prosemirror-commands";
5
8
  //#region src/prosemirror/extensions/marks/markUtils.ts
6
9
  const isFontTheme = (value) => value !== void 0 && FONT_THEME_VALUES.some((theme) => theme === value);
7
10
  const fontFamilyAttrsToFormatting = ({ ascii, hAnsi, eastAsia, cs, hint, asciiTheme, hAnsiTheme, eastAsiaTheme, csTheme }) => ({
@@ -158,6 +161,89 @@ function setMark(markType, attrs) {
158
161
  return true;
159
162
  };
160
163
  }
164
+ const DIRECT_FONT_PROPERTIES = [
165
+ "color",
166
+ "fontFamily",
167
+ "fontSize"
168
+ ];
169
+ const updatePairedToggleAttrs = (attrs, property, enabled) => {
170
+ const next = { ...attrs };
171
+ const complexProperty = property === "bold" ? "boldCs" : "italicCs";
172
+ if (property === "bold") {
173
+ next.bold = enabled;
174
+ next.boldCs = enabled;
175
+ } else {
176
+ next.italic = enabled;
177
+ next.italicCs = enabled;
178
+ }
179
+ const absences = next.complexScriptPropertyAbsences?.filter((candidate) => candidate !== complexProperty);
180
+ if (absences && absences.length > 0) next.complexScriptPropertyAbsences = absences;
181
+ else delete next.complexScriptPropertyAbsences;
182
+ return next;
183
+ };
184
+ const updateFontSizeCompanionAttrs = (attrs, size) => {
185
+ const next = { ...attrs };
186
+ const directFontProperties = new Set(next.directFontProperties ?? []);
187
+ if (size === void 0) {
188
+ delete next.fontSizeCs;
189
+ directFontProperties.delete("fontSize");
190
+ } else {
191
+ next.fontSizeCs = size;
192
+ directFontProperties.add("fontSize");
193
+ }
194
+ if (directFontProperties.size > 0) next.directFontProperties = DIRECT_FONT_PROPERTIES.filter((property) => directFontProperties.has(property));
195
+ else delete next.directFontProperties;
196
+ const absences = next.complexScriptPropertyAbsences?.filter((candidate) => candidate !== "fontSizeCs");
197
+ if (absences && absences.length > 0) next.complexScriptPropertyAbsences = absences;
198
+ else delete next.complexScriptPropertyAbsences;
199
+ return next;
200
+ };
201
+ const updateRunFormattingOverrideMarks = (marks, overrideType, update) => {
202
+ const existing = overrideType.isInSet(marks);
203
+ const attrs = update(existing ? expectRunFormattingOverrideMarkAttrs(existing) : {});
204
+ const withoutExisting = marks.filter((mark) => mark.type !== overrideType);
205
+ return hasRunFormattingOverrideAttrs(attrs) ? overrideType.create(attrs).addToSet(withoutExisting) : withoutExisting;
206
+ };
207
+ const updateRunFormattingOverride = (state, tr, update) => {
208
+ const overrideType = state.schema.marks["runFormattingOverride"];
209
+ if (!overrideType) return tr;
210
+ const { from, to, empty } = state.selection;
211
+ if (empty) {
212
+ const marks = updateRunFormattingOverrideMarks(tr.storedMarks ?? state.storedMarks ?? state.selection.$from.marks(), overrideType, update);
213
+ saveStoredMarksToParagraph(state, tr, marks);
214
+ tr.setStoredMarks(marks);
215
+ return tr;
216
+ }
217
+ const representations = selectRunFormattingCarrierRepresentations({
218
+ doc: tr.doc,
219
+ from,
220
+ to
221
+ });
222
+ for (const representation of representations) {
223
+ const { node, position } = representation;
224
+ const nextMarks = updateRunFormattingOverrideMarks(node.marks, overrideType, update);
225
+ if (node.isText) {
226
+ tr.removeMark(representation.from, representation.to, overrideType);
227
+ const nextOverride = overrideType.isInSet(nextMarks);
228
+ if (nextOverride) tr.addMark(representation.from, representation.to, nextOverride);
229
+ continue;
230
+ }
231
+ tr.setNodeMarkup(position, void 0, node.attrs, nextMarks);
232
+ }
233
+ return tr;
234
+ };
235
+ const withRunFormattingOverride = (command, update) => (state, dispatch) => command(state, dispatch ? (tr) => {
236
+ dispatch(updateRunFormattingOverride(state, tr, update));
237
+ } : void 0);
238
+ /** UI toggle whose direct-formatting contract explicitly targets both script families. */
239
+ const toggleMarkForAllScripts = (markType, property) => (state, dispatch) => {
240
+ const enabled = !isMarkActive(state, markType);
241
+ return withRunFormattingOverride(toggleMark(markType), (attrs) => updatePairedToggleAttrs(attrs, property, enabled))(state, dispatch);
242
+ };
243
+ /** UI size command whose direct-formatting contract explicitly targets both script families. */
244
+ const setFontSizeForAllScripts = (markType, size) => withRunFormattingOverride(setMark(markType, { size }), (attrs) => updateFontSizeCompanionAttrs(attrs, size));
245
+ /** Clears both ordinary and complex-script direct size through the UI command boundary. */
246
+ const clearFontSizeForAllScripts = (markType) => withRunFormattingOverride(removeMark(markType), (attrs) => updateFontSizeCompanionAttrs(attrs, void 0));
161
247
  function selectionHasVisibleUnderline(state, markType) {
162
248
  const { from, to, empty, $from } = state.selection;
163
249
  if (empty) {
@@ -321,4 +407,4 @@ function createRemoveMarkCommand(markType) {
321
407
  return removeMark(markType);
322
408
  }
323
409
  //#endregion
324
- export { clearFormatting, createRemoveMarkCommand, createSetMarkCommand, getMarkAttr, isMarkActive, removeMark, setMark, textFormattingToMarks, toggleUnderlineMark };
410
+ export { clearFontSizeForAllScripts, clearFormatting, createRemoveMarkCommand, createSetMarkCommand, getMarkAttr, isMarkActive, removeMark, setFontSizeForAllScripts, setMark, textFormattingToMarks, toggleMarkForAllScripts, toggleUnderlineMark };
@@ -1,7 +1,9 @@
1
- import { expectBookmarkBoundaryAttrs } from "../../bookmarkBoundaryAttrs.js";
1
+ import { readParagraphAttrs } from "../../attrs/index.js";
2
+ import { expectBookmarkBoundaryAttrs, readBookmarkBoundaryAttrs } from "../../bookmarkBoundaryAttrs.js";
3
+ import { findInvalidBookmarkBoundaryIds } from "../../bookmarkBoundaryIntegrity.js";
2
4
  import { createNodeExtension } from "../create.js";
5
+ import { Plugin } from "prosemirror-state";
3
6
  //#region src/prosemirror/extensions/nodes/BookmarkBoundaryExtension.ts
4
- /** Zero-width bookmark boundary that preserves its position through ProseMirror edits. */
5
7
  function readNonnegativeInteger(value) {
6
8
  if (value === null || !/^(?:0|[1-9]\d*)$/.test(value)) return false;
7
9
  const parsed = Number(value);
@@ -13,6 +15,37 @@ function readOptionalColumn(dom, attribute) {
13
15
  }
14
16
  /** The node name, for callers asking whether a paragraph holds any content. */
15
17
  const BOOKMARK_BOUNDARY_NODE_NAME = "bookmarkBoundary";
18
+ const collectInvalidBoundaries = (doc) => {
19
+ const boundaries = [];
20
+ const malformedBoundaries = [];
21
+ const paragraphBookmarkIds = /* @__PURE__ */ new Set();
22
+ doc.descendants((node, position) => {
23
+ if (node.type.name === "paragraph") {
24
+ const attrs = readParagraphAttrs(node);
25
+ if (attrs.ok) for (const bookmark of attrs.value.bookmarks ?? []) paragraphBookmarkIds.add(bookmark.id);
26
+ }
27
+ if (node.type.name !== "bookmarkBoundary") return true;
28
+ const result = readBookmarkBoundaryAttrs(node);
29
+ if (!result.ok) {
30
+ malformedBoundaries.push({
31
+ position,
32
+ node
33
+ });
34
+ return false;
35
+ }
36
+ const attrs = result.value;
37
+ const boundary = {
38
+ id: attrs.id,
39
+ type: attrs.type,
40
+ position,
41
+ node
42
+ };
43
+ boundaries.push(boundary);
44
+ return false;
45
+ });
46
+ const invalidIds = findInvalidBookmarkBoundaryIds(boundaries, paragraphBookmarkIds);
47
+ return [...boundaries.filter(({ id }) => invalidIds.has(id)), ...malformedBoundaries];
48
+ };
16
49
  const BookmarkBoundaryExtension = createNodeExtension({
17
50
  name: BOOKMARK_BOUNDARY_NODE_NAME,
18
51
  schemaNodeName: BOOKMARK_BOUNDARY_NODE_NAME,
@@ -63,7 +96,15 @@ const BookmarkBoundaryExtension = createNodeExtension({
63
96
  ...options.getInternalClipboardToken ? { "data-docx-internal-clipboard": options.getInternalClipboardToken() } : {}
64
97
  }];
65
98
  }
66
- })
99
+ }),
100
+ onSchemaReady: () => ({ plugins: [new Plugin({ appendTransaction(transactions, _oldState, newState) {
101
+ if (!transactions.some(({ docChanged }) => docChanged)) return null;
102
+ const invalidBoundaries = collectInvalidBoundaries(newState.doc);
103
+ if (invalidBoundaries.length === 0) return null;
104
+ const transaction = newState.tr;
105
+ for (const { node, position } of invalidBoundaries.toSorted((first, second) => second.position - first.position)) transaction.delete(position, position + node.nodeSize);
106
+ return transaction;
107
+ } })] })
67
108
  });
68
109
  //#endregion
69
110
  export { BOOKMARK_BOUNDARY_NODE_NAME, BookmarkBoundaryExtension };
@@ -74,7 +74,7 @@ const StructuredFieldExtension = createNodeExtension({
74
74
  nodeSpec: (options) => ({
75
75
  inline: true,
76
76
  group: "inline",
77
- content: "(text | bookmarkBoundary | tab | symbol | hardBreak | image | shape | renderedPageBreak | textBoxAnchor)+",
77
+ content: "(text | bookmarkBoundary | tab | symbol | hardBreak | pageBreakRun | image | shape | renderedPageBreak | textBoxAnchor)+",
78
78
  atom: true,
79
79
  selectable: true,
80
80
  attrs: createFieldAttrs(),
@@ -1,3 +1,4 @@
1
+ import { expectHardBreakAttrs } from "../../attrs/index.js";
1
2
  import { createNodeExtension } from "../create.js";
2
3
  import { panic } from "better-result";
3
4
  //#region src/prosemirror/extensions/nodes/HardBreakExtension.ts
@@ -10,19 +11,29 @@ const HardBreakExtension = createNodeExtension({
10
11
  nodeSpec: {
11
12
  inline: true,
12
13
  group: "inline",
13
- attrs: { breakType: { default: null } },
14
+ attrs: {
15
+ breakType: { default: null },
16
+ clear: { default: null }
17
+ },
14
18
  selectable: false,
15
19
  parseDOM: [{
16
20
  tag: "br",
17
21
  getAttrs(node) {
18
22
  if (!(node instanceof HTMLElement)) return null;
19
23
  const breakType = node.dataset["docxBreakType"];
20
- return breakType === "column" ? { breakType } : null;
24
+ const clear = node.dataset["docxBreakClear"];
25
+ const attrs = {};
26
+ if (breakType === "column" || breakType === "textWrapping") attrs["breakType"] = breakType;
27
+ if (clear === "none" || clear === "left" || clear === "right" || clear === "all") attrs["clear"] = clear;
28
+ return Object.keys(attrs).length > 0 ? attrs : null;
21
29
  }
22
30
  }],
23
31
  toDOM(node) {
24
- if (node.attrs["breakType"] === "column") return ["br", { "data-docx-break-type": "column" }];
25
- return ["br"];
32
+ const { breakType, clear } = expectHardBreakAttrs(node);
33
+ const attrs = {};
34
+ if (breakType !== void 0) attrs["data-docx-break-type"] = breakType;
35
+ if (clear !== void 0) attrs["data-docx-break-clear"] = clear;
36
+ return Object.keys(attrs).length > 0 ? ["br", attrs] : ["br"];
26
37
  }
27
38
  },
28
39
  onSchemaReady(ctx) {
@@ -3,6 +3,12 @@ import { NodeExtension } from "../types.js";
3
3
  /**
4
4
  * Page Break Extension — block node representing a DOCX page break
5
5
  */
6
+ /**
7
+ * LEGACY_PAGE_BREAK_NODE_REMOVAL_CONDITION: delete the block node after persisted editor
8
+ * snapshots created before `pageBreakRun` have been normalized and telemetry
9
+ * confirms that no loaded snapshot contains a block-level page break. DOCX
10
+ * import and editor commands must never create this legacy shape.
11
+ */
6
12
  declare const PageBreakExtension: (options?: Partial<Record<string, unknown>> | undefined) => NodeExtension;
7
13
  //#endregion
8
14
  export { PageBreakExtension };
@@ -3,6 +3,12 @@ import { createNodeExtension } from "../create.js";
3
3
  /**
4
4
  * Page Break Extension — block node representing a DOCX page break
5
5
  */
6
+ /**
7
+ * LEGACY_PAGE_BREAK_NODE_REMOVAL_CONDITION: delete the block node after persisted editor
8
+ * snapshots created before `pageBreakRun` have been normalized and telemetry
9
+ * confirms that no loaded snapshot contains a block-level page break. DOCX
10
+ * import and editor commands must never create this legacy shape.
11
+ */
6
12
  const PageBreakExtension = createNodeExtension({
7
13
  name: "pageBreak",
8
14
  schemaNodeName: "pageBreak",
@@ -0,0 +1,6 @@
1
+ import { NodeExtension } from "../types.js";
2
+ //#region src/prosemirror/extensions/nodes/PageBreakRunExtension.d.ts
3
+ /** Inline owner for an authored `<w:br w:type="page"/>` run child. */
4
+ declare const PageBreakRunExtension: (options?: Partial<Record<string, unknown>> | undefined) => NodeExtension;
5
+ //#endregion
6
+ export { PageBreakRunExtension };
@@ -0,0 +1,36 @@
1
+ import { expectPageBreakRunAttrs } from "../../attrs/index.js";
2
+ import { createNodeExtension } from "../create.js";
3
+ //#region src/prosemirror/extensions/nodes/PageBreakRunExtension.ts
4
+ /** Inline owner for an authored `<w:br w:type="page"/>` run child. */
5
+ const PAGE_BREAK_RUN_NODE_NAME = "pageBreakRun";
6
+ const PageBreakRunExtension = createNodeExtension({
7
+ name: PAGE_BREAK_RUN_NODE_NAME,
8
+ schemaNodeName: PAGE_BREAK_RUN_NODE_NAME,
9
+ nodeSpec: {
10
+ inline: true,
11
+ group: "inline",
12
+ atom: true,
13
+ marks: "_",
14
+ attrs: { clear: { default: null } },
15
+ selectable: true,
16
+ parseDOM: [{
17
+ tag: "span[data-docx-page-break-run]",
18
+ getAttrs(node) {
19
+ if (!(node instanceof HTMLElement)) return false;
20
+ const clear = node.dataset["docxBreakClear"];
21
+ return clear === "none" || clear === "left" || clear === "right" || clear === "all" ? { clear } : null;
22
+ }
23
+ }],
24
+ toDOM(node) {
25
+ const { clear } = expectPageBreakRunAttrs(node);
26
+ return ["span", {
27
+ "aria-hidden": "true",
28
+ "data-docx-page-break-run": "true",
29
+ ...clear ? { "data-docx-break-clear": clear } : {},
30
+ style: "display: inline-block; overflow: hidden; width: 0;"
31
+ }];
32
+ }
33
+ }
34
+ });
35
+ //#endregion
36
+ export { PageBreakRunExtension };
@@ -88,18 +88,23 @@ function resolveTextRangeInParagraph({ paragraph, paragraphPos, startOffset, end
88
88
  from: null,
89
89
  to: null
90
90
  };
91
+ const pageBreakOffsets = [];
91
92
  paragraph.descendants((node, pos) => {
93
+ if (node.type.name === "pageBreakRun") {
94
+ pageBreakOffsets.push(textOffset);
95
+ return false;
96
+ }
92
97
  const tokenLength = getSearchTextTokenLength(node);
93
98
  if (tokenLength === 0) return true;
94
99
  const textStart = textOffset;
95
100
  const textEnd = textStart + tokenLength;
96
101
  const nodeStart = paragraphPos + 1 + pos;
97
- if (range.from === null && startOffset >= textStart && startOffset <= textEnd) range.from = nodeStart + Math.min(startOffset - textStart, node.nodeSize);
98
- if (range.to === null && endOffset >= textStart && endOffset <= textEnd) range.to = nodeStart + Math.min(endOffset - textStart, node.nodeSize);
102
+ if (range.from === null && startOffset >= textStart && startOffset < textEnd) range.from = nodeStart + Math.min(startOffset - textStart, node.nodeSize);
103
+ if (range.to === null && endOffset > textStart && endOffset <= textEnd) range.to = nodeStart + Math.min(endOffset - textStart, node.nodeSize);
99
104
  textOffset = textEnd;
100
105
  return range.to === null;
101
106
  });
102
- if (range.from === null || range.to === null || range.from >= range.to) return null;
107
+ if (range.from === null || range.to === null || range.from >= range.to || pageBreakOffsets.some((offset) => offset > startOffset && offset < endOffset)) return null;
103
108
  return {
104
109
  from: range.from,
105
110
  to: range.to
@@ -1,9 +1,10 @@
1
1
  import { FontFamilyAttrs, FontSizeAttrs, HyperlinkAttrs, TextColorAttrs, UnderlineAttrs } from "./schema/marks.js";
2
2
  import { ImageAttrs, ParagraphAttrs } from "./schema/nodes.js";
3
+ import { ResolvedParagraphStyle, StyleResolver, createStyleResolver } from "./styles/styleResolver.js";
3
4
  import { schema, singletonManager } from "./schema/index.js";
4
5
  import { getParagraphAlignment, getParagraphBidi, getStyleId } from "./extensions/core/ParagraphExtension.js";
5
6
  import { BorderPreset, TableBorderPreset, TableContextInfo, getTableContext, isInTable as isInTableCell } from "./extensions/nodes/TableExtension.js";
6
- import { PAINTABLE_MARK_NAMES, applyFormatMarks, captureFormatMarks } from "./commands/formatPainter.js";
7
+ import { CapturedTextFormatting, PAINTABLE_MARK_NAMES, applyFormatMarks, captureFormatMarks } from "./commands/formatPainter.js";
7
8
  import { clearFormatting, getMarkAttr, isMarkActive } from "./extensions/marks/markUtils.js";
8
9
  import { getHyperlinkAttrs, getSelectedText, isHyperlinkActive } from "./extensions/marks/HyperlinkExtension.js";
9
10
  import { clearFontFamily, clearFontSize, clearHighlight, clearTextColor, insertHyperlink, removeHyperlink, setFontFamily, setFontSize, setHighlight, setHyperlink, setTextColor, toggleBold, toggleItalic, toggleStrike, toggleSubscript, toggleSuperscript, toggleUnderline } from "./commands/formatting.js";
@@ -19,11 +20,10 @@ import { ProseMirrorDocumentValidationIssue, ValidateProseMirrorDocumentResult,
19
20
  import "./conversion/index.js";
20
21
  import { SelectionChangeCallback, SelectionContext, createSelectionTrackerPlugin, extractSelectionContext, getSelectionContext, selectionTrackerKey } from "./plugins/selectionTracker.js";
21
22
  import { ensureParaIdsInState } from "./extensions/features/ParaIdAllocatorExtension.js";
22
- import { ResolvedParagraphStyle, StyleResolver, createStyleResolver } from "./styles/styleResolver.js";
23
23
  import "./styles/index.js";
24
24
  import { SelectionState, extractSelectionState } from "./selectionState.js";
25
25
  import { createDocumentStylesPlugin, documentStylesKey, getDocumentStyleResolver } from "./plugins/documentStyles.js";
26
26
  import "./plugins/index.js";
27
27
  import { insertPageBreakInView, insertTableInView, insertTableOfContentsInView } from "./insertOperations.js";
28
28
  import { TextSelection } from "prosemirror-state";
29
- export { type BorderPreset, type FontFamilyAttrs, type FontSizeAttrs, type HyperlinkAttrs, type ImageAttrs, PAINTABLE_MARK_NAMES, type ParagraphAttrs, type ProseMirrorDocumentValidationIssue, type ResolvedParagraphStyle, type SelectionChangeCallback, type SelectionContext, type SelectionState, StyleResolver, type TableBorderPreset, type TableContextInfo, type TextColorAttrs, TextSelection, type ToProseDocOptions, type UnderlineAttrs, type ValidateProseMirrorDocumentResult, addColumnLeft, addColumnRight, addRowAbove, addRowBelow, addTabStop, alignCenter, alignJustify, alignLeft, alignRight, applyFormatMarks, applyStyle, applyTableStyle, assertValidProseMirrorDocument, autoFitContents, captureFormatMarks, clearFontFamily, clearFontSize, clearFormatting, clearHighlight, clearStyle, clearTextColor, createDocumentStylesPlugin, createEmptyDoc, createSelectionTrackerPlugin, createStyleResolver, decreaseIndent, decreaseListLevel, deleteColumn, deleteRow, deleteTable, distributeColumns, documentStylesKey, ensureParaIdsInState, extractSelectionContext, extractSelectionState, formatProseMirrorDocumentIssues, fromProseDoc, generateTOC, getDocumentStyleResolver, getHyperlinkAttrs, getListInfo, getMarkAttr, getParagraphAlignment, getParagraphBidi, getSelectedText, getSelectionContext, getStyleId, getTableContext, increaseIndent, increaseListLevel, insertHyperlink, insertImageFromFile, insertPageBreak, insertPageBreakInView, insertTable, insertTableInView, insertTableOfContentsInView, isHyperlinkActive, isInList, isInTableCell as isInTable, isMarkActive, mergeCells, removeHyperlink, removeList, removeTabStop, removeTableBorders, schema, selectColumn, selectRow, selectTable, selectionTrackerKey, setAlignment, setAllTableBorders, setCellBorder, setCellFillColor, setCellMargins, setCellTextDirection, setCellVerticalAlign, setFontFamily, setFontSize, setHighlight, setHyperlink, setIndentFirstLine, setIndentLeft, setIndentRight, setInsideTableBorders, setLineSpacing, setLtr, setOutsideTableBorders, setRowHeight, setRtl, setTableBorderColor, setTableBorderPreset, setTableBorderWidth, setTableBorders, setTableProperties, setTextColor, singletonManager, splitCell, toProseDoc, toggleBidi, toggleBold, toggleBulletList, toggleHeaderRow, toggleItalic, toggleNoWrap, toggleNumberedList, toggleStrike, toggleSubscript, toggleSuperscript, toggleUnderline, updateDocumentContent, validateProseMirrorDocument };
29
+ export { type BorderPreset, type CapturedTextFormatting, type FontFamilyAttrs, type FontSizeAttrs, type HyperlinkAttrs, type ImageAttrs, PAINTABLE_MARK_NAMES, type ParagraphAttrs, type ProseMirrorDocumentValidationIssue, type ResolvedParagraphStyle, type SelectionChangeCallback, type SelectionContext, type SelectionState, StyleResolver, type TableBorderPreset, type TableContextInfo, type TextColorAttrs, TextSelection, type ToProseDocOptions, type UnderlineAttrs, type ValidateProseMirrorDocumentResult, addColumnLeft, addColumnRight, addRowAbove, addRowBelow, addTabStop, alignCenter, alignJustify, alignLeft, alignRight, applyFormatMarks, applyStyle, applyTableStyle, assertValidProseMirrorDocument, autoFitContents, captureFormatMarks, clearFontFamily, clearFontSize, clearFormatting, clearHighlight, clearStyle, clearTextColor, createDocumentStylesPlugin, createEmptyDoc, createSelectionTrackerPlugin, createStyleResolver, decreaseIndent, decreaseListLevel, deleteColumn, deleteRow, deleteTable, distributeColumns, documentStylesKey, ensureParaIdsInState, extractSelectionContext, extractSelectionState, formatProseMirrorDocumentIssues, fromProseDoc, generateTOC, getDocumentStyleResolver, getHyperlinkAttrs, getListInfo, getMarkAttr, getParagraphAlignment, getParagraphBidi, getSelectedText, getSelectionContext, getStyleId, getTableContext, increaseIndent, increaseListLevel, insertHyperlink, insertImageFromFile, insertPageBreak, insertPageBreakInView, insertTable, insertTableInView, insertTableOfContentsInView, isHyperlinkActive, isInList, isInTableCell as isInTable, isMarkActive, mergeCells, removeHyperlink, removeList, removeTabStop, removeTableBorders, schema, selectColumn, selectRow, selectTable, selectionTrackerKey, setAlignment, setAllTableBorders, setCellBorder, setCellFillColor, setCellMargins, setCellTextDirection, setCellVerticalAlign, setFontFamily, setFontSize, setHighlight, setHyperlink, setIndentFirstLine, setIndentLeft, setIndentRight, setInsideTableBorders, setLineSpacing, setLtr, setOutsideTableBorders, setRowHeight, setRtl, setTableBorderColor, setTableBorderPreset, setTableBorderWidth, setTableBorders, setTableProperties, setTextColor, singletonManager, splitCell, toProseDoc, toggleBidi, toggleBold, toggleBulletList, toggleHeaderRow, toggleItalic, toggleNoWrap, toggleNumberedList, toggleStrike, toggleSubscript, toggleSuperscript, toggleUnderline, updateDocumentContent, validateProseMirrorDocument };
@@ -5,6 +5,12 @@ type ListCounterState = {
5
5
  counters: Map<number, number[]>;
6
6
  abstractCounters: Map<number, number[]>;
7
7
  seenLevels: Set<string>;
8
+ restartedNumIds?: Set<number>;
9
+ previousList?: {
10
+ abstractNumId: number | null;
11
+ fromStyle: boolean;
12
+ numId: number | null;
13
+ };
8
14
  lastAdvancedNumId?: number;
9
15
  };
10
16
  type ListCounterStreams = {
@@ -36,6 +42,25 @@ type ResolvedListTemplate = {
36
42
  components: readonly ResolvedListComponent[];
37
43
  };
38
44
  declare const MAX_LIST_LEVEL = 8;
45
+ declare const LIST_RENDERING_ATTR_KEYS: readonly ["listIsBullet", "listIsLegal", "listNumFmt", "listMarker", "listMarkerTemplate", "listMarkerHidden", "listMarkerFormatting", "listMarkerAlignment", "listMarkerSuffix", "listMarkerAllCaps", "listImplicitChildLevelAdvances", "listMarkerSecondSlotOffsetTwips", "listLevelNumFmts", "listLevelStarts", "listAbstractNumId", "listStartOverride"];
46
+ declare const CLEARED_LIST_RENDERING_ATTRS: Readonly<{
47
+ listIsBullet: null;
48
+ listIsLegal: null;
49
+ listNumFmt: null;
50
+ listMarker: null;
51
+ listMarkerTemplate: null;
52
+ listMarkerHidden: null;
53
+ listMarkerFormatting: null;
54
+ listMarkerAlignment: null;
55
+ listMarkerSuffix: null;
56
+ listMarkerAllCaps: null;
57
+ listImplicitChildLevelAdvances: null;
58
+ listMarkerSecondSlotOffsetTwips: null;
59
+ listLevelNumFmts: null;
60
+ listLevelStarts: null;
61
+ listAbstractNumId: null;
62
+ listStartOverride: null;
63
+ }>;
39
64
  declare function createListCounterState(): ListCounterState;
40
65
  declare function cloneListCounterState(state: ListCounterState): ListCounterState;
41
66
  /**
@@ -55,4 +80,4 @@ declare function resolveListTemplate(options: ResolveListTemplateOptions): strin
55
80
  declare function resolveListTemplateWithComponents({ template, counters, levelFormats, forceDecimal }: ResolveListTemplateOptions): ResolvedListTemplate;
56
81
  declare function advanceListMarker(attrs: ParagraphAttrs, state: ListCounterState): string | null;
57
82
  //#endregion
58
- export { AdvancedListMarker, ListCounterState, ListCounterStream, ListCounterStreams, MAX_LIST_LEVEL, ResolvedListComponent, ResolvedListTemplate, VisibleListMarker, advanceListMarker, advanceVisibleListMarker, cloneListCounterState, createListCounterState, formatCounter, resolveListTemplate, resolveListTemplateWithComponents };
83
+ export { AdvancedListMarker, CLEARED_LIST_RENDERING_ATTRS, LIST_RENDERING_ATTR_KEYS, ListCounterState, ListCounterStream, ListCounterStreams, MAX_LIST_LEVEL, ResolvedListComponent, ResolvedListTemplate, VisibleListMarker, advanceListMarker, advanceVisibleListMarker, cloneListCounterState, createListCounterState, formatCounter, resolveListTemplate, resolveListTemplateWithComponents };
@@ -2,22 +2,78 @@ import { convertBulletToUnicode } from "../docx/bulletMarkers.js";
2
2
  import { formatOoxmlCounter } from "../docx/ooxmlCounterFormatter.js";
3
3
  //#region src/prosemirror/listMarker.ts
4
4
  const MAX_LIST_LEVEL = 8;
5
+ const LIST_RENDERING_ATTR_KEYS = [
6
+ "listIsBullet",
7
+ "listIsLegal",
8
+ "listNumFmt",
9
+ "listMarker",
10
+ "listMarkerTemplate",
11
+ "listMarkerHidden",
12
+ "listMarkerFormatting",
13
+ "listMarkerAlignment",
14
+ "listMarkerSuffix",
15
+ "listMarkerAllCaps",
16
+ "listImplicitChildLevelAdvances",
17
+ "listMarkerSecondSlotOffsetTwips",
18
+ "listLevelNumFmts",
19
+ "listLevelStarts",
20
+ "listAbstractNumId",
21
+ "listStartOverride"
22
+ ];
23
+ const CLEARED_LIST_RENDERING_ATTRS = Object.freeze({
24
+ listIsBullet: null,
25
+ listIsLegal: null,
26
+ listNumFmt: null,
27
+ listMarker: null,
28
+ listMarkerTemplate: null,
29
+ listMarkerHidden: null,
30
+ listMarkerFormatting: null,
31
+ listMarkerAlignment: null,
32
+ listMarkerSuffix: null,
33
+ listMarkerAllCaps: null,
34
+ listImplicitChildLevelAdvances: null,
35
+ listMarkerSecondSlotOffsetTwips: null,
36
+ listLevelNumFmts: null,
37
+ listLevelStarts: null,
38
+ listAbstractNumId: null,
39
+ listStartOverride: null
40
+ });
5
41
  function createListCounterState() {
6
42
  return {
7
43
  counters: /* @__PURE__ */ new Map(),
8
44
  abstractCounters: /* @__PURE__ */ new Map(),
9
- seenLevels: /* @__PURE__ */ new Set()
45
+ seenLevels: /* @__PURE__ */ new Set(),
46
+ restartedNumIds: /* @__PURE__ */ new Set(),
47
+ previousList: {
48
+ abstractNumId: null,
49
+ fromStyle: false,
50
+ numId: null
51
+ }
10
52
  };
11
53
  }
12
54
  function cloneListCounterState(state) {
55
+ const clonedArrays = /* @__PURE__ */ new Map();
56
+ const cloneCounters = (source) => {
57
+ const existing = clonedArrays.get(source);
58
+ if (existing) return existing;
59
+ const cloned = [...source];
60
+ clonedArrays.set(source, cloned);
61
+ return cloned;
62
+ };
13
63
  const counters = /* @__PURE__ */ new Map();
14
- for (const [numId, values] of state.counters) counters.set(numId, [...values]);
64
+ for (const [numId, values] of state.counters) counters.set(numId, cloneCounters(values));
15
65
  const abstractCounters = /* @__PURE__ */ new Map();
16
- for (const [abstractNumId, values] of state.abstractCounters) abstractCounters.set(abstractNumId, [...values]);
66
+ for (const [abstractNumId, values] of state.abstractCounters) abstractCounters.set(abstractNumId, cloneCounters(values));
17
67
  return {
18
68
  counters,
19
69
  abstractCounters,
20
70
  seenLevels: new Set(state.seenLevels),
71
+ restartedNumIds: new Set(state.restartedNumIds ?? []),
72
+ previousList: { ...state.previousList ?? {
73
+ abstractNumId: null,
74
+ fromStyle: false,
75
+ numId: null
76
+ } },
21
77
  ...state.lastAdvancedNumId !== void 0 ? { lastAdvancedNumId: state.lastAdvancedNumId } : {}
22
78
  };
23
79
  }
@@ -35,7 +91,14 @@ function previousListAttrs(attrs) {
35
91
  ...previous.listIsLegal !== void 0 ? { listIsLegal: previous.listIsLegal } : {},
36
92
  ...previous.listNumFmt !== void 0 ? { listNumFmt: previous.listNumFmt } : {},
37
93
  ...previous.listMarker !== void 0 ? { listMarker: previous.listMarker } : {},
94
+ ...previous.listMarkerTemplate !== void 0 ? { listMarkerTemplate: previous.listMarkerTemplate } : {},
38
95
  ...previous.listMarkerHidden !== void 0 ? { listMarkerHidden: previous.listMarkerHidden } : {},
96
+ ...previous.listMarkerFormatting !== void 0 ? { listMarkerFormatting: previous.listMarkerFormatting } : {},
97
+ ...previous.listMarkerAlignment !== void 0 ? { listMarkerAlignment: previous.listMarkerAlignment } : {},
98
+ ...previous.listMarkerSuffix !== void 0 ? { listMarkerSuffix: previous.listMarkerSuffix } : {},
99
+ ...previous.listMarkerAllCaps !== void 0 ? { listMarkerAllCaps: previous.listMarkerAllCaps } : {},
100
+ ...previous.listImplicitChildLevelAdvances !== void 0 ? { listImplicitChildLevelAdvances: previous.listImplicitChildLevelAdvances } : {},
101
+ ...previous.listMarkerSecondSlotOffsetTwips !== void 0 ? { listMarkerSecondSlotOffsetTwips: previous.listMarkerSecondSlotOffsetTwips } : {},
39
102
  ...previous.listLevelNumFmts !== void 0 ? { listLevelNumFmts: previous.listLevelNumFmts } : {},
40
103
  ...previous.listLevelStarts !== void 0 ? { listLevelStarts: previous.listLevelStarts } : {},
41
104
  ...previous.listAbstractNumId !== void 0 ? { listAbstractNumId: previous.listAbstractNumId } : {},
@@ -129,26 +192,52 @@ function formatNumberedMarker(counters, level) {
129
192
  return parts.length === 0 ? "1." : `${parts.join(".")}.`;
130
193
  }
131
194
  function advanceListMarker(attrs, state) {
195
+ const markerTemplate = attrs.listMarkerTemplate ?? attrs.listMarker;
132
196
  const level = attrs.numPr?.ilvl ?? 0;
133
197
  if (!Number.isInteger(level) || level < 0 || level > 8) return null;
134
198
  const numId = attrs.numPr?.numId;
135
199
  if (numId === void 0 || numId === 0) {
136
- if (attrs.listMarker?.includes("%") && !attrs.listIsBullet) {
200
+ let marker = null;
201
+ if (markerTemplate?.includes("%") && !attrs.listIsBullet) {
137
202
  const counters = getLastListCounters(state);
138
- if (counters) return resolveListTemplate({
139
- template: attrs.listMarker,
203
+ if (counters) marker = resolveListTemplate({
204
+ template: markerTemplate,
140
205
  counters,
141
206
  levelFormats: attrs.listLevelNumFmts,
142
207
  forceDecimal: attrs.listIsLegal
143
208
  });
144
209
  }
145
- return null;
210
+ state.previousList = {
211
+ abstractNumId: null,
212
+ fromStyle: false,
213
+ numId: null
214
+ };
215
+ return marker;
146
216
  }
147
- if (attrs.listIsBullet) return convertBulletToUnicode(attrs.listMarker ?? "");
148
- const counters = state.counters.get(numId) ?? Array.from({ length: 9 }, () => NaN);
217
+ if (attrs.listIsBullet) {
218
+ state.previousList = {
219
+ abstractNumId: null,
220
+ fromStyle: false,
221
+ numId: null
222
+ };
223
+ return convertBulletToUnicode(attrs.listMarker ?? markerTemplate ?? "");
224
+ }
225
+ const firstInstanceEncounter = !state.counters.has(numId);
226
+ let counters = state.counters.get(numId) ?? Array.from({ length: 9 }, () => NaN);
149
227
  const abstractNumId = attrs.listAbstractNumId;
228
+ const previousList = state.previousList ?? {
229
+ abstractNumId: null,
230
+ fromStyle: false,
231
+ numId: null
232
+ };
233
+ const restartedNumIds = state.restartedNumIds ??= /* @__PURE__ */ new Set();
234
+ const latestAbstractCounters = abstractNumId === void 0 ? void 0 : state.abstractCounters.get(abstractNumId);
235
+ const styleNumbering = attrs.numPrFromStyle;
236
+ const resumesRestartedInstance = firstInstanceEncounter && attrs.listStartOverride == null && abstractNumId !== void 0 && previousList.abstractNumId === abstractNumId && previousList.numId !== null && previousList.numId !== numId && restartedNumIds.has(previousList.numId);
237
+ const resumesStyleInstance = firstInstanceEncounter && !styleNumbering && attrs.listStartOverride == null && abstractNumId !== void 0 && previousList.abstractNumId === abstractNumId && previousList.fromStyle;
238
+ if (latestAbstractCounters && (styleNumbering || resumesRestartedInstance || resumesStyleInstance)) counters = latestAbstractCounters;
239
+ if (attrs.listStartOverride != null || resumesRestartedInstance || previousList.numId === numId && restartedNumIds.has(numId)) restartedNumIds.add(numId);
150
240
  if (level > 0) {
151
- const latestAbstractCounters = abstractNumId === void 0 ? void 0 : state.abstractCounters.get(abstractNumId);
152
241
  if (counters.slice(0, level).every((counter) => !Number.isFinite(counter))) for (let index = 0; index < level; index += 1) {
153
242
  const latestCounter = latestAbstractCounters?.[index];
154
243
  counters[index] = latestCounter !== void 0 && Number.isFinite(latestCounter) ? latestCounter : attrs.listLevelStarts?.[index] ?? 1;
@@ -169,10 +258,15 @@ function advanceListMarker(attrs, state) {
169
258
  }
170
259
  state.counters.set(numId, counters);
171
260
  state.lastAdvancedNumId = numId;
172
- if (abstractNumId !== void 0) state.abstractCounters.set(abstractNumId, [...counters]);
261
+ if (abstractNumId !== void 0) state.abstractCounters.set(abstractNumId, counters);
262
+ state.previousList = {
263
+ abstractNumId: abstractNumId ?? null,
264
+ fromStyle: Boolean(styleNumbering),
265
+ numId
266
+ };
173
267
  const levelFormats = attrs.listLevelNumFmts ?? (attrs.listNumFmt ? [attrs.listNumFmt] : void 0);
174
- if (attrs.listMarker?.includes("%")) return resolveListTemplate({
175
- template: attrs.listMarker,
268
+ if (markerTemplate?.includes("%")) return resolveListTemplate({
269
+ template: markerTemplate,
176
270
  counters,
177
271
  levelFormats,
178
272
  forceDecimal: attrs.listIsLegal
@@ -182,4 +276,4 @@ function advanceListMarker(attrs, state) {
182
276
  return formatNumberedMarker(counters, level);
183
277
  }
184
278
  //#endregion
185
- export { MAX_LIST_LEVEL, advanceListMarker, advanceVisibleListMarker, cloneListCounterState, createListCounterState, formatCounter, resolveListTemplate, resolveListTemplateWithComponents };
279
+ export { CLEARED_LIST_RENDERING_ATTRS, LIST_RENDERING_ATTR_KEYS, MAX_LIST_LEVEL, advanceListMarker, advanceVisibleListMarker, cloneListCounterState, createListCounterState, formatCounter, resolveListTemplate, resolveListTemplateWithComponents };
@@ -0,0 +1,28 @@
1
+ import { document_d_exports } from "../types/document.js";
2
+ import { ParagraphAttrs } from "./schema/nodes.js";
3
+ import { Node } from "prosemirror-model";
4
+ //#region src/prosemirror/pageBreakRunProjection.d.ts
5
+ declare const PAGE_BREAK_RUN_PARAGRAPH_PROJECTION_MESSAGES: {
6
+ readonly borders: "A bordered paragraph containing an explicit page-break run cannot be projected";
7
+ readonly frame: "A framed paragraph containing an explicit page-break run cannot be projected";
8
+ readonly outline: "An outline paragraph containing an explicit page-break run cannot be projected";
9
+ readonly textBoxAnchor: "A paragraph containing both an explicit page-break run and a text-box anchor cannot be projected";
10
+ };
11
+ type PageBreakRunParagraphProjectionReason = keyof typeof PAGE_BREAK_RUN_PARAGRAPH_PROJECTION_MESSAGES;
12
+ type PageBreakRunParagraphProjectionDisposition = {
13
+ status: "supported";
14
+ } | {
15
+ status: "unsupported";
16
+ reason: PageBreakRunParagraphProjectionReason;
17
+ message: (typeof PAGE_BREAK_RUN_PARAGRAPH_PROJECTION_MESSAGES)[keyof typeof PAGE_BREAK_RUN_PARAGRAPH_PROJECTION_MESSAGES];
18
+ };
19
+ type PageBreakRunParagraphFeatures = {
20
+ attrs: ParagraphAttrs;
21
+ effectiveFrame: document_d_exports.ParagraphFormatting["frame"];
22
+ hasTextBoxAnchor: boolean;
23
+ };
24
+ /** Keep source-import and ProseMirror-layout ownership decisions on one predicate. */
25
+ declare const pageBreakRunParagraphProjectionDispositionForFeatures: ({ attrs, effectiveFrame, hasTextBoxAnchor }: PageBreakRunParagraphFeatures) => PageBreakRunParagraphProjectionDisposition;
26
+ declare const pageBreakRunParagraphProjectionDisposition: (paragraph: Node) => PageBreakRunParagraphProjectionDisposition;
27
+ //#endregion
28
+ export { PageBreakRunParagraphProjectionDisposition, PageBreakRunParagraphProjectionReason, pageBreakRunParagraphProjectionDisposition, pageBreakRunParagraphProjectionDispositionForFeatures };