@stll/folio-core 0.54.2 → 0.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/dist/ai-edits/apply.js +185 -33
  2. package/dist/ai-edits/headless.js +3 -2
  3. package/dist/ai-edits/types.d.ts +7 -1
  4. package/dist/compare/compare.js +1 -0
  5. package/dist/compare/content-types.d.ts +3 -15
  6. package/dist/compare/reproducible-package.d.ts +0 -17
  7. package/dist/compare/reproducible-package.js +12 -18
  8. package/dist/controller/canonicalClipboard.d.ts +23 -0
  9. package/dist/controller/canonicalClipboard.js +476 -0
  10. package/dist/controller/canonicalClipboardResources.d.ts +21 -0
  11. package/dist/controller/canonicalClipboardResources.js +382 -0
  12. package/dist/controller/canonicalComposition.d.ts +53 -0
  13. package/dist/controller/canonicalComposition.js +296 -0
  14. package/dist/controller/canonicalInlineProjection.d.ts +113 -0
  15. package/dist/controller/canonicalInlineProjection.js +393 -0
  16. package/dist/controller/canonicalInput.d.ts +54 -0
  17. package/dist/controller/canonicalInput.js +377 -0
  18. package/dist/controller/canonicalInputTimer.d.ts +7 -0
  19. package/dist/controller/canonicalInputTimer.js +11 -0
  20. package/dist/controller/canonicalOperations.d.ts +22 -0
  21. package/dist/controller/canonicalOperations.js +85 -0
  22. package/dist/controller/canonicalPublicOperations.d.ts +48 -0
  23. package/dist/controller/canonicalPublicOperations.js +556 -0
  24. package/dist/controller/canonicalReview.d.ts +12 -0
  25. package/dist/controller/canonicalReview.js +19 -0
  26. package/dist/controller/canonicalSession.d.ts +167 -0
  27. package/dist/controller/canonicalSession.js +1186 -0
  28. package/dist/controller/canonicalStoryEditor.d.ts +36 -0
  29. package/dist/controller/canonicalStoryEditor.js +87 -0
  30. package/dist/controller/canonicalStructure.d.ts +16 -0
  31. package/dist/controller/canonicalStructure.js +322 -0
  32. package/dist/controller/canonicalTocSelection.d.ts +11 -0
  33. package/dist/controller/canonicalTocSelection.js +43 -0
  34. package/dist/controller/folioEditor.d.ts +3 -10
  35. package/dist/controller/folioEditor.js +14 -4
  36. package/dist/controller/headerFooterEditorManager.d.ts +5 -0
  37. package/dist/controller/headerFooterEditorManager.js +72 -3
  38. package/dist/controller/hiddenEditorApi.d.ts +45 -0
  39. package/dist/controller/hiddenEditorApi.js +29 -8
  40. package/dist/controller/hiddenEditorManager.d.ts +13 -2
  41. package/dist/controller/hiddenEditorManager.js +639 -31
  42. package/dist/controller/layoutPipeline.d.ts +1 -1
  43. package/dist/controller/layoutPipeline.js +2 -0
  44. package/dist/controller/noteEditorManager.d.ts +5 -0
  45. package/dist/controller/noteEditorManager.js +114 -15
  46. package/dist/document-operations.d.ts +8 -1
  47. package/dist/document-operations.js +6 -4
  48. package/dist/docx/attributeRemainder.js +1 -0
  49. package/dist/docx/blockPlainText.d.ts +1 -1
  50. package/dist/docx/blockPlainText.js +11 -3
  51. package/dist/docx/canonicalResourceSave.d.ts +16 -0
  52. package/dist/docx/canonicalResourceSave.js +27 -0
  53. package/dist/docx/canonicalSave.d.ts +29 -0
  54. package/dist/docx/canonicalSave.js +101 -0
  55. package/dist/docx/canonicalSessionInput.d.ts +11 -0
  56. package/dist/docx/canonicalSessionInput.js +27 -0
  57. package/dist/docx/canonicalStoryRepack.d.ts +10 -0
  58. package/dist/docx/canonicalStoryRepack.js +74 -0
  59. package/dist/docx/contentTypeRegistry.d.ts +8 -0
  60. package/dist/docx/contentTypeRegistry.js +64 -0
  61. package/dist/docx/documentParser.d.ts +1 -13
  62. package/dist/docx/documentParser.js +1 -47
  63. package/dist/docx/ensureParaIds.d.ts +7 -1
  64. package/dist/docx/ensureParaIds.js +173 -215
  65. package/dist/docx/foldedListNumberFields.d.ts +85 -0
  66. package/dist/docx/foldedListNumberFields.js +267 -0
  67. package/dist/docx/footnoteParser.d.ts +1 -11
  68. package/dist/docx/footnoteParser.js +1 -16
  69. package/dist/docx/headerFooterParser.d.ts +1 -9
  70. package/dist/docx/headerFooterParser.js +1 -12
  71. package/dist/docx/headerFooterVerbatim.d.ts +39 -1
  72. package/dist/docx/headerFooterVerbatim.js +173 -2
  73. package/dist/docx/imageParser.d.ts +13 -1
  74. package/dist/docx/imageParser.js +20 -11
  75. package/dist/docx/metadataPrivacy.js +6 -1
  76. package/dist/docx/noteIds.d.ts +5 -0
  77. package/dist/docx/noteIds.js +6 -2
  78. package/dist/docx/noteReferenceMark.d.ts +3 -1
  79. package/dist/docx/noteReferenceMark.js +15 -14
  80. package/dist/docx/numberingParser.d.ts +3 -1
  81. package/dist/docx/numberingParser.js +17 -3
  82. package/dist/docx/packageParts.d.ts +3 -1
  83. package/dist/docx/packageParts.js +74 -19
  84. package/dist/docx/paragraphMarkPropertyPresence.d.ts +9 -0
  85. package/dist/docx/paragraphMarkPropertyPresence.js +21 -0
  86. package/dist/docx/paragraphParser.js +101 -53
  87. package/dist/docx/paragraphPropertySource.d.ts +15 -1
  88. package/dist/docx/paragraphPropertySource.js +77 -22
  89. package/dist/docx/parser.js +3 -1
  90. package/dist/docx/removeHeaderFooterParts.js +17 -6
  91. package/dist/docx/reviewHistoryNamespace.d.ts +4 -0
  92. package/dist/docx/reviewHistoryNamespace.js +4 -0
  93. package/dist/docx/reviewResolutionProvenance.d.ts +25 -0
  94. package/dist/docx/reviewResolutionProvenance.js +153 -0
  95. package/dist/docx/rezip.d.ts +54 -6
  96. package/dist/docx/rezip.js +835 -257
  97. package/dist/docx/runConsolidator.d.ts +2 -58
  98. package/dist/docx/runConsolidator.js +3 -175
  99. package/dist/docx/runParser.d.ts +2 -1
  100. package/dist/docx/runParser.js +156 -116
  101. package/dist/docx/saveDiagnostics.d.ts +22 -0
  102. package/dist/docx/saveDiagnostics.js +0 -0
  103. package/dist/docx/selectiveSave.d.ts +3 -1
  104. package/dist/docx/selectiveSave.js +36 -4
  105. package/dist/docx/selectiveXmlPatch.d.ts +16 -8
  106. package/dist/docx/selectiveXmlPatch.js +81 -7
  107. package/dist/docx/serializer/documentSerializer.d.ts +9 -2
  108. package/dist/docx/serializer/documentSerializer.js +29 -10
  109. package/dist/docx/serializer/headerFooterSerializer.d.ts +5 -1
  110. package/dist/docx/serializer/headerFooterSerializer.js +19 -11
  111. package/dist/docx/serializer/noteSerializer.d.ts +2 -2
  112. package/dist/docx/serializer/noteSerializer.js +24 -8
  113. package/dist/docx/serializer/paragraphSerializer.js +41 -4
  114. package/dist/docx/serializer/partNamespaces.js +2 -1
  115. package/dist/docx/serializer/runSerializer.js +3 -1
  116. package/dist/docx/server/applyDocxXmlPatchProposal.js +14 -9
  117. package/dist/docx/settingsHeaderFooterUpdate.d.ts +5 -0
  118. package/dist/docx/settingsHeaderFooterUpdate.js +90 -0
  119. package/dist/docx/settingsParser.d.ts +1 -2
  120. package/dist/docx/settingsParser.js +5 -6
  121. package/dist/docx/storyBlockReplay.d.ts +31 -0
  122. package/dist/docx/storyBlockReplay.js +471 -0
  123. package/dist/docx/storyPlainText.d.ts +20 -0
  124. package/dist/docx/storyPlainText.js +23 -0
  125. package/dist/docx/streamingXmlParser.d.ts +22 -1
  126. package/dist/docx/streamingXmlParser.js +49 -3
  127. package/dist/docx/structuralXmlPatch.js +18 -23
  128. package/dist/docx/styleParser.d.ts +5 -1
  129. package/dist/docx/styleParser.js +1 -1
  130. package/dist/docx/tableParser.d.ts +1 -8
  131. package/dist/docx/tableParser.js +1 -28
  132. package/dist/docx/textBoxParser.d.ts +1 -5
  133. package/dist/docx/textBoxParser.js +1 -20
  134. package/dist/docx/unzip.js +6 -1
  135. package/dist/docx/verbatimCapture.d.ts +3 -1
  136. package/dist/docx/verbatimCapture.js +49 -6
  137. package/dist/i18n/messages/ar.gen.d.ts +5 -0
  138. package/dist/i18n/messages/ar.gen.js +656 -0
  139. package/dist/i18n/messages/cs.gen.d.ts +5 -0
  140. package/dist/i18n/messages/cs.gen.js +656 -0
  141. package/dist/i18n/messages/de.gen.d.ts +5 -0
  142. package/dist/i18n/messages/de.gen.js +656 -0
  143. package/dist/i18n/messages/en.gen.d.ts +5 -0
  144. package/dist/i18n/messages/en.gen.js +656 -0
  145. package/dist/i18n/messages/es.gen.d.ts +5 -0
  146. package/dist/i18n/messages/es.gen.js +656 -0
  147. package/dist/i18n/messages/et.gen.d.ts +5 -0
  148. package/dist/i18n/messages/et.gen.js +656 -0
  149. package/dist/i18n/messages/fr.gen.d.ts +5 -0
  150. package/dist/i18n/messages/fr.gen.js +656 -0
  151. package/dist/i18n/messages/he.gen.d.ts +5 -0
  152. package/dist/i18n/messages/he.gen.js +656 -0
  153. package/dist/i18n/messages/hi.gen.d.ts +5 -0
  154. package/dist/i18n/messages/hi.gen.js +656 -0
  155. package/dist/i18n/messages/hu.gen.d.ts +5 -0
  156. package/dist/i18n/messages/hu.gen.js +656 -0
  157. package/dist/i18n/messages/locales.d.ts +5 -0
  158. package/dist/i18n/messages/locales.js +22 -0
  159. package/dist/i18n/messages/lt.gen.d.ts +5 -0
  160. package/dist/i18n/messages/lt.gen.js +656 -0
  161. package/dist/i18n/messages/lv.gen.d.ts +5 -0
  162. package/dist/i18n/messages/lv.gen.js +656 -0
  163. package/dist/i18n/messages/pl.gen.d.ts +5 -0
  164. package/dist/i18n/messages/pl.gen.js +656 -0
  165. package/dist/i18n/messages/pt-BR.gen.d.ts +5 -0
  166. package/dist/i18n/messages/pt-BR.gen.js +656 -0
  167. package/dist/i18n/messages/sk.gen.d.ts +5 -0
  168. package/dist/i18n/messages/sk.gen.js +656 -0
  169. package/dist/i18n/messages/tr.gen.d.ts +5 -0
  170. package/dist/i18n/messages/tr.gen.js +656 -0
  171. package/dist/i18n/messages/zh-CN.gen.d.ts +5 -0
  172. package/dist/i18n/messages/zh-CN.gen.js +656 -0
  173. package/dist/i18n/messages.d.ts +2 -3
  174. package/dist/i18n/messages.js +1 -19
  175. package/dist/internal/acceptedBlockProjection.d.ts +12 -0
  176. package/dist/internal/acceptedBlockProjection.js +45 -0
  177. package/dist/internal/noteMarkerAttrs.d.ts +8 -0
  178. package/dist/internal/noteMarkerAttrs.js +16 -0
  179. package/dist/internal/pageBreakRunSourceDescendantIndex.js +1 -0
  180. package/dist/internal/prosemirrorAttrBoundary.d.ts +21 -0
  181. package/dist/internal/prosemirrorAttrBoundary.js +50 -0
  182. package/dist/layout-bridge/convert/footnoteLayout.d.ts +1 -0
  183. package/dist/layout-bridge/convert/footnoteLayout.js +3 -3
  184. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -0
  185. package/dist/layout-bridge/convert/headerFooterLayout.js +1 -0
  186. package/dist/layout-bridge/convert/noteReferences.d.ts +1 -3
  187. package/dist/layout-bridge/convert/noteReferences.js +1 -6
  188. package/dist/layout-bridge/convert/paragraphRuns.js +2 -4
  189. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +2 -2
  190. package/dist/layout-bridge/convert/toFlowBlocks.js +2 -2
  191. package/dist/managers/DocumentLoaderManager.d.ts +1 -0
  192. package/dist/managers/DocumentLoaderManager.js +9 -1
  193. package/dist/markdown/escape.d.ts +3 -1
  194. package/dist/markdown/escape.js +9 -2
  195. package/dist/markdown/renderBlock.js +20 -121
  196. package/dist/markdown/renderParagraph.js +13 -15
  197. package/dist/markdown/renderRuns.d.ts +7 -1
  198. package/dist/markdown/renderRuns.js +35 -15
  199. package/dist/markdown/renderTable.js +2 -0
  200. package/dist/markdown/types.d.ts +3 -9
  201. package/dist/prosemirror/attrs/index.d.ts +2 -12
  202. package/dist/prosemirror/attrs/index.js +22 -48
  203. package/dist/prosemirror/bookmarkBoundaryAttrs.d.ts +2 -1
  204. package/dist/prosemirror/canonicalCommands.d.ts +121 -0
  205. package/dist/prosemirror/canonicalCommands.js +35 -0
  206. package/dist/prosemirror/canonicalSelectionRange.d.ts +9 -0
  207. package/dist/prosemirror/canonicalSelectionRange.js +15 -0
  208. package/dist/prosemirror/clipboardIntent.d.ts +7 -0
  209. package/dist/prosemirror/clipboardIntent.js +9 -0
  210. package/dist/prosemirror/commands/pageBreak.js +15 -1
  211. package/dist/prosemirror/commands/pastePlainText.js +2 -1
  212. package/dist/prosemirror/commentReferenceAttrs.d.ts +2 -1
  213. package/dist/prosemirror/conversion/fromProseDoc.js +91 -19
  214. package/dist/prosemirror/conversion/hyphenTextCarriers.d.ts +8 -0
  215. package/dist/prosemirror/conversion/hyphenTextCarriers.js +8 -0
  216. package/dist/prosemirror/conversion/listRenderingDefinition.d.ts +6 -0
  217. package/dist/prosemirror/conversion/listRenderingDefinition.js +97 -0
  218. package/dist/prosemirror/conversion/toProseDoc.d.ts +11 -4
  219. package/dist/prosemirror/conversion/toProseDoc.js +55 -14
  220. package/dist/prosemirror/executeEditorCommand.d.ts +11 -0
  221. package/dist/prosemirror/executeEditorCommand.js +26 -0
  222. package/dist/prosemirror/extensions/StarterKit.js +2 -0
  223. package/dist/prosemirror/extensions/core/ParagraphExtension.js +88 -48
  224. package/dist/prosemirror/extensions/features/ListExtension.js +18 -5
  225. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +5 -2
  226. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +13 -1
  227. package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +56 -28
  228. package/dist/prosemirror/extensions/marks/TextColorExtension.js +3 -2
  229. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +2 -0
  230. package/dist/prosemirror/extensions/marks/markUtils.js +72 -8
  231. package/dist/prosemirror/extensions/nodes/NoteMarkerExtension.d.ts +6 -0
  232. package/dist/prosemirror/extensions/nodes/NoteMarkerExtension.js +36 -0
  233. package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.js +4 -2
  234. package/dist/prosemirror/insertOperations.js +2 -1
  235. package/dist/prosemirror/listMarker.d.ts +1 -0
  236. package/dist/prosemirror/listMarker.js +16 -7
  237. package/dist/prosemirror/listNumbering.js +26 -5
  238. package/dist/prosemirror/listRenderingAttrs.d.ts +1 -0
  239. package/dist/prosemirror/listRenderingAttrs.js +3 -0
  240. package/dist/prosemirror/markupViewNotes.js +3 -2
  241. package/dist/prosemirror/moveRangeBoundaryAttrs.d.ts +2 -1
  242. package/dist/prosemirror/noteReferenceReview.js +5 -3
  243. package/dist/prosemirror/paragraphPropertyCarry.d.ts +7 -1
  244. package/dist/prosemirror/paragraphPropertyCarry.js +8 -3
  245. package/dist/prosemirror/plugins/suggestionMode.js +57 -7
  246. package/dist/prosemirror/rangeAnchorAttrs.d.ts +2 -1
  247. package/dist/prosemirror/runFormattingFromMarks.d.ts +4 -1
  248. package/dist/prosemirror/runFormattingFromMarks.js +15 -1
  249. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +2 -1
  250. package/dist/prosemirror/runFormattingInlineCarriers.js +4 -1
  251. package/dist/prosemirror/schema/marks.d.ts +2 -0
  252. package/dist/prosemirror/schema/nodes.d.ts +10 -2
  253. package/dist/prosemirror/textBoxAnchorAttrs.d.ts +2 -1
  254. package/dist/prosemirror/textInput.js +5 -1
  255. package/dist/prosemirror/trackedRevisionPath.js +2 -1
  256. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +1 -0
  257. package/dist/prosemirror/trackedRunInlineAtoms.js +1 -0
  258. package/dist/prosemirror/validation.js +4 -0
  259. package/dist/types/canonicalCapabilities.d.ts +215 -0
  260. package/dist/types/canonicalCapabilities.js +212 -0
  261. package/dist/types/canonicalSave.d.ts +11 -0
  262. package/dist/types/canonicalSave.js +0 -0
  263. package/dist/types/content.d.ts +2 -2
  264. package/dist/types/docxSerialization.d.ts +14 -0
  265. package/dist/types/docxSerialization.js +7 -0
  266. package/dist/utils/createDocument.js +2 -2
  267. package/package.json +16 -4
@@ -0,0 +1,296 @@
1
+ import { splitsSurrogatePair } from "../ai-edits/character-boundaries.js";
2
+ import { CANONICAL_GAP } from "../types/canonicalCapabilities.js";
3
+ import { setCanonicalInputTimer } from "./canonicalInputTimer.js";
4
+ import { CanonicalSessionError } from "./canonicalSession.js";
5
+ import { Result } from "better-result";
6
+ import { EditorState, TextSelection } from "prosemirror-state";
7
+ //#region src/controller/canonicalComposition.ts
8
+ const COMPOSITION_FLUSH_DELAY_MS = 25;
9
+ /** Native IME owns the provisional view; the captured canonical projection stays unchanged. */
10
+ const createCanonicalComposition = (options) => {
11
+ let state = { type: "committed" };
12
+ let authorizedNativeState = null;
13
+ let completed = { type: "idle" };
14
+ let timer;
15
+ const clearTimer = () => {
16
+ if (timer !== void 0) clearTimeout(timer);
17
+ timer = void 0;
18
+ };
19
+ const selectedText = (baseline, proposed) => {
20
+ const { from, to } = baseline.selection;
21
+ const size = proposed.doc.content.size - baseline.doc.content.size + to - from;
22
+ if (size < 0 || from + size > proposed.doc.content.size) return null;
23
+ const text = proposed.doc.textBetween(from, from + size, "", "");
24
+ return text.length === size ? text : null;
25
+ };
26
+ const selectedReplacement = (baseline, proposed) => {
27
+ const { from, to } = baseline.selection;
28
+ const text = selectedText(baseline, proposed);
29
+ if (text === null || !baseline.tr.insertText(text, from, to).doc.eq(proposed.doc)) return null;
30
+ return {
31
+ from,
32
+ to,
33
+ text,
34
+ semantic: "composition"
35
+ };
36
+ };
37
+ const replacement = (baseline, proposed) => {
38
+ const { $from, $to } = baseline.selection;
39
+ if (!$from.parent.isTextblock || !$to.parent.isTextblock) return null;
40
+ const selected = selectedReplacement(baseline, proposed);
41
+ if (selected) {
42
+ if ($from.sameParent($to) && selected.text === baseline.doc.textBetween(selected.from, selected.to, "", "")) return {
43
+ from: selected.from,
44
+ to: selected.from,
45
+ text: "",
46
+ semantic: "composition"
47
+ };
48
+ return selected;
49
+ }
50
+ if (!$from.sameParent($to)) return null;
51
+ const start = $from.start();
52
+ const next = proposed.doc.nodeAt(start - 1);
53
+ if (!next || next.type !== $from.parent.type || next.content.size !== next.textContent.length) return null;
54
+ const before = $from.parent.textContent;
55
+ const after = next.textContent;
56
+ let from = 0;
57
+ while (from < before.length && from < after.length && before[from] === after[from]) from++;
58
+ while (splitsSurrogatePair(before, from) || splitsSurrogatePair(after, from)) from--;
59
+ let oldEnd = before.length;
60
+ let newEnd = after.length;
61
+ while (oldEnd > from && newEnd > from && before[oldEnd - 1] === after[newEnd - 1]) {
62
+ oldEnd--;
63
+ newEnd--;
64
+ }
65
+ while (splitsSurrogatePair(before, oldEnd) || splitsSurrogatePair(after, newEnd)) {
66
+ oldEnd++;
67
+ newEnd++;
68
+ }
69
+ const text = after.slice(from, newEnd);
70
+ if (!baseline.tr.insertText(text, start + from, start + oldEnd).doc.eq(proposed.doc)) return null;
71
+ return {
72
+ from: start + from,
73
+ to: start + oldEnd,
74
+ text,
75
+ semantic: "composition"
76
+ };
77
+ };
78
+ const applyNative = (view, transaction) => Result.try({
79
+ try: () => view.state.applyTransaction(transaction),
80
+ catch: (cause) => new CanonicalSessionError({
81
+ gap: CANONICAL_GAP.dispatch,
82
+ reason: "refused",
83
+ message: `Composition projection failed: ${String(cause)}`
84
+ })
85
+ });
86
+ const finish = (view, commit) => {
87
+ clearTimer();
88
+ authorizedNativeState = null;
89
+ const pending = state;
90
+ if (pending.type === "committed") return { type: "idle" };
91
+ const input = commit && pending.type === "provisional" ? replacement(pending.baseline, view.state) : null;
92
+ const committedText = selectedText(pending.baseline, view.state);
93
+ const proposed = view.state;
94
+ const from = pending.baseline.selection.from;
95
+ completed = { type: "idle" };
96
+ state = { type: "committed" };
97
+ if (!view.isDestroyed) {
98
+ if (view.composing) view.dom.dispatchEvent(new Event("compositionend", { bubbles: true }));
99
+ view.updateState(pending.baseline);
100
+ }
101
+ options.end();
102
+ if (!commit || view.isDestroyed) return { type: "cancelled" };
103
+ if (pending.type === "refused") return {
104
+ type: "refused",
105
+ text: pending.text
106
+ };
107
+ if (!input) {
108
+ options.refuse("Composition changed unsupported content; the canonical document was restored.");
109
+ return {
110
+ type: "refused",
111
+ text: committedText
112
+ };
113
+ }
114
+ if (input.from !== input.to || input.text !== "") options.replace(input);
115
+ if (committedText !== null && !view.isDestroyed && view.state.doc.textContent === proposed.doc.textContent && from + committedText.length <= view.state.doc.content.size && view.state.doc.textBetween(from, from + committedText.length, "", "") === committedText) completed = {
116
+ type: "completed",
117
+ receipt: {
118
+ view,
119
+ state: view.state,
120
+ from,
121
+ to: from + committedText.length,
122
+ text: committedText,
123
+ marks: pending.baseline.storedMarks ?? pending.baseline.selection.$from.marksAcross(pending.baseline.selection.$to)
124
+ }
125
+ };
126
+ return {
127
+ type: "committed",
128
+ text: committedText
129
+ };
130
+ };
131
+ const schedule = (view) => {
132
+ clearTimer();
133
+ timer = setCanonicalInputTimer(() => finish(view, true), COMPOSITION_FLUSH_DELAY_MS);
134
+ };
135
+ return {
136
+ get status() {
137
+ return state.type;
138
+ },
139
+ get active() {
140
+ return state.type !== "committed";
141
+ },
142
+ start: (view) => {
143
+ if (state.type !== "committed") return;
144
+ if (!options.begin()) return;
145
+ state = {
146
+ type: "provisional",
147
+ baseline: view.state,
148
+ view,
149
+ phase: "active"
150
+ };
151
+ },
152
+ ended: (view) => {
153
+ if (state.type === "committed") return;
154
+ switch (state.type) {
155
+ case "provisional":
156
+ state = {
157
+ type: "provisional",
158
+ baseline: state.baseline,
159
+ view: state.view,
160
+ phase: "ended"
161
+ };
162
+ break;
163
+ case "refused":
164
+ state = {
165
+ type: "refused",
166
+ baseline: state.baseline,
167
+ view: state.view,
168
+ phase: "ended",
169
+ text: state.text
170
+ };
171
+ break;
172
+ default:
173
+ }
174
+ schedule(view);
175
+ },
176
+ forgetCompleted: () => {
177
+ completed = { type: "idle" };
178
+ },
179
+ get pendingFinal() {
180
+ return completed.type === "authorized";
181
+ },
182
+ authorizeLateFinal: (view, text) => {
183
+ if (completed.type === "idle") return false;
184
+ const { receipt } = completed;
185
+ if (view.isDestroyed || receipt.view !== view || receipt.state !== view.state || text === null) {
186
+ completed = { type: "idle" };
187
+ return false;
188
+ }
189
+ completed = {
190
+ type: "authorized",
191
+ receipt,
192
+ text
193
+ };
194
+ return true;
195
+ },
196
+ authorizeNative: (view) => {
197
+ authorizedNativeState = view.state;
198
+ },
199
+ flushed: (view) => {
200
+ const authorized = authorizedNativeState;
201
+ queueMicrotask(() => {
202
+ if (authorizedNativeState === authorized) authorizedNativeState = null;
203
+ });
204
+ if (state.type !== "committed" && state.phase === "ended") schedule(view);
205
+ },
206
+ recover: (view) => finish(view, true),
207
+ cancel: (view) => finish(view, false),
208
+ reset: () => {
209
+ completed = { type: "idle" };
210
+ if (state.type !== "committed") finish(state.view, false);
211
+ else {
212
+ clearTimer();
213
+ authorizedNativeState = null;
214
+ }
215
+ },
216
+ accept: (view, transaction) => {
217
+ if (state.type === "committed") {
218
+ const final = completed;
219
+ if (final.type !== "authorized" || final.receipt.view !== view) return false;
220
+ completed = { type: "idle" };
221
+ if (view.isDestroyed || final.receipt.state !== view.state) return false;
222
+ const applied = applyNative(view, transaction);
223
+ const baseline = EditorState.create({
224
+ schema: final.receipt.state.schema,
225
+ doc: final.receipt.state.doc,
226
+ selection: TextSelection.create(final.receipt.state.doc, final.receipt.from, final.receipt.to),
227
+ storedMarks: final.receipt.marks
228
+ });
229
+ const input = applied.isOk() ? replacement(baseline, applied.value.state) : null;
230
+ if (applied.isErr() || !input || input.from < final.receipt.from || input.to > final.receipt.to || selectedText(baseline, applied.value.state) !== final.text) {
231
+ view.updateState(final.receipt.state);
232
+ options.refuse(applied.isErr() ? applied.error.message : "Final composition changed unsupported content; the canonical document was restored.");
233
+ return true;
234
+ }
235
+ if (final.receipt.text !== final.text) options.replace({
236
+ from: final.receipt.from,
237
+ to: final.receipt.to,
238
+ text: final.text,
239
+ semantic: "composition",
240
+ compositionPhase: "correction"
241
+ });
242
+ if (!view.isDestroyed) view.updateState(view.state);
243
+ if (!view.isDestroyed && view.state.doc.textContent === applied.value.state.doc.textContent && final.receipt.from + final.text.length <= view.state.doc.content.size && view.state.doc.textBetween(final.receipt.from, final.receipt.from + final.text.length, "", "") === final.text) completed = {
244
+ type: "completed",
245
+ receipt: {
246
+ view,
247
+ state: view.state,
248
+ from: final.receipt.from,
249
+ to: final.receipt.from + final.text.length,
250
+ text: final.text,
251
+ marks: final.receipt.marks
252
+ }
253
+ };
254
+ return true;
255
+ }
256
+ if (state.type === "refused") {
257
+ view.updateState(state.baseline);
258
+ return true;
259
+ }
260
+ if (typeof transaction.getMeta("composition") !== "number" && authorizedNativeState !== view.state) {
261
+ options.refuse("Other edits must wait until composition finishes.");
262
+ return true;
263
+ }
264
+ authorizedNativeState = null;
265
+ const applied = applyNative(view, transaction);
266
+ if (applied.isErr()) {
267
+ view.updateState(state.baseline);
268
+ state = {
269
+ type: "refused",
270
+ baseline: state.baseline,
271
+ view: state.view,
272
+ phase: state.phase,
273
+ text: selectedText(state.baseline, transaction)
274
+ };
275
+ options.refuse(applied.error.message);
276
+ return true;
277
+ }
278
+ if (!replacement(state.baseline, applied.value.state)) {
279
+ view.updateState(state.baseline);
280
+ state = {
281
+ type: "refused",
282
+ baseline: state.baseline,
283
+ view: state.view,
284
+ phase: state.phase,
285
+ text: selectedText(state.baseline, applied.value.state)
286
+ };
287
+ options.refuse("Composition changed unsupported content; the canonical document was restored.");
288
+ return true;
289
+ }
290
+ view.updateState(applied.value.state);
291
+ return true;
292
+ }
293
+ };
294
+ };
295
+ //#endregion
296
+ export { createCanonicalComposition };
@@ -0,0 +1,113 @@
1
+ import { document_d_exports } from "../types/document.js";
2
+ import { Node } from "prosemirror-model";
3
+ import { Result } from "better-result";
4
+ //#region src/controller/canonicalInlineProjection.d.ts
5
+ declare const CANONICAL_SOURCE_INLINE_POLICIES: {
6
+ readonly run: "container";
7
+ readonly hyperlink: "container";
8
+ readonly insertion: "container";
9
+ readonly deletion: "container";
10
+ readonly moveFrom: "container";
11
+ readonly moveTo: "container";
12
+ readonly inlineWrapper: "container";
13
+ readonly inlineSdt: "control";
14
+ readonly simpleField: "leaf";
15
+ readonly complexField: "leaf";
16
+ readonly mathEquation: "leaf";
17
+ readonly preservedInline: "leaf";
18
+ readonly bookmarkStart: "leaf";
19
+ readonly bookmarkEnd: "leaf";
20
+ readonly commentRangeStart: "leaf";
21
+ readonly commentRangeEnd: "leaf";
22
+ readonly commentReference: "leaf";
23
+ readonly moveFromRangeStart: "leaf";
24
+ readonly moveFromRangeEnd: "leaf";
25
+ readonly moveToRangeStart: "leaf";
26
+ readonly moveToRangeEnd: "leaf";
27
+ readonly text: "text";
28
+ readonly tab: "leaf";
29
+ readonly break: "leaf";
30
+ readonly symbol: "leaf";
31
+ readonly footnoteRef: "leaf";
32
+ readonly endnoteRef: "leaf";
33
+ readonly noteMarker: "leaf";
34
+ readonly fieldChar: "rawField";
35
+ readonly instrText: "rawField";
36
+ readonly softHyphen: "leaf";
37
+ readonly noBreakHyphen: "leaf";
38
+ readonly renderedPageBreak: "layout";
39
+ readonly preservedXml: "leaf";
40
+ readonly drawing: "leaf";
41
+ readonly shape: "leaf";
42
+ };
43
+ declare const CANONICAL_NATIVE_INLINE_POLICIES: {
44
+ readonly text: "text";
45
+ readonly bookmarkBoundary: "markers";
46
+ readonly moveRangeBoundary: "markers";
47
+ readonly rangeAnchor: "markers";
48
+ readonly noteMarker: "noteMarker";
49
+ readonly preservedXml: "capture";
50
+ readonly field: "unit";
51
+ readonly structuredField: "unit";
52
+ readonly hardBreak: "unit";
53
+ readonly image: "unit";
54
+ readonly math: "unit";
55
+ readonly pageBreakRun: "unit";
56
+ readonly shape: "unit";
57
+ readonly symbol: "unit";
58
+ readonly tab: "unit";
59
+ readonly textBoxAnchor: "unit";
60
+ readonly commentReference: "unit";
61
+ readonly renderedPageBreak: "refused";
62
+ readonly sdt: "refused";
63
+ };
64
+ declare const InlineProjectionError_base: import("better-result").TaggedErrorClass<"InlineProjectionError">;
65
+ declare class InlineProjectionError extends InlineProjectionError_base<{
66
+ message: string;
67
+ }> {}
68
+ /** Every source variant makes a decision before conversion can discard its positions. */
69
+ declare const canonicalInlineSourceIssue: (items: readonly (document_d_exports.ParagraphContent | document_d_exports.RunContent)[], context?: "paragraph" | "fieldPayload") => string | null;
70
+ type NativeCell = {
71
+ type: "text";
72
+ text: string;
73
+ from: number;
74
+ to: number;
75
+ node: Node;
76
+ } | {
77
+ type: "unit";
78
+ from: number;
79
+ to: number;
80
+ node: Node;
81
+ } | {
82
+ type: "markedUnit";
83
+ sourceType: document_d_exports.NoteReferenceContent["type"];
84
+ label: string;
85
+ from: number;
86
+ to: number;
87
+ node: Node;
88
+ } | {
89
+ type: "zeroWidth";
90
+ sources: readonly (document_d_exports.ParagraphContent | document_d_exports.RunContent)[];
91
+ from: number;
92
+ to: number;
93
+ node: Node;
94
+ };
95
+ /** Native positions and deletion geometry read the same inline-cell classification. */
96
+ declare const canonicalNativeCells: (paragraph: Node) => Result<NativeCell[], InlineProjectionError>;
97
+ type CanonicalInlineGap = {
98
+ position: number;
99
+ zeroWidthBefore: number;
100
+ };
101
+ type InlineProjection = {
102
+ text: string;
103
+ boundaries: CanonicalInlineGap[][];
104
+ };
105
+ type CanonicalInlineProjectionArgs = {
106
+ source: document_d_exports.Paragraph;
107
+ paragraph: Node;
108
+ pairedBookmarkIds: ReadonlySet<number>;
109
+ };
110
+ /** Bind rendered gaps to the operation owner's source leaf ordinals, including collapsed pairs. */
111
+ declare const projectCanonicalInline: ({ source, paragraph, pairedBookmarkIds }: CanonicalInlineProjectionArgs) => Result<InlineProjection, InlineProjectionError>;
112
+ //#endregion
113
+ export { CANONICAL_NATIVE_INLINE_POLICIES, CANONICAL_SOURCE_INLINE_POLICIES, CanonicalInlineGap, canonicalInlineSourceIssue, canonicalNativeCells, projectCanonicalInline };