@stll/folio-core 0.53.0 → 0.54.1

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 (155) hide show
  1. package/dist/ai-edits/apply.js +415 -166
  2. package/dist/ai-edits/batch-claims.d.ts +21 -6
  3. package/dist/ai-edits/batch-claims.js +47 -16
  4. package/dist/ai-edits/headless.d.ts +20 -0
  5. package/dist/ai-edits/headless.js +140 -11
  6. package/dist/ai-edits/pending-suggestions.js +1 -1
  7. package/dist/ai-edits/read.d.ts +5 -3
  8. package/dist/ai-edits/read.js +97 -47
  9. package/dist/ai-edits/revisionStretches.d.ts +17 -0
  10. package/dist/ai-edits/revisionStretches.js +80 -0
  11. package/dist/ai-edits/snapshot.js +3 -2
  12. package/dist/ai-edits/table-cell-mutations.d.ts +3 -1
  13. package/dist/ai-edits/table-cell-mutations.js +2 -1
  14. package/dist/ai-edits/table-row-column-mutations.d.ts +6 -1
  15. package/dist/ai-edits/table-row-column-mutations.js +27 -10
  16. package/dist/compare/content-alignment.d.ts +5 -1
  17. package/dist/compare/content-alignment.js +39 -32
  18. package/dist/compare/inline-provenance.js +1 -1
  19. package/dist/controller/layoutPipeline.js +3 -2
  20. package/dist/docx/archiveInflation.d.ts +127 -0
  21. package/dist/docx/archiveInflation.js +181 -0
  22. package/dist/docx/metadataPrivacy.js +24 -1
  23. package/dist/docx/noteReferenceMark.d.ts +15 -0
  24. package/dist/docx/noteReferenceMark.js +48 -0
  25. package/dist/docx/paragraphParser.js +5 -3
  26. package/dist/docx/paragraphPropertySource.d.ts +1 -1
  27. package/dist/docx/paragraphPropertySource.js +4 -2
  28. package/dist/docx/parser.js +2 -2
  29. package/dist/docx/rezip.js +4 -2
  30. package/dist/docx/selectiveXmlPatch.d.ts +3 -1
  31. package/dist/docx/selectiveXmlPatch.js +81 -3
  32. package/dist/docx/server/boundedArchive.d.ts +8 -13
  33. package/dist/docx/server/boundedArchive.js +70 -59
  34. package/dist/docx/server/extractDocxText.d.ts +8 -2
  35. package/dist/docx/server/extractDocxText.js +2 -2
  36. package/dist/docx/server/validateDocxConformance.d.ts +1 -1
  37. package/dist/docx/server/validateDocxConformance.js +1 -0
  38. package/dist/docx/unzip.d.ts +19 -2
  39. package/dist/docx/unzip.js +135 -24
  40. package/dist/docx/verticalMergeProjection.d.ts +17 -0
  41. package/dist/docx/verticalMergeProjection.js +120 -0
  42. package/dist/fonts/embeddedFonts.js +1 -1
  43. package/dist/i18n/messages/catalogs.gen.d.ts +34 -34
  44. package/dist/i18n/messages/catalogs.gen.js +34 -34
  45. package/dist/i18n/messages/messages.gen.d.ts +2 -2
  46. package/dist/internal/wholeStoryRevisionResolution.js +95 -25
  47. package/dist/layout-engine/measure/measureParagraph.js +2 -2
  48. package/dist/layout-engine/measure/paragraphMeasureShared.d.ts +12 -1
  49. package/dist/layout-engine/measure/paragraphMeasureShared.js +14 -1
  50. package/dist/markdown/escape.d.ts +2 -2
  51. package/dist/markdown/escape.js +4 -5
  52. package/dist/markdown/renderBlock.js +91 -25
  53. package/dist/markdown/renderRuns.d.ts +10 -1
  54. package/dist/markdown/renderRuns.js +320 -59
  55. package/dist/prosemirror/clearRunColor.d.ts +6 -0
  56. package/dist/prosemirror/clearRunColor.js +46 -0
  57. package/dist/prosemirror/commands/comments.js +62 -22
  58. package/dist/prosemirror/commands/formatPainter.js +1 -1
  59. package/dist/prosemirror/commands/hyperlink.js +2 -1
  60. package/dist/prosemirror/commands/propertyChangeScope.d.ts +3 -2
  61. package/dist/prosemirror/commands/propertyChangeScope.js +28 -4
  62. package/dist/prosemirror/commands/resolveAllTableChanges.js +40 -41
  63. package/dist/prosemirror/commands/resolveParagraphProperties.js +33 -8
  64. package/dist/prosemirror/commands/tableCellMergeResolution.d.ts +7 -1
  65. package/dist/prosemirror/commands/tableCellMergeResolution.js +39 -20
  66. package/dist/prosemirror/commands/tableMergeFoldDecisions.d.ts +61 -0
  67. package/dist/prosemirror/commands/tableMergeFoldDecisions.js +79 -0
  68. package/dist/prosemirror/containerFinalParagraph.d.ts +11 -5
  69. package/dist/prosemirror/containerFinalParagraph.js +7 -6
  70. package/dist/prosemirror/conversion/fromProseDoc.d.ts +2 -13
  71. package/dist/prosemirror/conversion/fromProseDoc.js +12 -590
  72. package/dist/prosemirror/conversion/toProseDoc.d.ts +1 -13
  73. package/dist/prosemirror/conversion/toProseDoc.js +28 -262
  74. package/dist/prosemirror/documentSchema.d.ts +8 -0
  75. package/dist/prosemirror/documentSchema.js +18 -0
  76. package/dist/prosemirror/extensions/StarterKit.js +2 -0
  77. package/dist/prosemirror/extensions/core/ParagraphExtension.js +104 -63
  78. package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +1 -1
  79. package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.js +24 -3
  80. package/dist/prosemirror/extensions/features/JoinedRunStyleExtension.d.ts +20 -0
  81. package/dist/prosemirror/extensions/features/JoinedRunStyleExtension.js +43 -0
  82. package/dist/prosemirror/extensions/features/ListExtension.js +10 -9
  83. package/dist/prosemirror/extensions/features/pastedHeadingStyles.js +1 -1
  84. package/dist/prosemirror/extensions/features/pastedHtmlLists.js +2 -4
  85. package/dist/prosemirror/extensions/marks/FootnoteRefExtension.js +14 -8
  86. package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +8 -4
  87. package/dist/prosemirror/extensions/marks/StrikeExtension.js +2 -2
  88. package/dist/prosemirror/extensions/marks/SubscriptExtension.js +2 -2
  89. package/dist/prosemirror/extensions/marks/SuperscriptExtension.js +2 -2
  90. package/dist/prosemirror/extensions/marks/TextColorExtension.js +4 -3
  91. package/dist/prosemirror/extensions/marks/markUtils.d.ts +8 -6
  92. package/dist/prosemirror/extensions/marks/markUtils.js +17 -8
  93. package/dist/prosemirror/extensions/marks/noteReferenceDeletion.d.ts +3 -1
  94. package/dist/prosemirror/extensions/marks/noteReferenceDeletion.js +12 -1
  95. package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +2 -2
  96. package/dist/prosemirror/extensions/nodes/HardBreakExtension.js +5 -3
  97. package/dist/prosemirror/extensions/nodes/TableExtension.js +104 -210
  98. package/dist/prosemirror/extensions/types.d.ts +7 -0
  99. package/dist/prosemirror/hyperlinkRemoval.d.ts +9 -0
  100. package/dist/prosemirror/hyperlinkRemoval.js +129 -0
  101. package/dist/prosemirror/index.d.ts +2 -1
  102. package/dist/prosemirror/index.js +2 -1
  103. package/dist/prosemirror/listNumbering.d.ts +3 -21
  104. package/dist/prosemirror/listNumbering.js +24 -39
  105. package/dist/prosemirror/listRendering.d.ts +29 -0
  106. package/dist/prosemirror/listRendering.js +26 -0
  107. package/dist/prosemirror/markupViewNotes.d.ts +8 -0
  108. package/dist/prosemirror/markupViewNotes.js +49 -0
  109. package/dist/prosemirror/markupViewProjection.d.ts +3 -1
  110. package/dist/prosemirror/markupViewProjection.js +7 -2
  111. package/dist/prosemirror/noteReferenceReview.d.ts +77 -0
  112. package/dist/prosemirror/noteReferenceReview.js +332 -0
  113. package/dist/prosemirror/paragraphIndentation.js +5 -2
  114. package/dist/prosemirror/paragraphMarkJoin.d.ts +6 -4
  115. package/dist/prosemirror/paragraphMarkJoin.js +21 -19
  116. package/dist/prosemirror/paragraphPropertyCarry.d.ts +64 -0
  117. package/dist/prosemirror/paragraphPropertyCarry.js +155 -0
  118. package/dist/prosemirror/plugins/documentStyleState.d.ts +26 -0
  119. package/dist/prosemirror/plugins/documentStyleState.js +32 -0
  120. package/dist/prosemirror/plugins/documentStyles.d.ts +2 -21
  121. package/dist/prosemirror/plugins/documentStyles.js +66 -29
  122. package/dist/prosemirror/plugins/index.d.ts +2 -1
  123. package/dist/prosemirror/plugins/index.js +2 -1
  124. package/dist/prosemirror/plugins/paragraphStyleResolution.d.ts +15 -0
  125. package/dist/prosemirror/plugins/paragraphStyleResolution.js +230 -0
  126. package/dist/prosemirror/plugins/suggestionMode.d.ts +12 -2
  127. package/dist/prosemirror/plugins/suggestionMode.js +387 -28
  128. package/dist/prosemirror/plugins/templateDirectives.d.ts +6 -0
  129. package/dist/prosemirror/plugins/templateDirectives.js +21 -7
  130. package/dist/prosemirror/plugins/templatePreviewValues.js +14 -21
  131. package/dist/prosemirror/rebaseParagraphRunFormatting.d.ts +22 -2
  132. package/dist/prosemirror/rebaseParagraphRunFormatting.js +39 -13
  133. package/dist/prosemirror/rebaseParagraphRuns.d.ts +36 -0
  134. package/dist/prosemirror/rebaseParagraphRuns.js +99 -0
  135. package/dist/prosemirror/runFormattingFromMarks.d.ts +18 -0
  136. package/dist/prosemirror/runFormattingFromMarks.js +567 -0
  137. package/dist/prosemirror/runFormattingReconciliation.js +10 -9
  138. package/dist/prosemirror/schema/nodes.d.ts +2 -0
  139. package/dist/prosemirror/styles/paragraphStyleCascade.d.ts +59 -0
  140. package/dist/prosemirror/styles/paragraphStyleCascade.js +145 -0
  141. package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +21 -2
  142. package/dist/prosemirror/styles/resolvedStyleAttrs.js +38 -1
  143. package/dist/prosemirror/styles/tableStyleRegions.d.ts +31 -0
  144. package/dist/prosemirror/styles/tableStyleRegions.js +55 -0
  145. package/dist/prosemirror/tableCellPaste.d.ts +74 -0
  146. package/dist/prosemirror/tableCellPaste.js +525 -0
  147. package/dist/prosemirror/tableGridMutation.d.ts +53 -14
  148. package/dist/prosemirror/tableGridMutation.js +166 -18
  149. package/dist/prosemirror/tableRunIn.d.ts +51 -0
  150. package/dist/prosemirror/tableRunIn.js +165 -0
  151. package/dist/prosemirror/textInput.js +11 -2
  152. package/dist/prosemirror/trackedRevisionPath.d.ts +17 -0
  153. package/dist/prosemirror/trackedRevisionPath.js +32 -0
  154. package/dist/server.d.ts +2 -2
  155. package/package.json +6 -6
@@ -0,0 +1,567 @@
1
+ import { normalizeHorizontalScalePercent } from "../utils/horizontalScale.js";
2
+ import { mergeTextFormatting } from "../utils/textFormattingMerge.js";
3
+ import { expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectEmphasisMarkAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectHighlightMarkAttrs, expectLanguageMarkAttrs, expectRunFormattingOverrideMarkAttrs, expectRunShadingMarkAttrs, expectStrikeMarkAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectUnderlineMarkAttrs } from "./attrs/index.js";
4
+ import { runShadingAttrsToShading, shadingToRunShadingAttrs } from "./conversion/runShadingMark.js";
5
+ import { applyRunFormattingOverrideAttrs, buildRunFormattingOverrideAttrs } from "./extensions/marks/RunFormattingOverrideExtension.js";
6
+ import { authoredRunFormattingFromAttrs, hasAuthoredRunFormattingProvenance } from "./runFormattingProvenance.js";
7
+ import { paragraphFormattingForRun, resolveEffectiveRunStyleFormatting, suppressParagraphMarkFormatting } from "./runStyleFormatting.js";
8
+ //#region src/prosemirror/runFormattingFromMarks.ts
9
+ const RUN_FORMATTING_VISUAL_GROUPS = {
10
+ bold: "bold",
11
+ boldCs: null,
12
+ italic: "italic",
13
+ italicCs: null,
14
+ underline: "underline",
15
+ strike: "strike",
16
+ doubleStrike: "strike",
17
+ vertAlign: "vertAlign",
18
+ smallCaps: "smallCaps",
19
+ allCaps: "allCaps",
20
+ hidden: "hidden",
21
+ noProof: null,
22
+ color: "color",
23
+ highlight: "highlight",
24
+ shading: "shading",
25
+ fontSize: "fontSize",
26
+ fontSizeCs: null,
27
+ fontFamily: "fontFamily",
28
+ language: "language",
29
+ spacing: "characterSpacing",
30
+ position: "characterSpacing",
31
+ scale: "characterSpacing",
32
+ kerning: "characterSpacing",
33
+ effect: "effect",
34
+ emphasisMark: "emphasisMark",
35
+ emboss: "emboss",
36
+ imprint: "imprint",
37
+ outline: "outline",
38
+ shadow: "shadow",
39
+ rtl: "rtl",
40
+ cs: null,
41
+ styleId: null,
42
+ preserved: null
43
+ };
44
+ const RUN_FORMATTING_FAST_PATH_DISPOSITION = {
45
+ bold: "visual",
46
+ boldCs: "structural",
47
+ italic: "visual",
48
+ italicCs: "structural",
49
+ underline: "visual",
50
+ strike: "visual",
51
+ doubleStrike: "visual",
52
+ vertAlign: "visual",
53
+ smallCaps: "visual",
54
+ allCaps: "visual",
55
+ hidden: "visual",
56
+ noProof: "structural",
57
+ color: "visual",
58
+ highlight: "visual",
59
+ shading: "visual",
60
+ fontSize: "visual",
61
+ fontSizeCs: "structural",
62
+ fontFamily: "visual",
63
+ language: "visual",
64
+ spacing: "visual",
65
+ position: "visual",
66
+ scale: "visual",
67
+ kerning: "visual",
68
+ effect: "visual",
69
+ emphasisMark: "visual",
70
+ emboss: "visual",
71
+ imprint: "visual",
72
+ outline: "visual",
73
+ shadow: "visual",
74
+ rtl: "visual",
75
+ cs: "structural",
76
+ styleId: "character-style",
77
+ preserved: "structural"
78
+ };
79
+ const hasOnlyCarrierlessVisualFormatting = (formatting) => {
80
+ for (const property of Object.keys(formatting)) if (RUN_FORMATTING_FAST_PATH_DISPOSITION[property] !== "visual") return false;
81
+ return true;
82
+ };
83
+ const visibleUnderline = (formatting) => {
84
+ const underline = formatting?.underline;
85
+ return underline?.style === "none" ? void 0 : underline;
86
+ };
87
+ const visibleStrike = (formatting) => {
88
+ if (formatting?.doubleStrike === true) return "double";
89
+ return formatting?.strike === true ? "single" : void 0;
90
+ };
91
+ const visibleColor = (formatting) => formatting?.color?.auto === true ? void 0 : formatting?.color;
92
+ const visibleValue = (value) => value === "none" ? void 0 : value;
93
+ /**
94
+ * Compare the exact presentation encoded by PM run marks without allocating the
95
+ * intermediate maps used by reconciliation. Non-visual authored state is
96
+ * deliberately absent here: the carrierless fast path below excludes every
97
+ * structural carrier before calling this predicate.
98
+ */
99
+ const sameVisualFormatting = (left, right) => {
100
+ if (left?.bold === true !== (right?.bold === true) || left?.italic === true !== (right?.italic === true) || !sameFormattingValue(visibleUnderline(left), visibleUnderline(right)) || visibleStrike(left) !== visibleStrike(right) || !sameFormattingValue(visibleColor(left), visibleColor(right)) || visibleValue(left?.highlight) !== visibleValue(right?.highlight) || (left?.fontSize || void 0) !== (right?.fontSize || void 0) || !sameFormattingValue(left?.fontFamily, right?.fontFamily) || !sameFormattingValue(left?.language, right?.language) || (left?.vertAlign === "superscript" || left?.vertAlign === "subscript" ? left.vertAlign : void 0) !== (right?.vertAlign === "superscript" || right?.vertAlign === "subscript" ? right.vertAlign : void 0) || left?.allCaps === true !== (right?.allCaps === true) || left?.smallCaps === true !== (right?.smallCaps === true) || left?.hidden === true !== (right?.hidden === true) || left?.emboss === true !== (right?.emboss === true) || left?.imprint === true !== (right?.imprint === true) || left?.shadow === true !== (right?.shadow === true) || left?.outline === true !== (right?.outline === true) || left?.rtl === true !== (right?.rtl === true) || (typeof left?.spacing === "number" ? left.spacing : null) !== (typeof right?.spacing === "number" ? right.spacing : null) || (typeof left?.position === "number" ? left.position : null) !== (typeof right?.position === "number" ? right.position : null) || (normalizeHorizontalScalePercent(left?.scale) ?? null) !== (normalizeHorizontalScalePercent(right?.scale) ?? null) || (typeof left?.kerning === "number" ? left.kerning : null) !== (typeof right?.kerning === "number" ? right.kerning : null) || visibleValue(left?.effect) !== visibleValue(right?.effect) || visibleValue(left?.emphasisMark) !== visibleValue(right?.emphasisMark)) return false;
101
+ return sameFormattingValue(shadingToRunShadingAttrs(left?.shading), shadingToRunShadingAttrs(right?.shading));
102
+ };
103
+ const visualFormattingGroups = (formatting) => {
104
+ const groups = /* @__PURE__ */ new Map();
105
+ if (!formatting) return groups;
106
+ if (formatting.bold) groups.set("bold", true);
107
+ if (formatting.italic) groups.set("italic", true);
108
+ if (formatting.underline && formatting.underline.style !== "none") groups.set("underline", {
109
+ style: formatting.underline.style || "single",
110
+ ...formatting.underline.color ? { color: formatting.underline.color } : {}
111
+ });
112
+ if (formatting.strike || formatting.doubleStrike) groups.set("strike", formatting.doubleStrike ? "double" : "single");
113
+ if (formatting.color && !formatting.color.auto) {
114
+ const { rgb, themeColor, themeTint, themeShade } = formatting.color;
115
+ groups.set("color", {
116
+ ...rgb ? { rgb } : {},
117
+ ...themeColor ? { themeColor } : {},
118
+ ...themeTint ? { themeTint } : {},
119
+ ...themeShade ? { themeShade } : {}
120
+ });
121
+ }
122
+ if (formatting.highlight && formatting.highlight !== "none") groups.set("highlight", formatting.highlight);
123
+ const shadingAttrs = shadingToRunShadingAttrs(formatting.shading);
124
+ if (shadingAttrs) groups.set("shading", runShadingAttrsToShading(shadingAttrs));
125
+ if (formatting.fontSize) groups.set("fontSize", formatting.fontSize);
126
+ if (formatting.fontFamily) {
127
+ const { ascii, hAnsi, eastAsia, cs, hint, asciiTheme, hAnsiTheme, eastAsiaTheme, csTheme } = formatting.fontFamily;
128
+ groups.set("fontFamily", {
129
+ ...ascii ? { ascii } : {},
130
+ ...hAnsi ? { hAnsi } : {},
131
+ ...eastAsia ? { eastAsia } : {},
132
+ ...cs ? { cs } : {},
133
+ ...hint ? { hint } : {},
134
+ ...asciiTheme ? { asciiTheme } : {},
135
+ ...hAnsiTheme ? { hAnsiTheme } : {},
136
+ ...eastAsiaTheme ? { eastAsiaTheme } : {},
137
+ ...csTheme ? { csTheme } : {}
138
+ });
139
+ }
140
+ if (formatting.language) {
141
+ const { val, eastAsia, bidi } = formatting.language;
142
+ groups.set("language", {
143
+ ...val ? { val } : {},
144
+ ...eastAsia ? { eastAsia } : {},
145
+ ...bidi ? { bidi } : {}
146
+ });
147
+ }
148
+ if (formatting.vertAlign === "superscript" || formatting.vertAlign === "subscript") groups.set("vertAlign", formatting.vertAlign);
149
+ for (const [property, group] of [
150
+ ["allCaps", "allCaps"],
151
+ ["smallCaps", "smallCaps"],
152
+ ["hidden", "hidden"],
153
+ ["emboss", "emboss"],
154
+ ["imprint", "imprint"],
155
+ ["shadow", "shadow"],
156
+ ["outline", "outline"],
157
+ ["rtl", "rtl"]
158
+ ]) if (formatting[property]) groups.set(group, true);
159
+ const spacing = typeof formatting.spacing === "number" ? formatting.spacing : null;
160
+ const position = typeof formatting.position === "number" ? formatting.position : null;
161
+ const scale = normalizeHorizontalScalePercent(formatting.scale) ?? null;
162
+ const kerning = typeof formatting.kerning === "number" ? formatting.kerning : null;
163
+ if (spacing !== null || position !== null || scale !== null || kerning !== null) groups.set("characterSpacing", {
164
+ spacing,
165
+ position,
166
+ scale,
167
+ kerning
168
+ });
169
+ if (formatting.effect && formatting.effect !== "none") groups.set("effect", formatting.effect);
170
+ if (formatting.emphasisMark && formatting.emphasisMark !== "none") groups.set("emphasisMark", formatting.emphasisMark);
171
+ return groups;
172
+ };
173
+ const expectedRunFormattingOverrideAttrs = (authoredFormatting) => {
174
+ const attrs = buildRunFormattingOverrideAttrs(authoredFormatting, {
175
+ type: "authored-baseline",
176
+ formatting: authoredFormatting
177
+ });
178
+ const hasDirectFormatting = Object.keys(authoredFormatting).some((property) => property !== "styleId");
179
+ if (!attrs && !hasDirectFormatting) return;
180
+ const expected = { ...attrs };
181
+ const directFontProperties = [
182
+ "color",
183
+ "fontFamily",
184
+ "fontSize"
185
+ ].filter((property) => authoredFormatting[property] !== void 0);
186
+ if (directFontProperties.length > 0) expected.directFontProperties = directFontProperties;
187
+ const complexScriptPropertyAbsences = [
188
+ ["bold", "boldCs"],
189
+ ["italic", "italicCs"],
190
+ ["fontSize", "fontSizeCs"]
191
+ ].filter(([ordinary, complex]) => authoredFormatting[ordinary] !== void 0 && authoredFormatting[complex] === void 0).map(([, complex]) => complex);
192
+ if (complexScriptPropertyAbsences.length > 0) expected.complexScriptPropertyAbsences = complexScriptPropertyAbsences;
193
+ return Object.keys(expected).length > 0 ? expected : void 0;
194
+ };
195
+ const changedVisualFormattingGroups = (observedFormatting, expectedFormatting) => {
196
+ const actual = visualFormattingGroups(observedFormatting);
197
+ const expected = visualFormattingGroups(expectedFormatting);
198
+ const changed = /* @__PURE__ */ new Set();
199
+ for (const group of /* @__PURE__ */ new Set([...actual.keys(), ...expected.keys()])) {
200
+ const actualValue = actual.get(group);
201
+ const expectedValue = expected.get(group);
202
+ if (!sameFormattingValue(actualValue, expectedValue)) changed.add(group);
203
+ }
204
+ return changed;
205
+ };
206
+ const VISUAL_BOOLEAN_FORMATTING_PROPERTIES = /* @__PURE__ */ new Set([
207
+ "allCaps",
208
+ "bold",
209
+ "doubleStrike",
210
+ "emboss",
211
+ "hidden",
212
+ "imprint",
213
+ "italic",
214
+ "outline",
215
+ "rtl",
216
+ "shadow",
217
+ "smallCaps",
218
+ "strike"
219
+ ]);
220
+ const fontFamilyDifference = (actual, inherited) => {
221
+ const difference = {};
222
+ for (const property of [
223
+ "ascii",
224
+ "hAnsi",
225
+ "eastAsia",
226
+ "cs",
227
+ "hint",
228
+ "asciiTheme",
229
+ "hAnsiTheme",
230
+ "eastAsiaTheme",
231
+ "csTheme"
232
+ ]) {
233
+ const value = actual[property];
234
+ if (value !== void 0 && value !== inherited?.[property]) Reflect.set(difference, property, value);
235
+ }
236
+ return Object.keys(difference).length > 0 ? difference : void 0;
237
+ };
238
+ const DIRECT_OVERRIDE_FORMATTING_PROPERTIES = [
239
+ "allCaps",
240
+ "bold",
241
+ "boldCs",
242
+ "cs",
243
+ "doubleStrike",
244
+ "emboss",
245
+ "fontSizeCs",
246
+ "hidden",
247
+ "noProof",
248
+ "imprint",
249
+ "italic",
250
+ "italicCs",
251
+ "outline",
252
+ "rtl",
253
+ "shadow",
254
+ "smallCaps",
255
+ "strike",
256
+ "underline"
257
+ ];
258
+ const POSITIVE_OVERRIDE_PROPERTIES_REPRESENTED_BY_VISUAL_MARKS = /* @__PURE__ */ new Set([
259
+ "allCaps",
260
+ "emboss",
261
+ "hidden",
262
+ "imprint",
263
+ "outline",
264
+ "rtl",
265
+ "shadow",
266
+ "smallCaps",
267
+ "strike"
268
+ ]);
269
+ const setFormattingFromOverrideSignal = (formatting, property, value) => {
270
+ Reflect.deleteProperty(formatting, property);
271
+ if (value === void 0) return;
272
+ if (property === "underline") {
273
+ formatting.underline = { style: "none" };
274
+ return;
275
+ }
276
+ Reflect.set(formatting, property, value);
277
+ };
278
+ const sameFormattingValue = (left, right) => {
279
+ if (left === right) return true;
280
+ if (typeof left !== "object" || left === null || typeof right !== "object" || right === null) return false;
281
+ if (Array.isArray(left) || Array.isArray(right)) {
282
+ if (!Array.isArray(left) || !Array.isArray(right) || left.length !== right.length) return false;
283
+ return left.every((value, index) => sameFormattingValue(value, right[index]));
284
+ }
285
+ const leftKeys = Object.keys(left);
286
+ const rightKeys = Object.keys(right);
287
+ if (leftKeys.length !== rightKeys.length) return false;
288
+ return leftKeys.every((key) => Object.prototype.hasOwnProperty.call(right, key) && sameFormattingValue(Reflect.get(left, key), Reflect.get(right, key)));
289
+ };
290
+ const reconcileOverrideSignals = (formatting, current, expected, inheritedFormatting, observedFormatting) => {
291
+ for (const property of DIRECT_OVERRIDE_FORMATTING_PROPERTIES) {
292
+ if (sameFormattingValue(current?.[property], expected?.[property])) continue;
293
+ if (current?.[property] === void 0 && expected?.[property] === true && POSITIVE_OVERRIDE_PROPERTIES_REPRESENTED_BY_VISUAL_MARKS.has(property)) continue;
294
+ if (current && hasAuthoredRunFormattingProvenance(current) && expected?.[property] === void 0 && sameFormattingValue(current[property], inheritedFormatting?.[property])) continue;
295
+ setFormattingFromOverrideSignal(formatting, property, current?.[property]);
296
+ }
297
+ for (const property of [
298
+ "color",
299
+ "fontFamily",
300
+ "fontSize"
301
+ ]) {
302
+ const currentIsDirect = current?.directFontProperties?.includes(property) === true;
303
+ if (currentIsDirect === (expected?.directFontProperties?.includes(property) === true)) continue;
304
+ if (!currentIsDirect) {
305
+ Reflect.deleteProperty(formatting, property);
306
+ continue;
307
+ }
308
+ const observed = observedFormatting[property];
309
+ if (observed !== void 0) Reflect.set(formatting, property, observed);
310
+ }
311
+ for (const property of [
312
+ "boldCs",
313
+ "italicCs",
314
+ "fontSizeCs"
315
+ ]) {
316
+ const currentIsAbsent = current?.complexScriptPropertyAbsences?.includes(property) === true;
317
+ if (currentIsAbsent !== (expected?.complexScriptPropertyAbsences?.includes(property) === true) && currentIsAbsent) Reflect.deleteProperty(formatting, property);
318
+ }
319
+ };
320
+ /**
321
+ * Reconcile source-authored provenance with the current visual mark set at the
322
+ * one save boundary shared by editor commands, raw transactions and compare.
323
+ * Unchanged groups keep exact source state (including equal direct values and
324
+ * otherwise invisible sentinels); changed groups derive the smallest direct
325
+ * override needed relative to the current style cascade.
326
+ */
327
+ const reconcileAuthoredFormatting = ({ authoredFormatting, carrierlessContext, currentOverrideAttrs, inheritedFormatting, observedFormatting }) => {
328
+ const hasAuthoredFormatting = Object.keys(authoredFormatting).length > 0;
329
+ if (carrierlessContext === "ordinary" && currentOverrideAttrs === void 0 && !hasAuthoredFormatting && hasOnlyCarrierlessVisualFormatting(observedFormatting)) {
330
+ if (sameVisualFormatting(observedFormatting, inheritedFormatting)) return authoredFormatting;
331
+ if (observedFormatting.fontFamily === void 0 && sameVisualFormatting(inheritedFormatting, void 0)) return observedFormatting;
332
+ }
333
+ const expectedFormatting = hasAuthoredFormatting ? mergeTextFormatting(inheritedFormatting, authoredFormatting) : inheritedFormatting;
334
+ const changedGroups = changedVisualFormattingGroups(observedFormatting, expectedFormatting);
335
+ const reconciled = { ...authoredFormatting };
336
+ for (const property of Object.keys(RUN_FORMATTING_VISUAL_GROUPS)) {
337
+ const group = RUN_FORMATTING_VISUAL_GROUPS[property];
338
+ if (group === null || !changedGroups.has(group)) continue;
339
+ Reflect.deleteProperty(reconciled, property);
340
+ if (VISUAL_BOOLEAN_FORMATTING_PROPERTIES.has(property)) {
341
+ const observed = observedFormatting[property] === true;
342
+ if (observed !== (inheritedFormatting?.[property] === true)) Reflect.set(reconciled, property, observed);
343
+ continue;
344
+ }
345
+ const observed = observedFormatting[property];
346
+ if (observed === void 0) continue;
347
+ if (property === "fontFamily") {
348
+ const difference = fontFamilyDifference(observed, inheritedFormatting?.fontFamily);
349
+ if (difference) reconciled.fontFamily = difference;
350
+ continue;
351
+ }
352
+ if (!sameFormattingValue(observed, inheritedFormatting?.[property])) Reflect.set(reconciled, property, observed);
353
+ }
354
+ if (currentOverrideAttrs !== void 0) reconcileOverrideSignals(reconciled, currentOverrideAttrs, expectedRunFormattingOverrideAttrs(authoredFormatting), inheritedFormatting, observedFormatting);
355
+ return reconciled;
356
+ };
357
+ const formattingAuthorshipCost = (formatting) => {
358
+ let cost = 0;
359
+ const visit = (value) => {
360
+ if (value === void 0) return;
361
+ if (value === null || typeof value !== "object") {
362
+ cost++;
363
+ return;
364
+ }
365
+ const entries = Object.entries(value);
366
+ if (entries.length === 0) {
367
+ cost++;
368
+ return;
369
+ }
370
+ for (const [, nested] of entries) visit(nested);
371
+ };
372
+ for (const [property, value] of Object.entries(formatting)) if (property !== "styleId") visit(value);
373
+ return cost;
374
+ };
375
+ function marksToTextFormatting(marks, options) {
376
+ const formatting = {};
377
+ let directOverrideFormatting;
378
+ let directFontProperties;
379
+ let characterStyleId;
380
+ let runFormattingOverrideMark;
381
+ let currentOverrideAttrs;
382
+ for (const mark of marks) switch (mark.type.name) {
383
+ case "bold":
384
+ formatting.bold = true;
385
+ break;
386
+ case "italic":
387
+ formatting.italic = true;
388
+ break;
389
+ case "underline": {
390
+ const attrs = expectUnderlineMarkAttrs(mark);
391
+ const uline = { style: attrs.style || "single" };
392
+ if (attrs.color) uline.color = attrs.color;
393
+ formatting.underline = uline;
394
+ break;
395
+ }
396
+ case "strike":
397
+ if (expectStrikeMarkAttrs(mark).double) formatting.doubleStrike = true;
398
+ else formatting.strike = true;
399
+ break;
400
+ case "textColor": {
401
+ const attrs = expectTextColorMarkAttrs(mark);
402
+ const colorVal = {};
403
+ if (attrs.rgb) colorVal.rgb = attrs.rgb;
404
+ if (attrs.themeColor) colorVal.themeColor = attrs.themeColor;
405
+ if (attrs.themeTint) colorVal.themeTint = attrs.themeTint;
406
+ if (attrs.themeShade) colorVal.themeShade = attrs.themeShade;
407
+ formatting.color = colorVal;
408
+ break;
409
+ }
410
+ case "highlight":
411
+ formatting.highlight = expectHighlightMarkAttrs(mark).color;
412
+ break;
413
+ case "runShading":
414
+ formatting.shading = runShadingAttrsToShading(expectRunShadingMarkAttrs(mark));
415
+ break;
416
+ case "fontSize":
417
+ formatting.fontSize = expectFontSizeMarkAttrs(mark).size;
418
+ break;
419
+ case "fontFamily": {
420
+ const attrs = expectFontFamilyMarkAttrs(mark);
421
+ const ff = {};
422
+ if (attrs.ascii) ff.ascii = attrs.ascii;
423
+ if (attrs.hAnsi) ff.hAnsi = attrs.hAnsi;
424
+ if (attrs.eastAsia) ff.eastAsia = attrs.eastAsia;
425
+ if (attrs.hint) ff.hint = attrs.hint;
426
+ if (attrs.cs) ff.cs = attrs.cs;
427
+ if (attrs.asciiTheme) ff.asciiTheme = attrs.asciiTheme;
428
+ if (attrs.hAnsiTheme) ff.hAnsiTheme = attrs.hAnsiTheme;
429
+ if (attrs.eastAsiaTheme) ff.eastAsiaTheme = attrs.eastAsiaTheme;
430
+ if (attrs.csTheme) ff.csTheme = attrs.csTheme;
431
+ formatting.fontFamily = ff;
432
+ break;
433
+ }
434
+ case "language": {
435
+ const attrs = expectLanguageMarkAttrs(mark);
436
+ formatting.language = {
437
+ ...attrs.val ? { val: attrs.val } : {},
438
+ ...attrs.eastAsia ? { eastAsia: attrs.eastAsia } : {},
439
+ ...attrs.bidi ? { bidi: attrs.bidi } : {}
440
+ };
441
+ break;
442
+ }
443
+ case "superscript":
444
+ formatting.vertAlign = "superscript";
445
+ break;
446
+ case "subscript":
447
+ formatting.vertAlign = "subscript";
448
+ break;
449
+ case "allCaps":
450
+ formatting.allCaps = true;
451
+ break;
452
+ case "smallCaps":
453
+ formatting.smallCaps = true;
454
+ break;
455
+ case "characterSpacing": {
456
+ const attrs = expectCharacterSpacingMarkAttrs(mark);
457
+ if (attrs.spacing !== void 0) formatting.spacing = attrs.spacing;
458
+ if (attrs.position !== void 0) formatting.position = attrs.position;
459
+ const horizontalScale = normalizeHorizontalScalePercent(attrs.scale);
460
+ if (horizontalScale !== void 0) formatting.scale = horizontalScale;
461
+ if (attrs.kerning !== void 0) formatting.kerning = attrs.kerning;
462
+ break;
463
+ }
464
+ case "emboss":
465
+ formatting.emboss = true;
466
+ break;
467
+ case "imprint":
468
+ formatting.imprint = true;
469
+ break;
470
+ case "hidden":
471
+ formatting.hidden = true;
472
+ break;
473
+ case "textShadow":
474
+ formatting.shadow = true;
475
+ break;
476
+ case "emphasisMark":
477
+ formatting.emphasisMark = expectEmphasisMarkAttrs(mark).type || "dot";
478
+ break;
479
+ case "textOutline":
480
+ formatting.outline = true;
481
+ break;
482
+ case "rtl":
483
+ formatting.rtl = true;
484
+ break;
485
+ case "textEffect":
486
+ formatting.effect = expectTextEffectMarkAttrs(mark).effect;
487
+ break;
488
+ case "runFormattingOverride":
489
+ runFormattingOverrideMark = mark;
490
+ break;
491
+ case "characterStyle": {
492
+ const attrs = expectCharacterStyleMarkAttrs(mark);
493
+ formatting.styleId = attrs.styleId;
494
+ characterStyleId = attrs.styleId;
495
+ break;
496
+ }
497
+ default: break;
498
+ }
499
+ let authoredFormatting = {};
500
+ if (runFormattingOverrideMark) {
501
+ const overrideAttrs = expectRunFormattingOverrideMarkAttrs(runFormattingOverrideMark);
502
+ currentOverrideAttrs = overrideAttrs;
503
+ directFontProperties = overrideAttrs.directFontProperties;
504
+ directOverrideFormatting = {};
505
+ applyRunFormattingOverrideAttrs(directOverrideFormatting, overrideAttrs);
506
+ for (const property of directFontProperties ?? []) {
507
+ const value = formatting[property];
508
+ if (value !== void 0) Reflect.set(directOverrideFormatting, property, value);
509
+ }
510
+ authoredFormatting = authoredRunFormattingFromAttrs(overrideAttrs) ?? directOverrideFormatting;
511
+ }
512
+ if (characterStyleId !== void 0 && !options?.styleResolver) {
513
+ const conservativeFormatting = mergeTextFormatting(formatting, directOverrideFormatting) ?? {};
514
+ for (const property of currentOverrideAttrs?.complexScriptPropertyAbsences ?? []) Reflect.deleteProperty(conservativeFormatting, property);
515
+ return {
516
+ ...conservativeFormatting,
517
+ styleId: characterStyleId
518
+ };
519
+ }
520
+ const inheritedFormatting = resolveEffectiveRunStyleFormatting({
521
+ marks,
522
+ paragraphFormatting: paragraphFormattingForRun({
523
+ context: {
524
+ baseParagraphFormatting: options?.baseParagraphFormatting,
525
+ paragraphFormatting: options?.inheritedFormatting,
526
+ paragraphMarkFormatting: options?.paragraphMarkFormatting,
527
+ paragraphMarkPrecedesStyle: options?.paragraphMarkPrecedesStyle ?? false
528
+ },
529
+ directFormatting: authoredFormatting,
530
+ marks
531
+ }),
532
+ ...options?.styleResolver !== void 0 ? { styleResolver: options.styleResolver } : {}
533
+ });
534
+ let reconciled = reconcileAuthoredFormatting({
535
+ authoredFormatting,
536
+ carrierlessContext: options?.paragraphMarkFormatting === void 0 ? "ordinary" : "paragraph-mark",
537
+ currentOverrideAttrs,
538
+ inheritedFormatting,
539
+ observedFormatting: formatting
540
+ });
541
+ if (runFormattingOverrideMark === void 0 && characterStyleId === void 0 && options?.paragraphMarkFormatting !== void 0) {
542
+ const suppressedInheritedFormatting = resolveEffectiveRunStyleFormatting({
543
+ marks,
544
+ paragraphFormatting: suppressParagraphMarkFormatting({
545
+ baseFormatting: options.baseParagraphFormatting,
546
+ directFormatting: authoredFormatting,
547
+ paragraphMarkFormatting: options.paragraphMarkFormatting,
548
+ paragraphMarkPrecedesStyle: options.paragraphMarkPrecedesStyle ?? false
549
+ }),
550
+ ...options.styleResolver !== void 0 ? { styleResolver: options.styleResolver } : {}
551
+ });
552
+ const suppressed = reconcileAuthoredFormatting({
553
+ authoredFormatting,
554
+ carrierlessContext: "paragraph-mark",
555
+ currentOverrideAttrs,
556
+ inheritedFormatting: suppressedInheritedFormatting,
557
+ observedFormatting: formatting
558
+ });
559
+ if (formattingAuthorshipCost(suppressed) < formattingAuthorshipCost(reconciled)) reconciled = suppressed;
560
+ }
561
+ return {
562
+ ...reconciled,
563
+ ...characterStyleId !== void 0 ? { styleId: characterStyleId } : {}
564
+ };
565
+ }
566
+ //#endregion
567
+ export { marksToTextFormatting, sameFormattingValue };
@@ -1,10 +1,9 @@
1
1
  import { mergeTextFormatting } from "../utils/textFormattingMerge.js";
2
2
  import { expectCharacterStyleMarkAttrs } from "./attrs/index.js";
3
- import { marksToTextFormatting } from "./conversion/fromProseDoc.js";
4
3
  import { textFormattingToMarks } from "./extensions/marks/markUtils.js";
4
+ import { marksToTextFormatting } from "./runFormattingFromMarks.js";
5
5
  import { RUN_FORMATTING_MARK_NAMES } from "./runFormattingMarkNames.js";
6
6
  import { getParagraphMarkSuppressionOverrides, hasDirectRunFormatting, paragraphFormattingForRun, resolveEffectiveRunStyleFormatting } from "./runStyleFormatting.js";
7
- import { schema } from "./schema/index.js";
8
7
  import { Mark } from "prosemirror-model";
9
8
  //#region src/prosemirror/runFormattingReconciliation.ts
10
9
  /** Read authored run properties without confusing inherited visuals for direct formatting. */
@@ -33,16 +32,18 @@ const reconcileRunFormattingMarks = ({ authoredFormatting, context, node, styleR
33
32
  context,
34
33
  directFormatting: authoredFormatting
35
34
  });
36
- const formattingMarks = textFormattingToMarks(mergeTextFormatting(resolveEffectiveRunStyleFormatting({
35
+ const effectiveFormatting = mergeTextFormatting(resolveEffectiveRunStyleFormatting({
37
36
  marks: styleResolutionMarks,
38
37
  paragraphFormatting,
39
38
  ...styleResolver !== void 0 ? { styleResolver } : {}
40
- }), authoredFormatting), schema, {
41
- overrideFormatting: mergeTextFormatting(getParagraphMarkSuppressionOverrides({
42
- directFormatting: authoredFormatting,
43
- paragraphMarkFormatting: context.paragraphMarkFormatting,
44
- suppressedFormatting: paragraphFormatting
45
- }), authoredFormatting),
39
+ }), authoredFormatting);
40
+ const overrideFormatting = mergeTextFormatting(getParagraphMarkSuppressionOverrides({
41
+ directFormatting: authoredFormatting,
42
+ paragraphMarkFormatting: context.paragraphMarkFormatting,
43
+ suppressedFormatting: paragraphFormatting
44
+ }), authoredFormatting);
45
+ const formattingMarks = textFormattingToMarks(effectiveFormatting, node.type.schema, {
46
+ overrideFormatting,
46
47
  directFormatting: authoredFormatting
47
48
  });
48
49
  return Mark.setFrom([
@@ -1030,6 +1030,8 @@ type TableAttrs = {
1030
1030
  * Table row attributes
1031
1031
  */
1032
1032
  type TableRowAttrs = {
1033
+ /** Transaction-local cleanup state; cleared before dispatch or continuation capture. */
1034
+ _batchRowCleanup?: "pending" | null;
1033
1035
  /** Row height (in twips) */
1034
1036
  height?: number;
1035
1037
  /** Height rule ('auto', 'exact', 'atLeast') */
@@ -0,0 +1,59 @@
1
+ import { document_d_exports } from "../../types/document.js";
2
+ import { ParagraphAttrs } from "../schema/nodes.js";
3
+ import { TableCellParagraphSpacingOverlay } from "./styleResolver.js";
4
+ import { StyleEngine } from "../../style-engine/styleEngine.js";
5
+ import "../../style-engine/index.js";
6
+ import { TableStyleRegion } from "./tableStyleRegions.js";
7
+ //#region src/prosemirror/styles/paragraphStyleCascade.d.ts
8
+ /** The resolver surface the paragraph cascade reads. */
9
+ type ParagraphCascadeResolver = Pick<StyleEngine, "getStyle" | "getDocDefaults" | "getDefaultParagraphStyle" | "getDefaultCharacterStyle" | "getRunStyleOwnProperties" | "resolveParagraphStyleInTable">;
10
+ /**
11
+ * Resolve an embedded character-style reference without importing
12
+ * `docDefaults`. The caller already has the paragraph cascade, including
13
+ * document defaults, and will layer these own properties over it.
14
+ */
15
+ type ParagraphDefaultFormattingResolver = Pick<StyleEngine, "getStyle" | "getDocDefaults" | "getDefaultParagraphStyle" | "getDefaultCharacterStyle" | "getRunStyleOwnProperties">;
16
+ declare function resolveRunFormattingWithoutDefaults(formatting: document_d_exports.TextFormatting | undefined, styleResolver: ParagraphDefaultFormattingResolver | null): document_d_exports.TextFormatting | undefined;
17
+ /** @internal Recompute a paragraph's inherited run defaults from authored package state. */
18
+ declare function resolveParagraphDefaultTextFormatting(styleId: string | undefined, formatting: document_d_exports.Paragraph["formatting"] | undefined, styleResolver: ParagraphDefaultFormattingResolver, options?: {
19
+ includeParagraphMarkRunProperties?: boolean;
20
+ }): document_d_exports.TextFormatting | undefined;
21
+ type ParagraphStyleCascadeInput = {
22
+ styleId: string | undefined;
23
+ /** What the paragraph states itself; each stated field wins over the cascade. */
24
+ formatting: document_d_exports.ParagraphFormatting | undefined;
25
+ styleResolver: ParagraphCascadeResolver;
26
+ /**
27
+ * The enclosing table style's modeled paragraph fields, layered between
28
+ * docDefaults and the paragraph's own style chain (cell paragraphs only).
29
+ */
30
+ tableParagraphOverlay?: TableCellParagraphSpacingOverlay | undefined;
31
+ /** Whether the paragraph mark's own run properties join the run defaults. */
32
+ includeParagraphMarkRunProperties: boolean;
33
+ };
34
+ type ParagraphStyleCascade = {
35
+ /** The effective attrs, with the provenance a save needs to keep inherited values out of `w:pPr`. */
36
+ attrs: ParagraphAttrs;
37
+ /** The resolved style cascade the attrs were read from. */
38
+ stylePpr: document_d_exports.ParagraphFormatting | undefined;
39
+ };
40
+ /**
41
+ * Project a paragraph's style cascade onto its editor attrs: each field the
42
+ * paragraph states wins, every other field reads the cascade, and the
43
+ * provenance attrs record which is which.
44
+ */
45
+ declare function paragraphStyleCascadeAttrs({ styleId, formatting, styleResolver, tableParagraphOverlay, includeParagraphMarkRunProperties }: ParagraphStyleCascadeInput): ParagraphStyleCascade;
46
+ /**
47
+ * Pick the modeled paragraph fields out of a table style's (or conditional
48
+ * region's) `w:pPr` for use as the cell-paragraph cascade overlay.
49
+ */
50
+ declare function extractTableParagraphOverlay(pPr: document_d_exports.ParagraphFormatting | undefined): TableCellParagraphSpacingOverlay | undefined;
51
+ /**
52
+ * The paragraph overlay a table style gives one cell's paragraphs: its base
53
+ * `w:pPr`, then each applicable region's (`regions`, lowest precedence first,
54
+ * from `tableCellStyleRegions`). A table naming no style, or a style the part
55
+ * does not define, reads the default table style (ECMA-376 §17.7.6).
56
+ */
57
+ declare function tableCellParagraphOverlay(styleResolver: Pick<StyleEngine, "getStyle" | "getDefaultTableStyle">, tableStyleId: string | null | undefined, regions: readonly TableStyleRegion[]): TableCellParagraphSpacingOverlay | undefined;
58
+ //#endregion
59
+ export { ParagraphCascadeResolver, ParagraphStyleCascade, ParagraphStyleCascadeInput, extractTableParagraphOverlay, paragraphStyleCascadeAttrs, resolveParagraphDefaultTextFormatting, resolveRunFormattingWithoutDefaults, tableCellParagraphOverlay };