@stll/folio-core 0.53.0 → 0.54.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 (148) hide show
  1. package/dist/ai-edits/apply.js +390 -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 +3 -1
  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/fonts/embeddedFonts.js +1 -1
  41. package/dist/i18n/messages/catalogs.gen.d.ts +34 -34
  42. package/dist/i18n/messages/catalogs.gen.js +34 -34
  43. package/dist/i18n/messages/messages.gen.d.ts +2 -2
  44. package/dist/internal/wholeStoryRevisionResolution.js +95 -25
  45. package/dist/layout-engine/measure/measureParagraph.js +2 -2
  46. package/dist/layout-engine/measure/paragraphMeasureShared.d.ts +12 -1
  47. package/dist/layout-engine/measure/paragraphMeasureShared.js +14 -1
  48. package/dist/markdown/escape.d.ts +2 -2
  49. package/dist/markdown/escape.js +4 -5
  50. package/dist/markdown/renderBlock.js +91 -25
  51. package/dist/markdown/renderRuns.d.ts +10 -1
  52. package/dist/markdown/renderRuns.js +320 -59
  53. package/dist/prosemirror/clearRunColor.d.ts +6 -0
  54. package/dist/prosemirror/clearRunColor.js +46 -0
  55. package/dist/prosemirror/commands/comments.js +56 -21
  56. package/dist/prosemirror/commands/formatPainter.js +1 -1
  57. package/dist/prosemirror/commands/hyperlink.js +2 -1
  58. package/dist/prosemirror/commands/propertyChangeScope.d.ts +3 -2
  59. package/dist/prosemirror/commands/propertyChangeScope.js +24 -3
  60. package/dist/prosemirror/commands/resolveAllTableChanges.js +46 -41
  61. package/dist/prosemirror/commands/resolveParagraphProperties.js +20 -6
  62. package/dist/prosemirror/commands/tableCellMergeResolution.d.ts +8 -1
  63. package/dist/prosemirror/commands/tableCellMergeResolution.js +23 -7
  64. package/dist/prosemirror/containerFinalParagraph.d.ts +11 -5
  65. package/dist/prosemirror/containerFinalParagraph.js +7 -6
  66. package/dist/prosemirror/conversion/fromProseDoc.d.ts +2 -13
  67. package/dist/prosemirror/conversion/fromProseDoc.js +12 -590
  68. package/dist/prosemirror/conversion/toProseDoc.d.ts +4 -11
  69. package/dist/prosemirror/conversion/toProseDoc.js +31 -150
  70. package/dist/prosemirror/documentSchema.d.ts +8 -0
  71. package/dist/prosemirror/documentSchema.js +18 -0
  72. package/dist/prosemirror/extensions/StarterKit.js +2 -0
  73. package/dist/prosemirror/extensions/core/ParagraphExtension.js +104 -63
  74. package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +1 -1
  75. package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.js +24 -3
  76. package/dist/prosemirror/extensions/features/JoinedRunStyleExtension.d.ts +20 -0
  77. package/dist/prosemirror/extensions/features/JoinedRunStyleExtension.js +43 -0
  78. package/dist/prosemirror/extensions/features/ListExtension.js +10 -9
  79. package/dist/prosemirror/extensions/features/pastedHeadingStyles.js +1 -1
  80. package/dist/prosemirror/extensions/features/pastedHtmlLists.js +2 -4
  81. package/dist/prosemirror/extensions/marks/FootnoteRefExtension.js +14 -8
  82. package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +8 -4
  83. package/dist/prosemirror/extensions/marks/StrikeExtension.js +2 -2
  84. package/dist/prosemirror/extensions/marks/SubscriptExtension.js +2 -2
  85. package/dist/prosemirror/extensions/marks/SuperscriptExtension.js +2 -2
  86. package/dist/prosemirror/extensions/marks/TextColorExtension.js +4 -3
  87. package/dist/prosemirror/extensions/marks/markUtils.d.ts +8 -6
  88. package/dist/prosemirror/extensions/marks/markUtils.js +17 -8
  89. package/dist/prosemirror/extensions/marks/noteReferenceDeletion.d.ts +3 -1
  90. package/dist/prosemirror/extensions/marks/noteReferenceDeletion.js +12 -1
  91. package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +2 -2
  92. package/dist/prosemirror/extensions/nodes/HardBreakExtension.js +5 -3
  93. package/dist/prosemirror/extensions/nodes/TableExtension.js +104 -210
  94. package/dist/prosemirror/extensions/types.d.ts +7 -0
  95. package/dist/prosemirror/hyperlinkRemoval.d.ts +9 -0
  96. package/dist/prosemirror/hyperlinkRemoval.js +129 -0
  97. package/dist/prosemirror/index.d.ts +2 -1
  98. package/dist/prosemirror/index.js +2 -1
  99. package/dist/prosemirror/listNumbering.d.ts +3 -21
  100. package/dist/prosemirror/listNumbering.js +10 -25
  101. package/dist/prosemirror/listRendering.d.ts +27 -0
  102. package/dist/prosemirror/listRendering.js +27 -0
  103. package/dist/prosemirror/markupViewNotes.d.ts +8 -0
  104. package/dist/prosemirror/markupViewNotes.js +49 -0
  105. package/dist/prosemirror/markupViewProjection.d.ts +3 -1
  106. package/dist/prosemirror/markupViewProjection.js +7 -2
  107. package/dist/prosemirror/noteReferenceReview.d.ts +77 -0
  108. package/dist/prosemirror/noteReferenceReview.js +332 -0
  109. package/dist/prosemirror/paragraphIndentation.js +5 -2
  110. package/dist/prosemirror/paragraphMarkJoin.d.ts +6 -4
  111. package/dist/prosemirror/paragraphMarkJoin.js +21 -19
  112. package/dist/prosemirror/paragraphPropertyCarry.d.ts +64 -0
  113. package/dist/prosemirror/paragraphPropertyCarry.js +158 -0
  114. package/dist/prosemirror/plugins/documentStyleState.d.ts +26 -0
  115. package/dist/prosemirror/plugins/documentStyleState.js +32 -0
  116. package/dist/prosemirror/plugins/documentStyles.d.ts +2 -21
  117. package/dist/prosemirror/plugins/documentStyles.js +66 -29
  118. package/dist/prosemirror/plugins/index.d.ts +2 -1
  119. package/dist/prosemirror/plugins/index.js +2 -1
  120. package/dist/prosemirror/plugins/paragraphStyleResolution.d.ts +15 -0
  121. package/dist/prosemirror/plugins/paragraphStyleResolution.js +230 -0
  122. package/dist/prosemirror/plugins/suggestionMode.d.ts +12 -2
  123. package/dist/prosemirror/plugins/suggestionMode.js +391 -28
  124. package/dist/prosemirror/rebaseParagraphRunFormatting.d.ts +22 -2
  125. package/dist/prosemirror/rebaseParagraphRunFormatting.js +39 -13
  126. package/dist/prosemirror/rebaseParagraphRuns.d.ts +36 -0
  127. package/dist/prosemirror/rebaseParagraphRuns.js +99 -0
  128. package/dist/prosemirror/runFormattingFromMarks.d.ts +18 -0
  129. package/dist/prosemirror/runFormattingFromMarks.js +567 -0
  130. package/dist/prosemirror/runFormattingReconciliation.js +10 -9
  131. package/dist/prosemirror/schema/nodes.d.ts +2 -0
  132. package/dist/prosemirror/styles/paragraphStyleCascade.d.ts +59 -0
  133. package/dist/prosemirror/styles/paragraphStyleCascade.js +145 -0
  134. package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +21 -2
  135. package/dist/prosemirror/styles/resolvedStyleAttrs.js +38 -1
  136. package/dist/prosemirror/styles/tableStyleRegions.d.ts +31 -0
  137. package/dist/prosemirror/styles/tableStyleRegions.js +55 -0
  138. package/dist/prosemirror/tableCellPaste.d.ts +74 -0
  139. package/dist/prosemirror/tableCellPaste.js +525 -0
  140. package/dist/prosemirror/tableGridMutation.d.ts +53 -14
  141. package/dist/prosemirror/tableGridMutation.js +166 -18
  142. package/dist/prosemirror/tableRunIn.d.ts +51 -0
  143. package/dist/prosemirror/tableRunIn.js +165 -0
  144. package/dist/prosemirror/textInput.js +11 -2
  145. package/dist/prosemirror/trackedRevisionPath.d.ts +17 -0
  146. package/dist/prosemirror/trackedRevisionPath.js +32 -0
  147. package/dist/server.d.ts +2 -2
  148. package/package.json +5 -5
@@ -0,0 +1,26 @@
1
+ import { document_d_exports } from "../../types/document.js";
2
+ import { BuiltInStyleIndex } from "../../docx/builtInStyles.js";
3
+ import { StyleResolver } from "../styles/styleResolver.js";
4
+ import { EditorState, PluginKey } from "prosemirror-state";
5
+ //#region src/prosemirror/plugins/documentStyleState.d.ts
6
+ declare const documentStylesKey: PluginKey<StyleResolver | null>;
7
+ /** Read the document's StyleResolver, or null when the plugin isn't installed. */
8
+ declare function getDocumentStyleResolver(state: EditorState): StyleResolver | null;
9
+ /**
10
+ * The document's style definitions by id, or `null` when the state carries no
11
+ * styles plugin and so cannot say what the document defines. A document
12
+ * without a styles part defines none.
13
+ */
14
+ declare function getDocumentStyleDefinitions(state: EditorState): {
15
+ get: (styleId: string) => document_d_exports.Style | undefined;
16
+ paragraphStyles: () => document_d_exports.Style[];
17
+ } | null;
18
+ /**
19
+ * Read the document's built-in style index, for the callers that classify
20
+ * paragraphs (heading collection, markdown export, the AI snapshot). Without
21
+ * the plugin every lookup misses, which degrades classification to the
22
+ * paragraph's own outline level rather than to English style ids.
23
+ */
24
+ declare function getDocumentBuiltInStyles(state: EditorState): BuiltInStyleIndex;
25
+ //#endregion
26
+ export { documentStylesKey, getDocumentBuiltInStyles, getDocumentStyleDefinitions, getDocumentStyleResolver };
@@ -0,0 +1,32 @@
1
+ import { EMPTY_BUILT_IN_STYLE_INDEX } from "../../docx/builtInStyles.js";
2
+ import { PluginKey } from "prosemirror-state";
3
+ //#region src/prosemirror/plugins/documentStyleState.ts
4
+ const documentStylesKey = new PluginKey("documentStyles");
5
+ /** Read the document's StyleResolver, or null when the plugin isn't installed. */
6
+ function getDocumentStyleResolver(state) {
7
+ return documentStylesKey.getState(state) ?? null;
8
+ }
9
+ /**
10
+ * The document's style definitions by id, or `null` when the state carries no
11
+ * styles plugin and so cannot say what the document defines. A document
12
+ * without a styles part defines none.
13
+ */
14
+ function getDocumentStyleDefinitions(state) {
15
+ if (documentStylesKey.get(state) === void 0) return null;
16
+ const resolver = getDocumentStyleResolver(state);
17
+ return {
18
+ get: (styleId) => resolver?.getStyle(styleId),
19
+ paragraphStyles: () => resolver?.getParagraphStyles() ?? []
20
+ };
21
+ }
22
+ /**
23
+ * Read the document's built-in style index, for the callers that classify
24
+ * paragraphs (heading collection, markdown export, the AI snapshot). Without
25
+ * the plugin every lookup misses, which degrades classification to the
26
+ * paragraph's own outline level rather than to English style ids.
27
+ */
28
+ function getDocumentBuiltInStyles(state) {
29
+ return getDocumentStyleResolver(state)?.builtInStyles ?? EMPTY_BUILT_IN_STYLE_INDEX;
30
+ }
31
+ //#endregion
32
+ export { documentStylesKey, getDocumentBuiltInStyles, getDocumentStyleDefinitions, getDocumentStyleResolver };
@@ -1,9 +1,8 @@
1
1
  import { document_d_exports } from "../../types/document.js";
2
- import { BuiltInStyleIndex } from "../../docx/builtInStyles.js";
3
2
  import { StyleResolver } from "../styles/styleResolver.js";
4
- import { EditorState, Plugin, PluginKey } from "prosemirror-state";
3
+ import { documentStylesKey, getDocumentBuiltInStyles, getDocumentStyleDefinitions, getDocumentStyleResolver } from "./documentStyleState.js";
4
+ import { EditorState, Plugin } from "prosemirror-state";
5
5
  //#region src/prosemirror/plugins/documentStyles.d.ts
6
- declare const documentStylesKey: PluginKey<StyleResolver | null>;
7
6
  /**
8
7
  * Create the plugin holding a StyleResolver for the document's `styles` for
9
8
  * the lifetime of the EditorState. The resolver is fixed per document load;
@@ -12,24 +11,6 @@ declare const documentStylesKey: PluginKey<StyleResolver | null>;
12
11
  * have one.
13
12
  */
14
13
  declare function createDocumentStylesPlugin(styles: document_d_exports.StyleDefinitions | StyleResolver | null | undefined): Plugin;
15
- /** Read the document's StyleResolver, or null when the plugin isn't installed. */
16
- declare function getDocumentStyleResolver(state: EditorState): StyleResolver | null;
17
- /**
18
- * The document's style definitions by id, or `null` when the state carries no
19
- * styles plugin and so cannot say what the document defines. A document
20
- * without a styles part defines none.
21
- */
22
- declare function getDocumentStyleDefinitions(state: EditorState): {
23
- get: (styleId: string) => document_d_exports.Style | undefined;
24
- paragraphStyles: () => document_d_exports.Style[];
25
- } | null;
26
- /**
27
- * Read the document's built-in style index, for the callers that classify
28
- * paragraphs (heading collection, markdown export, the AI snapshot). Without
29
- * the plugin every lookup misses, which degrades classification to the
30
- * paragraph's own outline level rather than to English style ids.
31
- */
32
- declare function getDocumentBuiltInStyles(state: EditorState): BuiltInStyleIndex;
33
14
  /** Reconfigure so ProseMirror replaces the keyed plugin's resolver state. */
34
15
  declare const withDocumentStyles: (state: EditorState, styles: document_d_exports.StyleDefinitions | StyleResolver | null | undefined) => EditorState;
35
16
  //#endregion
@@ -1,6 +1,13 @@
1
- import { EMPTY_BUILT_IN_STYLE_INDEX } from "../../docx/builtInStyles.js";
1
+ import "../extensions/features/JoinedRunStyleExtension.js";
2
+ import { rebaseParagraphRuns } from "../rebaseParagraphRuns.js";
2
3
  import { StyleResolver, createStyleResolver } from "../styles/styleResolver.js";
3
- import { Plugin, PluginKey } from "prosemirror-state";
4
+ import { getDocumentNumbering } from "./documentNumbering.js";
5
+ import { documentStylesKey, getDocumentBuiltInStyles, getDocumentStyleDefinitions, getDocumentStyleResolver } from "./documentStyleState.js";
6
+ import { resolveEditedParagraphStyles } from "./paragraphStyleResolution.js";
7
+ import { Mark } from "prosemirror-model";
8
+ import { Mapping, ReplaceStep } from "prosemirror-transform";
9
+ import { Plugin } from "prosemirror-state";
10
+ import { isHistoryTransaction } from "prosemirror-history";
4
11
  //#region src/prosemirror/plugins/documentStyles.ts
5
12
  /**
6
13
  * documentStyles plugin — makes the document's StyleResolver reachable from
@@ -18,7 +25,57 @@ import { Plugin, PluginKey } from "prosemirror-state";
18
25
  * EditorState. When absent, style-aware commands fall back to their
19
26
  * style-agnostic behavior.
20
27
  */
21
- const documentStylesKey = new PluginKey("documentStyles");
28
+ /** Rebase surviving right-hand runs when ordinary replacement steps consume a paragraph opening. */
29
+ const rebaseEditedParagraphJoins = (transactions, tr, resolver) => {
30
+ const maps = transactions.flatMap((transaction) => transaction.mapping.maps);
31
+ let offset = 0;
32
+ for (const transaction of transactions) {
33
+ if (isHistoryTransaction(transaction) || transaction.getMeta("joinedRunsRestyled") === true || !transaction.steps.every((step) => step instanceof ReplaceStep)) {
34
+ offset += transaction.steps.length;
35
+ continue;
36
+ }
37
+ for (const [index, step] of transaction.steps.entries()) {
38
+ const before = transaction.docs[index];
39
+ if (!before) continue;
40
+ const map = step.getMap();
41
+ const mapping = new Mapping([map, ...new Mapping(maps.slice(offset + index + 1)).maps]);
42
+ map.forEach((oldFrom, oldTo) => {
43
+ before.nodesBetween(oldFrom, oldTo, (paragraph, position) => {
44
+ if (paragraph.type.name !== "paragraph") return true;
45
+ if (!map.mapResult(position, 1).deleted) return false;
46
+ const from = mapping.map(position + 1, 1);
47
+ const to = mapping.map(position + paragraph.nodeSize - 1, -1);
48
+ if (from >= to) return false;
49
+ const at = tr.doc.resolve(from);
50
+ if (at.parent.type.name !== "paragraph") return false;
51
+ const targetPosition = at.start() - 1;
52
+ if (targetPosition === mapping.map(position, 1)) return false;
53
+ const surviving = tr.doc.nodeAt(from);
54
+ const original = before.nodeAt(mapping.invert().map(from, 1));
55
+ if (!surviving || !original || !Mark.sameSet(surviving.marks, original.marks)) return false;
56
+ rebaseParagraphRuns({
57
+ tr,
58
+ position: targetPosition,
59
+ previous: paragraph,
60
+ styleResolver: resolver,
61
+ range: {
62
+ from,
63
+ to
64
+ }
65
+ });
66
+ return false;
67
+ });
68
+ });
69
+ }
70
+ offset += transaction.steps.length;
71
+ }
72
+ };
73
+ let bareStyleResolver;
74
+ /** The cascade of a package that defines no styles: docDefaults-free built-ins. */
75
+ const bareResolver = () => {
76
+ bareStyleResolver ??= createStyleResolver(void 0);
77
+ return bareStyleResolver;
78
+ };
22
79
  /**
23
80
  * Create the plugin holding a StyleResolver for the document's `styles` for
24
81
  * the lifetime of the EditorState. The resolver is fixed per document load;
@@ -36,35 +93,15 @@ function createDocumentStylesPlugin(styles) {
36
93
  state: {
37
94
  init: () => resolver,
38
95
  apply: (_tr, value) => value
96
+ },
97
+ appendTransaction: (transactions, _oldState, newState) => {
98
+ const styleResolver = documentStylesKey.getState(newState) ?? bareResolver();
99
+ const tr = resolveEditedParagraphStyles(transactions, newState, styleResolver, () => getDocumentNumbering(newState)) ?? newState.tr;
100
+ rebaseEditedParagraphJoins(transactions, tr, styleResolver);
101
+ return tr.docChanged ? tr : null;
39
102
  }
40
103
  });
41
104
  }
42
- /** Read the document's StyleResolver, or null when the plugin isn't installed. */
43
- function getDocumentStyleResolver(state) {
44
- return documentStylesKey.getState(state) ?? null;
45
- }
46
- /**
47
- * The document's style definitions by id, or `null` when the state carries no
48
- * styles plugin and so cannot say what the document defines. A document
49
- * without a styles part defines none.
50
- */
51
- function getDocumentStyleDefinitions(state) {
52
- if (documentStylesKey.get(state) === void 0) return null;
53
- const resolver = getDocumentStyleResolver(state);
54
- return {
55
- get: (styleId) => resolver?.getStyle(styleId),
56
- paragraphStyles: () => resolver?.getParagraphStyles() ?? []
57
- };
58
- }
59
- /**
60
- * Read the document's built-in style index, for the callers that classify
61
- * paragraphs (heading collection, markdown export, the AI snapshot). Without
62
- * the plugin every lookup misses, which degrades classification to the
63
- * paragraph's own outline level rather than to English style ids.
64
- */
65
- function getDocumentBuiltInStyles(state) {
66
- return getDocumentStyleResolver(state)?.builtInStyles ?? EMPTY_BUILT_IN_STYLE_INDEX;
67
- }
68
105
  /** Reconfigure so ProseMirror replaces the keyed plugin's resolver state. */
69
106
  const withDocumentStyles = (state, styles) => {
70
107
  const previous = documentStylesKey.get(state);
@@ -1,3 +1,4 @@
1
1
  import { SelectionChangeCallback, SelectionContext, createSelectionTrackerPlugin, extractSelectionContext, getSelectionContext, selectionTrackerKey } from "./selectionTracker.js";
2
- import { createDocumentStylesPlugin, documentStylesKey, getDocumentBuiltInStyles, getDocumentStyleResolver } from "./documentStyles.js";
2
+ import { documentStylesKey, getDocumentBuiltInStyles, getDocumentStyleResolver } from "./documentStyleState.js";
3
+ import { createDocumentStylesPlugin } from "./documentStyles.js";
3
4
  export { type SelectionChangeCallback, type SelectionContext, createDocumentStylesPlugin, createSelectionTrackerPlugin, documentStylesKey, extractSelectionContext, getDocumentBuiltInStyles, getDocumentStyleResolver, getSelectionContext, selectionTrackerKey };
@@ -1,3 +1,4 @@
1
- import { createDocumentStylesPlugin, documentStylesKey, getDocumentBuiltInStyles, getDocumentStyleResolver } from "./documentStyles.js";
1
+ import { documentStylesKey, getDocumentBuiltInStyles, getDocumentStyleResolver } from "./documentStyleState.js";
2
+ import { createDocumentStylesPlugin } from "./documentStyles.js";
2
3
  import { createSelectionTrackerPlugin, extractSelectionContext, getSelectionContext, selectionTrackerKey } from "./selectionTracker.js";
3
4
  export { createDocumentStylesPlugin, createSelectionTrackerPlugin, documentStylesKey, extractSelectionContext, getDocumentBuiltInStyles, getDocumentStyleResolver, getSelectionContext, selectionTrackerKey };
@@ -0,0 +1,15 @@
1
+ import { StyleEngine } from "../../style-engine/styleEngine.js";
2
+ import "../../style-engine/index.js";
3
+ import { NumberingMap } from "../../docx/numberingParser.js";
4
+ import { ParagraphCascadeResolver } from "../styles/paragraphStyleCascade.js";
5
+ import { EditorState, Transaction } from "prosemirror-state";
6
+ //#region src/prosemirror/plugins/paragraphStyleResolution.d.ts
7
+ type ParagraphStyleResolver = ParagraphCascadeResolver & Pick<StyleEngine, "getDefaultTableStyle">;
8
+ /**
9
+ * Project the style cascade onto every paragraph the transactions touched
10
+ * that has not been projected yet. Returns the transaction to append, or null
11
+ * when every touched paragraph already reads as a reopened document would.
12
+ */
13
+ declare const resolveEditedParagraphStyles: (transactions: readonly Transaction[], state: EditorState, resolver: ParagraphStyleResolver, numbering: () => NumberingMap | null) => Transaction | null;
14
+ //#endregion
15
+ export { resolveEditedParagraphStyles };
@@ -0,0 +1,230 @@
1
+ import { resolveTableLook } from "../../docx/tableLook.js";
2
+ import { tableOfContentsStyleLevel } from "../../utils/tableOfContentsStyle.js";
3
+ import { expectParagraphAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs } from "../attrs/index.js";
4
+ import { setAutospacingBaseValue } from "../autospacingBase.js";
5
+ import { directionToAuthoredBidi } from "../paragraphDirection.js";
6
+ import { paragraphStyleCascadeAttrs, tableCellParagraphOverlay } from "../styles/paragraphStyleCascade.js";
7
+ import { listAttrsFromResolvedStyle } from "../styles/resolvedStyleAttrs.js";
8
+ import { tableCellStyleRegions, tableRowBand } from "../styles/tableStyleRegions.js";
9
+ import { TableMap } from "prosemirror-tables";
10
+ import { Mapping } from "prosemirror-transform";
11
+ import { isHistoryTransaction } from "prosemirror-history";
12
+ //#region src/prosemirror/plugins/paragraphStyleResolution.ts
13
+ /** The ranges of `doc` the given transactions changed, in its own positions. */
14
+ const changedRanges = (transactions) => {
15
+ const ranges = [];
16
+ const maps = transactions.flatMap((transaction) => transaction.mapping.maps);
17
+ let offset = 0;
18
+ for (const transaction of transactions) {
19
+ const own = transaction.mapping.maps.length;
20
+ if (transaction.docChanged && !isHistoryTransaction(transaction)) for (const [index, map] of transaction.mapping.maps.entries()) {
21
+ const following = new Mapping(maps.slice(offset + index + 1));
22
+ map.forEach((_oldFrom, _oldTo, from, to) => {
23
+ ranges.push([following.map(from, -1), following.map(to, 1)]);
24
+ });
25
+ }
26
+ offset += own;
27
+ }
28
+ return ranges;
29
+ };
30
+ /**
31
+ * What the paragraph states itself, as the cascade reads it: every attr the
32
+ * node holds a value for. Only called for paragraphs the load path never
33
+ * projected, whose attrs hold nothing inherited yet.
34
+ */
35
+ const statedFormatting = (attrs) => {
36
+ const formatting = {};
37
+ const copy = (key) => {
38
+ const value = attrs[key];
39
+ if (value !== null && value !== void 0) Reflect.set(formatting, key, value);
40
+ };
41
+ copy("alignment");
42
+ copy("spaceBefore");
43
+ copy("spaceAfter");
44
+ copy("lineSpacing");
45
+ copy("lineSpacingRule");
46
+ copy("snapToGrid");
47
+ copy("indentLeft");
48
+ copy("indentRight");
49
+ copy("indentFirstLine");
50
+ if (attrs.indentFirstLine !== null && attrs.indentFirstLine !== void 0) copy("hangingIndent");
51
+ copy("borders");
52
+ copy("shading");
53
+ copy("tabs");
54
+ copy("kinsoku");
55
+ copy("overflowPunctuation");
56
+ copy("suppressAutoHyphens");
57
+ copy("pageBreakBefore");
58
+ copy("keepNext");
59
+ copy("keepLines");
60
+ copy("widowControl");
61
+ copy("contextualSpacing");
62
+ copy("runInWithNext");
63
+ copy("outlineLevel");
64
+ copy("numPr");
65
+ const bidi = directionToAuthoredBidi(attrs.direction);
66
+ if (bidi !== void 0) formatting.bidi = bidi;
67
+ return formatting;
68
+ };
69
+ const isUnset = (value) => value === null || value === void 0;
70
+ /**
71
+ * The attrs the cascade supplies that `paragraph` leaves unset, or null when
72
+ * it already reads the way a reopened document would.
73
+ */
74
+ const cascadePatch = (node, resolver, tableParagraphOverlay, numbering) => {
75
+ const attrs = expectParagraphAttrs(node);
76
+ const styleId = attrs.styleId ?? void 0;
77
+ const { attrs: cascade, stylePpr } = paragraphStyleCascadeAttrs({
78
+ styleId,
79
+ formatting: statedFormatting(attrs),
80
+ styleResolver: resolver,
81
+ tableParagraphOverlay,
82
+ includeParagraphMarkRunProperties: false
83
+ });
84
+ const patch = {};
85
+ const fill = (key) => {
86
+ const value = cascade[key];
87
+ if (!isUnset(value) && isUnset(attrs[key])) patch[key] = value;
88
+ };
89
+ const lineProvenance = attrs.lineSpacingExplicit;
90
+ const filledSides = {
91
+ before: !attrs.spacingExplicit?.before && isUnset(attrs.spaceBefore),
92
+ after: !attrs.spacingExplicit?.after && isUnset(attrs.spaceAfter)
93
+ };
94
+ if (filledSides.before) fill("spaceBefore");
95
+ if (filledSides.after) fill("spaceAfter");
96
+ if (lineProvenance !== "value" && lineProvenance !== "both" && lineProvenance !== true) fill("lineSpacing");
97
+ if (lineProvenance !== "rule" && lineProvenance !== "both" && lineProvenance !== true) fill("lineSpacingRule");
98
+ for (const key of ["spacingFromDocDefaults", "spacingFromImplicitDefaultStyle"]) {
99
+ const inherited = cascade[key];
100
+ const side = {
101
+ ...inherited?.before && filledSides.before ? { before: true } : {},
102
+ ...inherited?.after && filledSides.after ? { after: true } : {}
103
+ };
104
+ if (side.before || side.after) patch[key] = {
105
+ ...attrs[key],
106
+ ...side
107
+ };
108
+ }
109
+ if (isUnset(attrs.indentFirstLine) && attrs.hangingIndent !== true) {
110
+ fill("indentFirstLine");
111
+ if (cascade.hangingIndent === true) patch.hangingIndent = true;
112
+ }
113
+ for (const key of [
114
+ "alignment",
115
+ "alignmentFromStyle",
116
+ "_resolvedFormatting",
117
+ "snapToGrid",
118
+ "indentLeft",
119
+ "indentRight",
120
+ "borders",
121
+ "shading",
122
+ "tabs",
123
+ "kinsoku",
124
+ "overflowPunctuation",
125
+ "suppressAutoHyphens",
126
+ "pageBreakBefore",
127
+ "keepNext",
128
+ "keepLines",
129
+ "widowControl",
130
+ "contextualSpacing",
131
+ "runInWithNext",
132
+ "outlineLevel",
133
+ "direction",
134
+ "defaultTextFormatting"
135
+ ]) fill(key);
136
+ if (styleId !== void 0 && isUnset(attrs._tableOfContentsLevel)) {
137
+ const styleName = resolver.getStyle(styleId)?.name;
138
+ const level = tableOfContentsStyleLevel({
139
+ styleId,
140
+ ...styleName ? { styleName } : {}
141
+ });
142
+ if (level !== void 0) patch._tableOfContentsLevel = level;
143
+ }
144
+ if (stylePpr?.numPr?.kind === "reference" && isUnset(attrs.numPr) && isUnset(attrs.numPrFromStyle)) {
145
+ const listAttrs = listAttrsFromResolvedStyle({ paragraphFormatting: stylePpr }, numbering());
146
+ const takesLevelIndent = {
147
+ indentLeft: isUnset(attrs.indentLeft) && patch.indentLeft === void 0,
148
+ indentFirstLine: isUnset(attrs.indentFirstLine) && attrs.hangingIndent !== true && patch.indentFirstLine === void 0
149
+ };
150
+ takesLevelIndent["hangingIndent"] = takesLevelIndent["indentFirstLine"] === true;
151
+ for (const [key, value] of Object.entries(listAttrs ?? {})) {
152
+ if (takesLevelIndent[key] === false) continue;
153
+ Reflect.set(patch, key, value);
154
+ }
155
+ }
156
+ const autospacingBase = {};
157
+ if (stylePpr?.beforeAutospacing && patch.spaceBefore !== void 0) setAutospacingBaseValue(autospacingBase, "before", patch.spaceBefore);
158
+ if (stylePpr?.afterAutospacing && patch.spaceAfter !== void 0) setAutospacingBaseValue(autospacingBase, "after", patch.spaceAfter);
159
+ if (Object.keys(autospacingBase).length > 0) patch._autospacingBase = {
160
+ ...attrs._autospacingBase,
161
+ ...autospacingBase
162
+ };
163
+ return Object.keys(patch).length > 0 ? patch : null;
164
+ };
165
+ /** The table-style regions for the cell at `depth` of `$pos`, as the load path picks them. */
166
+ const cellStyleRegions = ($pos, depth) => {
167
+ const table = $pos.node(depth - 2);
168
+ const row = $pos.node(depth - 1);
169
+ const map = TableMap.get(table);
170
+ const cellPos = $pos.before(depth) - $pos.start(depth - 2);
171
+ const rect = map.findCell(cellPos);
172
+ const look = resolveTableLook(expectTableAttrs(table).look ?? void 0);
173
+ return tableCellStyleRegions({
174
+ look,
175
+ rowIndex: rect.top,
176
+ totalRows: map.height,
177
+ column: rect.left,
178
+ colspan: rect.right - rect.left,
179
+ totalColumns: map.width,
180
+ rowBand: tableRowBand(look, rect.top, map.height),
181
+ rowConditionalFormat: expectTableRowAttrs(row)._originalFormatting?.conditionalFormat,
182
+ cellConditionalFormat: expectTableCellAttrs($pos.node(depth))._originalFormatting?.conditionalFormat
183
+ });
184
+ };
185
+ /**
186
+ * The table-style paragraph overlay for a paragraph directly inside a table
187
+ * cell (or a block container in one), as the load path layers it.
188
+ */
189
+ const cellParagraphOverlay = ($pos, resolver) => {
190
+ for (let depth = $pos.depth; depth > 0; depth -= 1) {
191
+ const ancestor = $pos.node(depth);
192
+ const role = ancestor.type.spec["tableRole"];
193
+ if (role === "cell" || role === "header_cell") {
194
+ const styleId = $pos.node(depth - 2).attrs["styleId"];
195
+ return tableCellParagraphOverlay(resolver, typeof styleId === "string" ? styleId : null, cellStyleRegions($pos, depth));
196
+ }
197
+ if (ancestor.type.name === "textBox") return;
198
+ }
199
+ };
200
+ /**
201
+ * Project the style cascade onto every paragraph the transactions touched
202
+ * that has not been projected yet. Returns the transaction to append, or null
203
+ * when every touched paragraph already reads as a reopened document would.
204
+ */
205
+ const resolveEditedParagraphStyles = (transactions, state, resolver, numbering) => {
206
+ const ranges = changedRanges(transactions);
207
+ if (ranges.length === 0) return null;
208
+ const tr = state.tr;
209
+ const seen = /* @__PURE__ */ new Set();
210
+ const docSize = state.doc.content.size;
211
+ for (const [rangeFrom, rangeTo] of ranges) {
212
+ const from = Math.max(0, Math.min(rangeFrom, docSize));
213
+ const to = Math.max(from, Math.min(rangeTo, docSize));
214
+ state.doc.nodesBetween(from, to, (node, pos) => {
215
+ if (node.type.name !== "paragraph") return !node.isTextblock;
216
+ if (seen.has(pos)) return false;
217
+ seen.add(pos);
218
+ if (node.attrs["_originalFormatting"] !== null) return false;
219
+ const patch = cascadePatch(node, resolver, cellParagraphOverlay(state.doc.resolve(pos), resolver), numbering);
220
+ if (patch) for (const [key, value] of Object.entries(patch)) {
221
+ const current = node.attrs[key];
222
+ if (current !== value && !(isUnset(current) && isUnset(value))) tr.setNodeAttribute(pos, key, value);
223
+ }
224
+ return false;
225
+ });
226
+ }
227
+ return tr.docChanged ? tr : null;
228
+ };
229
+ //#endregion
230
+ export { resolveEditedParagraphStyles };
@@ -24,11 +24,21 @@ declare function makeRevisionInfo(state: EditorState): {
24
24
  * With track changes on, pasting over a non-empty text selection marks the
25
25
  * replaced text as a tracked deletion and the pasted slice as a tracked
26
26
  * insertion (so they read as one replacement), matching typing over a
27
- * selection. Returns false for a collapsed cursor or non-text selection so the
27
+ * selection. Select-all (an `AllSelection`) counts as a text selection over the
28
+ * whole document. Returns false for a collapsed cursor or another selection so the
28
29
  * default paste + the `appendTransaction` catch-all marks a plain insertion
29
30
  * (eigenpal/docx-editor#784).
30
31
  */
31
32
  declare function handleSuggestionPaste(view: EditorView, slice: Slice, pluginState: SuggestionModeState): boolean;
33
+ /**
34
+ * With track changes on, a paste into a table's cells (a cell selection, or a
35
+ * block of copied cells) replaces each cell's content the way a paste over a
36
+ * text selection does: the old content struck through, the pasted content
37
+ * after it as an insertion. When the pasted content is whole paragraphs, the
38
+ * last one ends the cell, so its paragraph mark is tracked as added too:
39
+ * rejecting then drops it and accepting joins the struck paragraphs into it.
40
+ */
41
+ declare function handleSuggestionTableCellPaste(view: EditorView, slice: Slice, pluginState: SuggestionModeState): boolean;
32
42
  /**
33
43
  * Remove `from`..`to` of `tr.doc` as a suggestion: text the current author
34
44
  * inserted is retracted, anything else is marked deleted. `false` when the
@@ -80,4 +90,4 @@ declare function setSuggestionMode(active: boolean, state: EditorState, dispatch
80
90
  */
81
91
  declare function isSuggestionModeActive(state: EditorState): boolean;
82
92
  //#endregion
83
- export { SUGGESTED_TEXT_INPUT_META, SUGGESTION_BYPASS_META, SUGGESTION_META, createSuggestionModePlugin, deleteSelectionAsSuggestion, handleSuggestionEnter, handleSuggestionPaste, isSuggestionModeActive, makeRevisionInfo, paragraphBoundaryTarget, setSuggestionMode, suggestRangeDeletion, suggestionModeKey, toggleSuggestionMode };
93
+ export { SUGGESTED_TEXT_INPUT_META, SUGGESTION_BYPASS_META, SUGGESTION_META, createSuggestionModePlugin, deleteSelectionAsSuggestion, handleSuggestionEnter, handleSuggestionPaste, handleSuggestionTableCellPaste, isSuggestionModeActive, makeRevisionInfo, paragraphBoundaryTarget, setSuggestionMode, suggestRangeDeletion, suggestionModeKey, toggleSuggestionMode };