@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
@@ -1,7 +1,7 @@
1
1
  import { scanDirectives } from "./templateDirectives.js";
2
2
  import { Plugin, PluginKey } from "prosemirror-state";
3
3
  import { Decoration, DecorationSet } from "prosemirror-view";
4
- import { classifyMarker, isFieldPath } from "@stll/template-conditions";
4
+ import { isFieldPath } from "@stll/template-conditions";
5
5
  //#region src/prosemirror/plugins/templatePreviewValues.ts
6
6
  /** Concatenated plain text of a preview value. */
7
7
  const templatePreviewValueText = (value) => typeof value === "string" ? value : value.runs.map((run) => run.text).join("");
@@ -64,28 +64,21 @@ function buildValueWidget(value, mode) {
64
64
  return span;
65
65
  };
66
66
  }
67
- /** Loop alias the bare-path probe binds. Any identifier does; it is discarded. */
68
- const CHAIN_PROBE_ALIAS = "__folioCondition";
69
67
  /** A field path opens with a letter or underscore, so `9x` and `-x` are not one. */
70
68
  const FIELD_PATH_HEAD_RE = /^[\p{L}_]/u;
71
69
  /**
72
70
  * The bare field path a condition's filter chain hangs off, or undefined when
73
- * the expression is not a path plus a chain.
71
+ * the tag is not a path plus a chain.
74
72
  *
75
- * A host may write the tag the way `{% for x in xs | chain %}` already carries
76
- * one — `{% if buyer_is_a_consumer | checkbox | ai("Is the buyer …") %}` — while
77
- * keying `conditions` by the bare path. Splitting on `|` would cut a quoted
78
- * argument such as `label("a | b")` in half, so the expression is classified as
79
- * that very `for` chain instead and the grammar's own argument-aware scan
80
- * reports the path. An expression that is not a path plus a chain of known
81
- * filters (`a and b`, `items|length > 0`, `ai("a|b")`) classifies as nothing,
82
- * which is what keeps a real expression on exact matching.
73
+ * A host may write the tag with the chain of the boolean it names —
74
+ * `{% if buyer_is_a_consumer | checkbox | ai("Is the buyer …") %}` — while
75
+ * keying `conditions` by the bare path. The grammar's argument-aware scan
76
+ * splits the chain (`label("a | b")` stays one argument) and reports the path
77
+ * as `conditionPath`; an expression that is not a path plus a chain of known
78
+ * filters (`a and b`, `items|length > 0`, `ai("a|b")`) has none, which is what
79
+ * keeps a real expression on exact matching.
83
80
  */
84
- const filterChainPath = (expr) => {
85
- const meta = classifyMarker(`for ${CHAIN_PROBE_ALIAS} in ${expr}`, "statement");
86
- if (meta?.kind !== "for" || !isFieldPath(meta.path) || !FIELD_PATH_HEAD_RE.test(meta.path)) return;
87
- return meta.path;
88
- };
81
+ const filterChainPath = ({ conditionPath }) => conditionPath !== void 0 && isFieldPath(conditionPath) && FIELD_PATH_HEAD_RE.test(conditionPath) ? conditionPath : void 0;
89
82
  /**
90
83
  * The verdict stored under one key. Only a key the host set itself, holding a
91
84
  * real boolean, counts: an inherited property (`constructor`, or a boolean the
@@ -102,10 +95,10 @@ const ownVerdict = (conditions, key) => {
102
95
  * by the bare path its filter chain hangs off. `undefined` means the host said
103
96
  * nothing about this block, which leaves it exactly as authored.
104
97
  */
105
- const conditionVerdict = (conditions, expr) => {
106
- const exact = ownVerdict(conditions, expr);
98
+ const conditionVerdict = (conditions, opener) => {
99
+ const exact = ownVerdict(conditions, opener.expr);
107
100
  if (exact !== void 0) return exact;
108
- const path = filterChainPath(expr);
101
+ const path = filterChainPath(opener);
109
102
  return path === void 0 ? void 0 : ownVerdict(conditions, path);
110
103
  };
111
104
  /**
@@ -157,7 +150,7 @@ function collectHiddenRanges(ranges, conditions, mode) {
157
150
  }
158
151
  if (block === void 0 || block.opener.kind !== "if") continue;
159
152
  const { opener, branches } = block;
160
- const verdict = conditionVerdict(conditions, opener.expr);
153
+ const verdict = conditionVerdict(conditions, opener);
161
154
  if (verdict === void 0) continue;
162
155
  if (!verdict) {
163
156
  paired.push({
@@ -1,6 +1,7 @@
1
- import { RunStyleResolver } from "./runStyleFormatting.js";
1
+ import { ParagraphRunStyleContext, RunStyleResolver } from "./runStyleFormatting.js";
2
2
  import { Node } from "prosemirror-model";
3
3
  import { Transaction } from "prosemirror-state";
4
+ import { Transform } from "prosemirror-transform";
4
5
  //#region src/prosemirror/rebaseParagraphRunFormatting.d.ts
5
6
  type RebaseParagraphRunFormattingOptions = {
6
7
  nextAttrs: Record<string, unknown>;
@@ -9,10 +10,29 @@ type RebaseParagraphRunFormattingOptions = {
9
10
  styleResolver: RunStyleResolver;
10
11
  tr: Transaction;
11
12
  };
13
+ type RebaseParagraphRunsOptions<T extends Transform> = {
14
+ /** The style context the runs' marks were resolved in. */
15
+ previousContext: ParagraphRunStyleContext;
16
+ paragraphPosition: number;
17
+ /** Content offsets inside the paragraph to rebase; all of it when omitted. */
18
+ range?: {
19
+ from: number;
20
+ to: number;
21
+ };
22
+ shouldRebase?: (node: Node) => boolean;
23
+ styleResolver: RunStyleResolver;
24
+ tr: T;
25
+ };
26
+ /**
27
+ * Re-resolve the inherited marks of runs resolved in `previousContext` in the
28
+ * paragraph's current style context: direct formatting stays direct, and what
29
+ * the old context lent the runs goes with it.
30
+ */
31
+ declare const rebaseParagraphRuns: <T extends Transform>({ previousContext, paragraphPosition, range, shouldRebase, styleResolver, tr }: RebaseParagraphRunsOptions<T>) => T;
12
32
  /**
13
33
  * Change paragraph attrs and re-resolve inherited run marks in the new style
14
34
  * context without turning the old rendered style into direct run formatting.
15
35
  */
16
36
  declare const setParagraphAttrsWithRebasedRunFormatting: ({ nextAttrs, paragraphPosition, shouldRebase, styleResolver, tr }: RebaseParagraphRunFormattingOptions) => Transaction;
17
37
  //#endregion
18
- export { setParagraphAttrsWithRebasedRunFormatting };
38
+ export { rebaseParagraphRuns, setParagraphAttrsWithRebasedRunFormatting };
@@ -1,3 +1,4 @@
1
+ import { sameRunStyleContext } from "./rebaseParagraphRuns.js";
1
2
  import { expandRunFormattingCarrier } from "./runFormattingInlineCarriers.js";
2
3
  import { RUN_FORMATTING_MARK_NAMES } from "./runFormattingMarkNames.js";
3
4
  import { readAuthoredRunFormatting, reconcileRunFormattingMarks } from "./runFormattingReconciliation.js";
@@ -5,18 +6,23 @@ import { paragraphRunStyleContext } from "./runStyleFormatting.js";
5
6
  import { panic } from "better-result";
6
7
  import { Mark } from "prosemirror-model";
7
8
  //#region src/prosemirror/rebaseParagraphRunFormatting.ts
8
- /**
9
- * Change paragraph attrs and re-resolve inherited run marks in the new style
10
- * context without turning the old rendered style into direct run formatting.
11
- */
12
- const setParagraphAttrsWithRebasedRunFormatting = ({ nextAttrs, paragraphPosition, shouldRebase, styleResolver, tr }) => {
9
+ const paragraphAt = (tr, paragraphPosition) => {
13
10
  const paragraph = tr.doc.nodeAt(paragraphPosition);
14
11
  if (!paragraph || paragraph.type.name !== "paragraph") return panic("Cannot rebase run formatting outside a paragraph", {
15
12
  nodeType: paragraph?.type.name,
16
13
  paragraphPosition
17
14
  });
18
- const previousContext = paragraphRunStyleContext(paragraph, styleResolver);
19
- const nextContext = paragraphRunStyleContext(paragraph.type.create(nextAttrs, paragraph.content, paragraph.marks), styleResolver);
15
+ return paragraph;
16
+ };
17
+ /**
18
+ * Re-resolve the inherited marks of runs resolved in `previousContext` in the
19
+ * paragraph's current style context: direct formatting stays direct, and what
20
+ * the old context lent the runs goes with it.
21
+ */
22
+ const rebaseParagraphRuns = ({ previousContext, paragraphPosition, range, shouldRebase, styleResolver, tr }) => {
23
+ const paragraph = paragraphAt(tr, paragraphPosition);
24
+ const nextContext = paragraphRunStyleContext(paragraph, styleResolver);
25
+ if (sameRunStyleContext(previousContext, nextContext)) return tr;
20
26
  const changes = [];
21
27
  const collectRebasedRepresentation = ({ node, position }) => {
22
28
  if (shouldRebase && !shouldRebase(node)) return;
@@ -31,23 +37,28 @@ const setParagraphAttrsWithRebasedRunFormatting = ({ nextAttrs, paragraphPositio
31
37
  styleResolver
32
38
  });
33
39
  if (Mark.sameSet(node.marks, nextMarks)) return;
40
+ const start = paragraphPosition + 1;
41
+ const from = node.isText && range ? Math.max(position, start + range.from) : position;
42
+ const to = node.isText && range ? Math.min(position + node.nodeSize, start + range.to) : position + node.nodeSize;
43
+ if (to <= from) return;
34
44
  changes.push({
35
45
  attrs: node.attrs,
36
46
  currentFormattingMarks: node.marks.filter(({ type }) => RUN_FORMATTING_MARK_NAMES.has(type.name)),
37
- from: position,
47
+ from,
38
48
  isText: node.isText,
39
49
  marks: nextMarks,
40
- to: position + node.nodeSize
50
+ to
41
51
  });
42
52
  };
43
- paragraph.descendants((node, relativePosition) => {
53
+ const visit = (node, relativePosition) => {
44
54
  if (!node.isInline) return true;
45
55
  const carrier = expandRunFormattingCarrier(node, paragraphPosition + 1 + relativePosition);
46
56
  if (!carrier) return !node.isAtom;
47
57
  for (const representation of carrier.representations) collectRebasedRepresentation(representation);
48
58
  return false;
49
- });
50
- tr = tr.setNodeMarkup(paragraphPosition, void 0, nextAttrs);
59
+ };
60
+ if (range === void 0) paragraph.descendants(visit);
61
+ else paragraph.nodesBetween(range.from, range.to, visit);
51
62
  for (const { attrs, currentFormattingMarks, from, isText, marks, to } of changes) {
52
63
  if (!isText) {
53
64
  tr = tr.setNodeMarkup(from, void 0, attrs, marks);
@@ -58,5 +69,20 @@ const setParagraphAttrsWithRebasedRunFormatting = ({ nextAttrs, paragraphPositio
58
69
  }
59
70
  return tr;
60
71
  };
72
+ /**
73
+ * Change paragraph attrs and re-resolve inherited run marks in the new style
74
+ * context without turning the old rendered style into direct run formatting.
75
+ */
76
+ const setParagraphAttrsWithRebasedRunFormatting = ({ nextAttrs, paragraphPosition, shouldRebase, styleResolver, tr }) => {
77
+ const previousContext = paragraphRunStyleContext(paragraphAt(tr, paragraphPosition), styleResolver);
78
+ tr = tr.setNodeMarkup(paragraphPosition, void 0, nextAttrs);
79
+ return rebaseParagraphRuns({
80
+ previousContext,
81
+ paragraphPosition,
82
+ ...shouldRebase ? { shouldRebase } : {},
83
+ styleResolver,
84
+ tr
85
+ });
86
+ };
61
87
  //#endregion
62
- export { setParagraphAttrsWithRebasedRunFormatting };
88
+ export { rebaseParagraphRuns, setParagraphAttrsWithRebasedRunFormatting };
@@ -0,0 +1,36 @@
1
+ import { ParagraphRunStyleContext, RunStyleResolver } from "./runStyleFormatting.js";
2
+ import { Fragment, Mark, Node } from "prosemirror-model";
3
+ import { Transaction } from "prosemirror-state";
4
+ //#region src/prosemirror/rebaseParagraphRuns.d.ts
5
+ /** Two contexts that lend runs the same formatting: rebasing between them changes nothing. */
6
+ declare const sameRunStyleContext: (source: ParagraphRunStyleContext, target: ParagraphRunStyleContext) => boolean;
7
+ type RebaseParagraphRunsOptions = {
8
+ tr: Transaction;
9
+ position: number;
10
+ previous: Node;
11
+ target?: Node;
12
+ styleResolver: RunStyleResolver | null;
13
+ range?: {
14
+ from: number;
15
+ to: number;
16
+ };
17
+ storedMarks?: readonly Mark[] | null;
18
+ };
19
+ /** Rebuild rendered marks after the paragraph's style cascade changes. */
20
+ declare const rebaseParagraphRuns: ({ tr, position, previous, target, styleResolver, range, storedMarks: initialStoredMarks }: RebaseParagraphRunsOptions) => Transaction;
21
+ type RebasedRunFormatting = {
22
+ before: Node;
23
+ after: Node;
24
+ position: number;
25
+ };
26
+ type RebaseParagraphRunContentOptions = {
27
+ paragraph: Node;
28
+ target: Node;
29
+ position: number;
30
+ styleResolver: RunStyleResolver | null;
31
+ onRebased: (resolution: RebasedRunFormatting) => void;
32
+ };
33
+ /** Rebase an immutable paragraph chunk once, before assembling a resolved join chain. */
34
+ declare const rebaseParagraphRunContent: ({ paragraph, target, position, styleResolver, onRebased }: RebaseParagraphRunContentOptions) => Fragment;
35
+ //#endregion
36
+ export { rebaseParagraphRunContent, rebaseParagraphRuns, sameRunStyleContext };
@@ -0,0 +1,99 @@
1
+ import { recreateProseNodeWithParagraphPropertySource } from "../docx/paragraphPropertySource.js";
2
+ import { formattingEquals } from "../docx/runConsolidator.js";
3
+ import { applyMarksToRunFormattingRepresentation, selectRunFormattingCarrierRepresentations } from "./runFormattingInlineCarriers.js";
4
+ import { readAuthoredRunFormatting, reconcileRunFormattingMarks } from "./runFormattingReconciliation.js";
5
+ import { paragraphRunStyleContext } from "./runStyleFormatting.js";
6
+ import { Mark } from "prosemirror-model";
7
+ //#region src/prosemirror/rebaseParagraphRuns.ts
8
+ /** Two contexts that lend runs the same formatting: rebasing between them changes nothing. */
9
+ const sameRunStyleContext = (source, target) => source.paragraphMarkPrecedesStyle === target.paragraphMarkPrecedesStyle && formattingEquals(source.baseParagraphFormatting, target.baseParagraphFormatting) && formattingEquals(source.paragraphFormatting, target.paragraphFormatting) && formattingEquals(source.paragraphMarkFormatting, target.paragraphMarkFormatting);
10
+ /** Rebuild rendered marks after the paragraph's style cascade changes. */
11
+ const rebaseParagraphRuns = ({ tr, position, previous, target, styleResolver, range, storedMarks: initialStoredMarks }) => {
12
+ const paragraph = tr.doc.nodeAt(position);
13
+ if (!paragraph) return tr;
14
+ const storedMarks = initialStoredMarks ?? tr.storedMarks ?? tr.selection.$from.marks();
15
+ const sourceContext = paragraphRunStyleContext(previous, styleResolver);
16
+ const targetContext = paragraphRunStyleContext(target ?? paragraph, styleResolver);
17
+ const sameCascade = sameRunStyleContext(sourceContext, targetContext);
18
+ const representations = sameCascade ? [] : selectRunFormattingCarrierRepresentations({
19
+ doc: tr.doc,
20
+ from: range?.from ?? position + 1,
21
+ to: range?.to ?? position + paragraph.nodeSize - 1
22
+ });
23
+ for (const representation of representations) applyMarksToRunFormattingRepresentation({
24
+ tr,
25
+ representation,
26
+ marks: reconcileRunFormattingMarks({
27
+ authoredFormatting: readAuthoredRunFormatting({
28
+ context: sourceContext,
29
+ marks: representation.node.marks,
30
+ styleResolver
31
+ }),
32
+ context: targetContext,
33
+ node: representation.node,
34
+ styleResolver
35
+ })
36
+ });
37
+ if (target === void 0 && range === void 0 && tr.selection.empty && tr.selection.from > position && tr.selection.from < position + paragraph.nodeSize) {
38
+ const node = paragraph.type.schema.text(" ", storedMarks);
39
+ tr.setStoredMarks(sameCascade ? storedMarks : reconcileRunFormattingMarks({
40
+ authoredFormatting: readAuthoredRunFormatting({
41
+ context: sourceContext,
42
+ marks: node.marks,
43
+ styleResolver
44
+ }),
45
+ context: targetContext,
46
+ node,
47
+ styleResolver
48
+ }));
49
+ }
50
+ return tr;
51
+ };
52
+ /** Rebase an immutable paragraph chunk once, before assembling a resolved join chain. */
53
+ const rebaseParagraphRunContent = ({ paragraph, target, position, styleResolver, onRebased }) => {
54
+ const sourceContext = paragraphRunStyleContext(paragraph, styleResolver);
55
+ const targetContext = paragraphRunStyleContext(target, styleResolver);
56
+ if (sameRunStyleContext(sourceContext, targetContext)) return paragraph.content;
57
+ const replacements = /* @__PURE__ */ new Map();
58
+ const representations = selectRunFormattingCarrierRepresentations({
59
+ doc: paragraph,
60
+ from: 0,
61
+ to: paragraph.content.size
62
+ });
63
+ for (const representation of representations) {
64
+ const marks = reconcileRunFormattingMarks({
65
+ authoredFormatting: readAuthoredRunFormatting({
66
+ context: sourceContext,
67
+ marks: representation.node.marks,
68
+ styleResolver
69
+ }),
70
+ context: targetContext,
71
+ node: representation.node,
72
+ styleResolver
73
+ });
74
+ if (Mark.sameSet(marks, representation.node.marks)) continue;
75
+ const rebased = representation.node.mark(marks);
76
+ replacements.set(representation.node, rebased);
77
+ onRebased({
78
+ before: representation.node,
79
+ after: rebased,
80
+ position: position + 1 + representation.position
81
+ });
82
+ }
83
+ if (replacements.size === 0) return paragraph.content;
84
+ const rebuild = (node) => {
85
+ const replacement = replacements.get(node) ?? node;
86
+ if (node.isLeaf) return replacement;
87
+ const children = [];
88
+ let changed = false;
89
+ replacement.forEach((child) => {
90
+ const next = rebuild(child);
91
+ children.push(next);
92
+ changed ||= next !== child;
93
+ });
94
+ return changed ? recreateProseNodeWithParagraphPropertySource(replacement, { content: children }) : replacement;
95
+ };
96
+ return rebuild(paragraph).content;
97
+ };
98
+ //#endregion
99
+ export { rebaseParagraphRunContent, rebaseParagraphRuns, sameRunStyleContext };
@@ -0,0 +1,18 @@
1
+ import { document_d_exports } from "../types/document.js";
2
+ import { RunStyleResolver } from "./runStyleFormatting.js";
3
+ import { Mark } from "prosemirror-model";
4
+ //#region src/prosemirror/runFormattingFromMarks.d.ts
5
+ /**
6
+ * Convert ProseMirror marks to TextFormatting
7
+ */
8
+ type MarksToTextFormattingOptions = {
9
+ baseParagraphFormatting?: document_d_exports.TextFormatting | undefined;
10
+ inheritedFormatting?: document_d_exports.TextFormatting | undefined;
11
+ paragraphMarkFormatting?: document_d_exports.TextFormatting | undefined;
12
+ paragraphMarkPrecedesStyle?: boolean | undefined;
13
+ styleResolver?: RunStyleResolver | null | undefined;
14
+ };
15
+ declare const sameFormattingValue: (left: unknown, right: unknown) => boolean;
16
+ declare function marksToTextFormatting(marks: readonly Mark[], options?: MarksToTextFormattingOptions): document_d_exports.TextFormatting;
17
+ //#endregion
18
+ export { MarksToTextFormattingOptions, marksToTextFormatting, sameFormattingValue };