@stll/folio-core 0.11.0 → 0.13.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 (263) hide show
  1. package/dist/ai-edits/apply.d.ts +2 -1
  2. package/dist/ai-edits/apply.js +693 -63
  3. package/dist/ai-edits/block-identity.d.ts +4 -0
  4. package/dist/ai-edits/block-identity.js +9 -0
  5. package/dist/ai-edits/blockRange.d.ts +28 -1
  6. package/dist/ai-edits/blockRange.js +68 -2
  7. package/dist/ai-edits/clean-text.js +2 -1
  8. package/dist/ai-edits/headless.d.ts +4 -4
  9. package/dist/ai-edits/headless.js +9 -9
  10. package/dist/ai-edits/index.d.ts +2 -2
  11. package/dist/ai-edits/index.js +2 -2
  12. package/dist/ai-edits/read.d.ts +7 -7
  13. package/dist/ai-edits/read.js +110 -3
  14. package/dist/ai-edits/snapshot.js +21 -3
  15. package/dist/ai-edits/table-cell-mutations.d.ts +48 -0
  16. package/dist/ai-edits/table-cell-mutations.js +238 -0
  17. package/dist/ai-edits/table-mutation-plan.d.ts +38 -0
  18. package/dist/ai-edits/table-mutation-plan.js +90 -0
  19. package/dist/ai-edits/table-row-column-mutations.d.ts +108 -0
  20. package/dist/ai-edits/table-row-column-mutations.js +300 -0
  21. package/dist/ai-edits/table-targets.d.ts +32 -0
  22. package/dist/ai-edits/table-targets.js +70 -0
  23. package/dist/ai-edits/types.d.ts +62 -1
  24. package/dist/ai-edits/word-diff.js +21 -0
  25. package/dist/compat/eigenpal.d.ts +3 -3
  26. package/dist/compat/eigenpal.js +3 -3
  27. package/dist/content-controls/mutateContentControls.js +1 -1
  28. package/dist/controller/activeEditorStory.d.ts +36 -0
  29. package/dist/controller/activeEditorStory.js +30 -0
  30. package/dist/controller/contentControlWidgetController.d.ts +55 -0
  31. package/dist/controller/contentControlWidgetController.js +141 -0
  32. package/dist/controller/fontReadiness.js +2 -0
  33. package/dist/controller/headerFooterEditorManager.js +2 -2
  34. package/dist/controller/hiddenEditorApi.js +2 -2
  35. package/dist/controller/hiddenEditorManager.d.ts +12 -1
  36. package/dist/controller/hiddenEditorManager.js +44 -12
  37. package/dist/controller/layoutPipeline.d.ts +2 -0
  38. package/dist/controller/layoutPipeline.js +17 -2
  39. package/dist/controller/noteEditorManager.d.ts +36 -0
  40. package/dist/controller/noteEditorManager.js +210 -0
  41. package/dist/document-operations.d.ts +43 -11
  42. package/dist/document-operations.js +186 -18
  43. package/dist/docx/blockContentParser.js +21 -7
  44. package/dist/docx/commentParser.js +6 -1
  45. package/dist/docx/commentRangeIntegrity.d.ts +6 -0
  46. package/dist/docx/commentRangeIntegrity.js +186 -0
  47. package/dist/docx/conformance.js +62 -1
  48. package/dist/docx/documentGrid.d.ts +8 -0
  49. package/dist/docx/documentGrid.js +8 -0
  50. package/dist/docx/drawingUtils.js +1 -1
  51. package/dist/docx/encryption/agileDecryption.js +12 -2
  52. package/dist/docx/encryption/compoundFile.js +6 -1
  53. package/dist/docx/encryption/encryptionInfo.d.ts +9 -1
  54. package/dist/docx/encryption/encryptionInfo.js +18 -2
  55. package/dist/docx/encryption/openEncryptedDocx.js +1 -1
  56. package/dist/docx/ensureParaIds.js +8 -7
  57. package/dist/docx/fieldParser.js +1 -1
  58. package/dist/docx/groupDrawingParser.js +10 -5
  59. package/dist/docx/hyperlinkParser.js +1 -1
  60. package/dist/docx/imageParser.js +10 -6
  61. package/dist/docx/metadataPrivacy.js +17 -3
  62. package/dist/docx/notePropertiesParser.js +1 -1
  63. package/dist/docx/numberingParser.js +1 -1
  64. package/dist/docx/paragraphParser.js +70 -61
  65. package/dist/docx/paragraphTextBoxEnrichment.d.ts +2 -1
  66. package/dist/docx/paragraphTextBoxEnrichment.js +67 -13
  67. package/dist/docx/paragraphTraversal.js +1 -1
  68. package/dist/docx/parser.js +3 -3
  69. package/dist/docx/rezip.js +20 -9
  70. package/dist/docx/runParser.js +17 -6
  71. package/dist/docx/sdtProperties.js +1 -1
  72. package/dist/docx/sectionParser.js +18 -5
  73. package/dist/docx/selectiveSave.js +5 -1
  74. package/dist/docx/selectiveXmlPatch.d.ts +22 -1
  75. package/dist/docx/selectiveXmlPatch.js +61 -1
  76. package/dist/docx/serializer/blockSdtSerializer.js +3 -2
  77. package/dist/docx/serializer/commentSerializer.js +5 -6
  78. package/dist/docx/serializer/documentSerializer.js +2 -2
  79. package/dist/docx/serializer/headerFooterSerializer.js +2 -2
  80. package/dist/docx/serializer/noteSerializer.js +2 -2
  81. package/dist/docx/serializer/paragraphSerializer.js +23 -15
  82. package/dist/docx/serializer/runSerializer.js +25 -21
  83. package/dist/docx/serializer/sectionPropertiesSerializer.js +2 -1
  84. package/dist/docx/serializer/stylesSerializer.js +1 -1
  85. package/dist/docx/serializer/tableSerializer.d.ts +5 -4
  86. package/dist/docx/serializer/tableSerializer.js +26 -20
  87. package/dist/docx/serializer/xmlUtils.d.ts +13 -1
  88. package/dist/docx/serializer/xmlUtils.js +27 -1
  89. package/dist/docx/server/applyDocxXmlPatchProposal.d.ts +87 -0
  90. package/dist/docx/server/applyDocxXmlPatchProposal.js +204 -0
  91. package/dist/docx/server/boundedArchive.d.ts +14 -3
  92. package/dist/docx/server/boundedArchive.js +56 -11
  93. package/dist/docx/server/evaluateDocxXmlPatchProposal.d.ts +85 -0
  94. package/dist/docx/server/evaluateDocxXmlPatchProposal.js +361 -0
  95. package/dist/docx/server/extractDocxText.js +55 -8
  96. package/dist/docx/server/inspectDocxPackage.d.ts +70 -0
  97. package/dist/docx/server/inspectDocxPackage.js +217 -0
  98. package/dist/docx/server/validateDocxConformance.d.ts +41 -0
  99. package/dist/docx/server/validateDocxConformance.js +336 -0
  100. package/dist/docx/settingsParser.js +26 -3
  101. package/dist/docx/shapeParser.js +1 -1
  102. package/dist/docx/styleParser.js +4 -2
  103. package/dist/docx/tableParser.d.ts +8 -1
  104. package/dist/docx/tableParser.js +31 -10
  105. package/dist/docx/textBoxParser.d.ts +3 -3
  106. package/dist/docx/textBoxParser.js +16 -12
  107. package/dist/docx/unzip.js +1 -0
  108. package/dist/docx/vmlImageParser.js +11 -3
  109. package/dist/docx/xmlParser.js +11 -1
  110. package/dist/docx/xmlSafety.d.ts +5 -0
  111. package/dist/docx/xmlSafety.js +9 -0
  112. package/dist/fields/resolveFieldValues.js +1 -3
  113. package/dist/fonts/embeddedFonts.d.ts +33 -5
  114. package/dist/fonts/embeddedFonts.js +37 -8
  115. package/dist/i18n/messages/catalogs.gen.d.ts +17 -0
  116. package/dist/i18n/messages/catalogs.gen.js +17 -0
  117. package/dist/i18n/messages/messages.gen.d.ts +1 -0
  118. package/dist/index.d.ts +3 -3
  119. package/dist/index.js +3 -3
  120. package/dist/layout-bridge/convert/footnoteLayout.d.ts +1 -0
  121. package/dist/layout-bridge/convert/footnoteLayout.js +47 -40
  122. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -0
  123. package/dist/layout-bridge/convert/headerFooterLayout.js +3 -0
  124. package/dist/layout-bridge/convert/templatePreviewFlow.js +3 -3
  125. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +4 -2
  126. package/dist/layout-bridge/convert/toFlowBlocks.js +151 -20
  127. package/dist/layout-bridge/dom/noteStoryDom.d.ts +6 -0
  128. package/dist/layout-bridge/dom/noteStoryDom.js +17 -0
  129. package/dist/layout-bridge/engine/clickToPosition.js +2 -2
  130. package/dist/layout-engine/index.d.ts +2 -2
  131. package/dist/layout-engine/index.js +58 -30
  132. package/dist/layout-engine/justificationCompatibility.d.ts +6 -0
  133. package/dist/layout-engine/justificationCompatibility.js +8 -0
  134. package/dist/layout-engine/keep-together.js +11 -1
  135. package/dist/layout-engine/measure/cache.js +23 -5
  136. package/dist/layout-engine/measure/effectiveLineBreakPolicy.js +8 -2
  137. package/dist/layout-engine/measure/lineBreakProvider.d.ts +2 -2
  138. package/dist/layout-engine/measure/lineBreakProvider.js +56 -37
  139. package/dist/layout-engine/measure/measureBlocks.js +15 -4
  140. package/dist/layout-engine/measure/measureContainer.js +1 -1
  141. package/dist/layout-engine/measure/measureHelpers.d.ts +11 -2
  142. package/dist/layout-engine/measure/measureHelpers.js +15 -4
  143. package/dist/layout-engine/measure/measureParagraph.js +85 -25
  144. package/dist/layout-engine/measure/measureProvider.js +4 -3
  145. package/dist/layout-engine/measure/tableCellFlow.js +5 -2
  146. package/dist/layout-engine/measure/textBoxParagraphLayout.d.ts +9 -7
  147. package/dist/layout-engine/measure/textBoxParagraphLayout.js +22 -6
  148. package/dist/layout-engine/measure/textMeasurementPolicy.d.ts +3 -1
  149. package/dist/layout-engine/measure/textMeasurementPolicy.js +7 -1
  150. package/dist/layout-engine/paginator.js +5 -1
  151. package/dist/layout-engine/paragraphSpacing.d.ts +28 -4
  152. package/dist/layout-engine/paragraphSpacing.js +107 -13
  153. package/dist/layout-engine/renderedBreakReconciliation.js +1 -1
  154. package/dist/layout-engine/types.d.ts +48 -15
  155. package/dist/layout-painter/registry/modules/textBox.js +5 -1
  156. package/dist/layout-painter/renderImage.d.ts +12 -1
  157. package/dist/layout-painter/renderImage.js +21 -4
  158. package/dist/layout-painter/renderPage.d.ts +5 -2
  159. package/dist/layout-painter/renderPage.js +59 -14
  160. package/dist/layout-painter/renderParagraph.js +55 -15
  161. package/dist/layout-painter/renderTable.d.ts +5 -1
  162. package/dist/layout-painter/renderTable.js +7 -3
  163. package/dist/layout-painter/renderTextBox.d.ts +2 -1
  164. package/dist/layout-painter/renderTextBox.js +25 -14
  165. package/dist/layout-painter/renderWatermark.d.ts +1 -1
  166. package/dist/layout-painter/renderWatermark.js +2 -1
  167. package/dist/managers/DocumentLoaderManager.js +1 -1
  168. package/dist/markdown/fromMarkdown.js +1 -1
  169. package/dist/model.js +1 -1
  170. package/dist/prosemirror/attrs/index.d.ts +4 -2
  171. package/dist/prosemirror/attrs/index.js +175 -18
  172. package/dist/prosemirror/commands/comments.d.ts +79 -4
  173. package/dist/prosemirror/commands/comments.js +622 -13
  174. package/dist/prosemirror/commands/contentControls.js +1 -1
  175. package/dist/prosemirror/commands/hyperlink.js +15 -1
  176. package/dist/prosemirror/commands/image.js +7 -1
  177. package/dist/prosemirror/commands/index.d.ts +2 -2
  178. package/dist/prosemirror/commands/index.js +2 -2
  179. package/dist/prosemirror/commands/pageBreak.js +1 -1
  180. package/dist/prosemirror/commands/propertyChangeScope.d.ts +2 -2
  181. package/dist/prosemirror/commands/propertyChangeScope.js +3 -2
  182. package/dist/prosemirror/commands/tableCellMergeResolution.d.ts +9 -0
  183. package/dist/prosemirror/commands/tableCellMergeResolution.js +181 -0
  184. package/dist/prosemirror/commentIdAllocator.js +13 -3
  185. package/dist/prosemirror/conversion/fromProseDoc.d.ts +2 -1
  186. package/dist/prosemirror/conversion/fromProseDoc.js +404 -62
  187. package/dist/prosemirror/conversion/index.js +1 -1
  188. package/dist/prosemirror/conversion/sdtAttrs.d.ts +9 -0
  189. package/dist/prosemirror/conversion/sdtAttrs.js +49 -0
  190. package/dist/prosemirror/conversion/toProseDoc.d.ts +2 -1
  191. package/dist/prosemirror/conversion/toProseDoc.js +364 -103
  192. package/dist/prosemirror/extensions/ExtensionManager.js +1 -1
  193. package/dist/prosemirror/extensions/StarterKit.js +6 -1
  194. package/dist/prosemirror/extensions/core/ParagraphExtension.js +6 -2
  195. package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +1 -0
  196. package/dist/prosemirror/extensions/features/ImagePasteExtension.js +10 -2
  197. package/dist/prosemirror/extensions/features/ListExtension.js +1 -1
  198. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.d.ts +10 -1
  199. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +93 -2
  200. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +2 -1
  201. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +6 -2
  202. package/dist/prosemirror/extensions/features/pasteCleanup.js +15 -2
  203. package/dist/prosemirror/extensions/marks/CharacterSpacingExtension.js +1 -1
  204. package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +30 -4
  205. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.d.ts +9 -1
  206. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +70 -11
  207. package/dist/prosemirror/extensions/nodes/FieldExtension.js +1 -1
  208. package/dist/prosemirror/extensions/nodes/RenderedPageBreakExtension.d.ts +7 -0
  209. package/dist/prosemirror/extensions/nodes/RenderedPageBreakExtension.js +22 -0
  210. package/dist/prosemirror/extensions/nodes/TableExtension.d.ts +1 -1
  211. package/dist/prosemirror/extensions/nodes/TableExtension.js +14 -6
  212. package/dist/prosemirror/extensions/nodes/TextBoxAnchorExtension.d.ts +13 -0
  213. package/dist/prosemirror/extensions/nodes/TextBoxAnchorExtension.js +41 -0
  214. package/dist/prosemirror/extensions/nodes/TextBoxExtension.d.ts +5 -2
  215. package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +4 -1
  216. package/dist/prosemirror/index.d.ts +1 -1
  217. package/dist/prosemirror/index.js +1 -1
  218. package/dist/prosemirror/plugins/contentControlWidgets.d.ts +36 -10
  219. package/dist/prosemirror/plugins/contentControlWidgets.js +128 -94
  220. package/dist/prosemirror/plugins/revisionIds.d.ts +23 -0
  221. package/dist/prosemirror/plugins/revisionIds.js +57 -0
  222. package/dist/prosemirror/plugins/selectionTracker.js +1 -0
  223. package/dist/prosemirror/plugins/suggestionMode.js +5 -4
  224. package/dist/prosemirror/runFormattingMarkNames.d.ts +14 -0
  225. package/dist/prosemirror/runFormattingMarkNames.js +40 -0
  226. package/dist/prosemirror/schema/index.d.ts +2 -2
  227. package/dist/prosemirror/schema/marks.d.ts +30 -3
  228. package/dist/prosemirror/schema/marks.js +15 -0
  229. package/dist/prosemirror/schema/nodes.d.ts +111 -6
  230. package/dist/prosemirror/selectionState.js +1 -0
  231. package/dist/prosemirror/styles/resolvedStyleAttrs.js +1 -0
  232. package/dist/prosemirror/tableCellMergeRevision.d.ts +9 -0
  233. package/dist/prosemirror/tableCellMergeRevision.js +22 -0
  234. package/dist/prosemirror/textBoxAnchorAttrs.d.ts +9 -0
  235. package/dist/prosemirror/textBoxAnchorAttrs.js +33 -0
  236. package/dist/prosemirror/utils/extractTrackedChanges.d.ts +1 -1
  237. package/dist/prosemirror/utils/extractTrackedChanges.js +62 -14
  238. package/dist/prosemirror/validation.js +9 -1
  239. package/dist/render-dom/RemoteSelectionOverlay.js +2 -2
  240. package/dist/server.d.ts +7 -3
  241. package/dist/server.js +7 -3
  242. package/dist/utils/clipboard.d.ts +10 -1
  243. package/dist/utils/clipboard.js +33 -6
  244. package/dist/utils/colorResolver.d.ts +8 -1
  245. package/dist/utils/colorResolver.js +35 -5
  246. package/dist/utils/fontFamilyMerge.js +9 -11
  247. package/dist/utils/fontLoader.js +3 -2
  248. package/dist/utils/fontResolver.d.ts +2 -1
  249. package/dist/utils/fontResolver.js +31 -7
  250. package/dist/utils/fontWeights.d.ts +1 -1
  251. package/dist/utils/fontWeights.js +1 -1
  252. package/dist/utils/hexId.d.ts +11 -1
  253. package/dist/utils/hexId.js +11 -1
  254. package/dist/utils/paragraphFormattingMerge.js +1 -0
  255. package/dist/utils/sanitizeImageSrc.d.ts +21 -0
  256. package/dist/utils/sanitizeImageSrc.js +30 -0
  257. package/dist/utils/stripXmlDeclarations.d.ts +11 -0
  258. package/dist/utils/stripXmlDeclarations.js +35 -0
  259. package/dist/version-comparison.d.ts +22 -2
  260. package/dist/version-comparison.js +41 -12
  261. package/dist/watermark/index.d.ts +11 -1
  262. package/dist/watermark/index.js +22 -1
  263. package/package.json +3 -2
@@ -0,0 +1,210 @@
1
+ import { ExtensionManager } from "../prosemirror/extensions/ExtensionManager.js";
2
+ import { ensureBaseDirectionInState } from "../prosemirror/extensions/features/AutoBidiDetectionExtension.js";
3
+ import { createDocumentStylesPlugin } from "../prosemirror/plugins/documentStyles.js";
4
+ import { ensureParaIdsInState } from "../prosemirror/extensions/features/ParaIdAllocatorExtension.js";
5
+ import { createStarterKit } from "../prosemirror/extensions/StarterKit.js";
6
+ import { schema } from "../prosemirror/schema/index.js";
7
+ import { footnoteToProseDoc } from "../prosemirror/conversion/toProseDoc.js";
8
+ import { proseDocToBlocks } from "../prosemirror/conversion/fromProseDoc.js";
9
+ import { isSeparatorEndnote, isSeparatorFootnote } from "../docx/footnoteParser.js";
10
+ import { EditorState } from "prosemirror-state";
11
+ import { EditorView } from "prosemirror-view";
12
+ //#region src/controller/noteEditorManager.ts
13
+ /** Framework-neutral lifecycle owner for editable footnote and endnote stories. */
14
+ const EMPTY_PLUGINS = [];
15
+ const storyMapKey = ({ kind, noteId }) => `${kind}:${String(noteId)}`;
16
+ const isNormalFootnote = (note) => !isSeparatorFootnote(note);
17
+ const isNormalEndnote = (note) => !isSeparatorEndnote(note);
18
+ const enumerateDocumentNoteStories = (document) => [...(document?.package.footnotes ?? []).filter(isNormalFootnote).map(({ id }) => ({
19
+ kind: "footnote",
20
+ noteId: id
21
+ })), ...(document?.package.endnotes ?? []).filter(isNormalEndnote).map(({ id }) => ({
22
+ kind: "endnote",
23
+ noteId: id
24
+ }))];
25
+ const resolveNote = (document, story) => {
26
+ return (story.kind === "footnote" ? document?.package.footnotes : document?.package.endnotes)?.find(({ id }) => id === story.noteId) ?? null;
27
+ };
28
+ const noteToProseDocument = (note, styles, theme) => {
29
+ const options = {};
30
+ if (styles) options.styles = styles;
31
+ if (theme !== void 0) options.theme = theme;
32
+ return footnoteToProseDoc(note.content, options);
33
+ };
34
+ const buildInitialState = (document, styles, manager, externalPlugins) => {
35
+ return ensureBaseDirectionInState(ensureParaIdsInState(EditorState.create({
36
+ doc: document,
37
+ schema,
38
+ plugins: [
39
+ ...manager.getPlugins(),
40
+ ...externalPlugins,
41
+ createDocumentStylesPlugin(styles)
42
+ ]
43
+ })));
44
+ };
45
+ const createNoteEditorManager = (deps) => {
46
+ const mounted = /* @__PURE__ */ new Map();
47
+ let active = null;
48
+ const updateVisibility = () => {
49
+ const activeKey = active ? storyMapKey(active) : null;
50
+ for (const [key, story] of mounted) story.mountNode.hidden = key !== activeKey;
51
+ };
52
+ const destroyMounted = (story) => {
53
+ story.view.destroy();
54
+ story.manager.destroy();
55
+ story.mountNode.remove();
56
+ };
57
+ const destroy = () => {
58
+ for (const story of mounted.values()) destroyMounted(story);
59
+ mounted.clear();
60
+ active = null;
61
+ };
62
+ const sync = () => {
63
+ const host = deps.getHost();
64
+ if (!host) return;
65
+ const document = deps.getDocument();
66
+ const styles = deps.getStyles();
67
+ const theme = deps.getTheme();
68
+ const externalPlugins = deps.getPlugins?.() ?? EMPTY_PLUGINS;
69
+ const wanted = new Map(enumerateDocumentNoteStories(document).map((story) => [storyMapKey(story), story]));
70
+ const activeKey = active ? storyMapKey(active) : null;
71
+ for (const [key, story] of mounted) {
72
+ if (wanted.has(key)) continue;
73
+ destroyMounted(story);
74
+ mounted.delete(key);
75
+ }
76
+ for (const [key, storyKey] of wanted) {
77
+ if (!mounted.has(key) && key !== activeKey) continue;
78
+ const note = resolveNote(document, storyKey);
79
+ if (!note) continue;
80
+ const existing = mounted.get(key);
81
+ if (existing) {
82
+ if (existing.mountNode.parentElement !== host) host.append(existing.mountNode);
83
+ const nextProseDocument = noteToProseDocument(note, styles, theme);
84
+ const contextIsCurrent = existing.appliedStyles === styles && existing.appliedTheme === theme && existing.appliedPlugins === externalPlugins;
85
+ if ((existing.appliedNote === note && existing.appliedContent === note.content || existing.appliedProseDocument.eq(nextProseDocument)) && contextIsCurrent) {
86
+ existing.appliedNote = note;
87
+ existing.appliedContent = note.content;
88
+ existing.appliedProseDocument = nextProseDocument;
89
+ continue;
90
+ }
91
+ existing.view.updateState(buildInitialState(nextProseDocument, styles, existing.manager, externalPlugins));
92
+ existing.appliedNote = note;
93
+ existing.appliedContent = note.content;
94
+ existing.appliedStyles = styles;
95
+ existing.appliedTheme = theme;
96
+ existing.appliedPlugins = externalPlugins;
97
+ existing.appliedProseDocument = nextProseDocument;
98
+ existing.dirty = false;
99
+ continue;
100
+ }
101
+ const manager = new ExtensionManager(createStarterKit());
102
+ manager.buildSchema();
103
+ manager.initializeRuntime();
104
+ const mountNode = host.ownerDocument.createElement("div");
105
+ mountNode.dataset["noteKind"] = storyKey.kind;
106
+ mountNode.dataset["noteId"] = String(storyKey.noteId);
107
+ host.append(mountNode);
108
+ const proseDocument = noteToProseDocument(note, styles, theme);
109
+ const view = new EditorView(mountNode, {
110
+ state: buildInitialState(proseDocument, styles, manager, externalPlugins),
111
+ dispatchTransaction(transaction) {
112
+ view.updateState(view.state.apply(transaction));
113
+ const mountedStory = mounted.get(key);
114
+ if (mountedStory && transaction.docChanged) mountedStory.dirty = true;
115
+ deps.onTransaction?.({
116
+ ...storyKey,
117
+ docChanged: transaction.docChanged,
118
+ selectionChanged: transaction.selectionSet,
119
+ view
120
+ });
121
+ }
122
+ });
123
+ mounted.set(key, {
124
+ appliedContent: note.content,
125
+ appliedNote: note,
126
+ appliedPlugins: externalPlugins,
127
+ appliedProseDocument: proseDocument,
128
+ appliedStyles: styles,
129
+ appliedTheme: theme,
130
+ dirty: false,
131
+ manager,
132
+ mountNode,
133
+ note: storyKey,
134
+ view
135
+ });
136
+ }
137
+ if (active && !wanted.has(storyMapKey(active))) active = null;
138
+ updateVisibility();
139
+ };
140
+ return {
141
+ activate: (story) => {
142
+ active = story;
143
+ sync();
144
+ if (!story) return null;
145
+ const view = mounted.get(storyMapKey(story))?.view ?? null;
146
+ if (view) return view;
147
+ active = null;
148
+ updateVisibility();
149
+ return null;
150
+ },
151
+ destroy,
152
+ getActive: () => active,
153
+ getView: (story) => mounted.get(storyMapKey(story))?.view ?? null,
154
+ listStories: () => enumerateDocumentNoteStories(deps.getDocument()),
155
+ snapshotDocument: (document) => {
156
+ let footnotes = document.package.footnotes;
157
+ let endnotes = document.package.endnotes;
158
+ let footnotesChanged = false;
159
+ let endnotesChanged = false;
160
+ for (const story of mounted.values()) {
161
+ if (!story.dirty) continue;
162
+ if (story.note.kind === "footnote") {
163
+ const index = footnotes?.findIndex(({ id }) => id === story.note.noteId) ?? -1;
164
+ const current = index === -1 ? null : footnotes?.at(index);
165
+ if (!current || !footnotes) continue;
166
+ if (!footnotesChanged) {
167
+ footnotes = [...footnotes];
168
+ footnotesChanged = true;
169
+ }
170
+ const updated = {
171
+ ...current,
172
+ content: proseDocToBlocks(story.view.state.doc)
173
+ };
174
+ footnotes[index] = updated;
175
+ story.appliedNote = updated;
176
+ story.appliedContent = updated.content;
177
+ story.appliedProseDocument = noteToProseDocument(updated, story.appliedStyles, story.appliedTheme);
178
+ continue;
179
+ }
180
+ const index = endnotes?.findIndex(({ id }) => id === story.note.noteId) ?? -1;
181
+ const current = index === -1 ? null : endnotes?.at(index);
182
+ if (!current || !endnotes) continue;
183
+ if (!endnotesChanged) {
184
+ endnotes = [...endnotes];
185
+ endnotesChanged = true;
186
+ }
187
+ const updated = {
188
+ ...current,
189
+ content: proseDocToBlocks(story.view.state.doc)
190
+ };
191
+ endnotes[index] = updated;
192
+ story.appliedNote = updated;
193
+ story.appliedContent = updated.content;
194
+ story.appliedProseDocument = noteToProseDocument(updated, story.appliedStyles, story.appliedTheme);
195
+ }
196
+ if (!footnotesChanged && !endnotesChanged) return document;
197
+ return {
198
+ ...document,
199
+ package: {
200
+ ...document.package,
201
+ ...footnotesChanged && footnotes ? { footnotes } : {},
202
+ ...endnotesChanged && endnotes ? { endnotes } : {}
203
+ }
204
+ };
205
+ },
206
+ sync
207
+ };
208
+ };
209
+ //#endregion
210
+ export { createNoteEditorManager, enumerateDocumentNoteStories };
@@ -3,8 +3,8 @@ import { FolioAIEditView } from "./ai-edits/apply.js";
3
3
 
4
4
  //#region src/document-operations.d.ts
5
5
  declare const FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION: 1;
6
- declare const FOLIO_DOCUMENT_OPERATION_TYPES: readonly ["replaceInBlock", "replaceRange", "commentOnRange", "formatRange", "insertAfterBlock", "insertBeforeBlock", "replaceBlock", "deleteBlock", "commentOnBlock", "insertSignatureTable"];
7
- declare const FOLIO_DOCUMENT_OPERATION_MODES: readonly ["direct", "tracked-changes"];
6
+ declare const FOLIO_DOCUMENT_OPERATION_TYPES: readonly ["replaceInBlock", "replaceRange", "commentOnRange", "formatRange", "insertAfterBlock", "insertBeforeBlock", "replaceBlock", "deleteBlock", "commentOnBlock", "insertSignatureTable", "insertTableRow", "deleteTableRow", "insertTableColumn", "deleteTableColumn", "mergeTableCells", "splitTableCell"];
7
+ declare const FOLIO_DOCUMENT_OPERATION_MODES: readonly ["direct", "tracked-changes", "suggested"];
8
8
  declare const FOLIO_DOCUMENT_OPERATION_STORIES: readonly ["main", "header", "footer", "footnote", "endnote"];
9
9
  declare const FOLIO_DOCUMENT_OPERATION_PRECONDITIONS: readonly ["blockTextHash"];
10
10
  declare const FOLIO_DOCUMENT_OPERATION_BATCH_MODES: readonly ["best-effort", "atomic"];
@@ -13,16 +13,22 @@ type FolioDocumentOperationMode = FolioAIEditApplyMode;
13
13
  type FolioDocumentOperationPrecondition = FolioAIEditPrecondition;
14
14
  type FolioDocumentOperationType = FolioDocumentOperation["type"];
15
15
  declare const FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE: Readonly<{
16
- readonly replaceInBlock: readonly ["direct", "tracked-changes"];
17
- readonly replaceRange: readonly ["direct", "tracked-changes"];
16
+ readonly replaceInBlock: readonly ["direct", "tracked-changes", "suggested"];
17
+ readonly replaceRange: readonly ["direct", "tracked-changes", "suggested"];
18
18
  readonly commentOnRange: readonly ["direct", "tracked-changes"];
19
- readonly formatRange: readonly ["direct"];
20
- readonly insertAfterBlock: readonly ["direct", "tracked-changes"];
21
- readonly insertBeforeBlock: readonly ["direct", "tracked-changes"];
22
- readonly replaceBlock: readonly ["direct", "tracked-changes"];
23
- readonly deleteBlock: readonly ["direct", "tracked-changes"];
19
+ readonly formatRange: readonly ["direct", "tracked-changes", "suggested"];
20
+ readonly insertAfterBlock: readonly ["direct", "tracked-changes", "suggested"];
21
+ readonly insertBeforeBlock: readonly ["direct", "tracked-changes", "suggested"];
22
+ readonly replaceBlock: readonly ["direct", "tracked-changes", "suggested"];
23
+ readonly deleteBlock: readonly ["direct", "tracked-changes", "suggested"];
24
24
  readonly commentOnBlock: readonly ["direct", "tracked-changes"];
25
- readonly insertSignatureTable: readonly ["direct"];
25
+ readonly insertSignatureTable: readonly ["direct", "suggested"];
26
+ readonly insertTableRow: readonly ["direct", "tracked-changes", "suggested"];
27
+ readonly deleteTableRow: readonly ["direct", "tracked-changes", "suggested"];
28
+ readonly insertTableColumn: readonly ["direct", "tracked-changes", "suggested"];
29
+ readonly deleteTableColumn: readonly ["direct", "tracked-changes", "suggested"];
30
+ readonly mergeTableCells: readonly ["direct", "tracked-changes"];
31
+ readonly splitTableCell: readonly ["direct", "tracked-changes"];
26
32
  }>;
27
33
  type FolioDocumentOperationCapabilities = {
28
34
  readonly version: typeof FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION;
@@ -96,10 +102,36 @@ type FolioDocumentOperationAffectedTarget = {
96
102
  story: FolioDocumentOperationStory;
97
103
  anchorBlockId: string;
98
104
  position: "before" | "after";
99
- content: "block" | "signatureTable";
105
+ content: "block" | "signatureTable" | "tableRow" | "tableColumn";
100
106
  } | {
101
107
  type: "comment";
102
108
  commentId: number;
109
+ } | {
110
+ type: "tableRow";
111
+ story: FolioDocumentOperationStory;
112
+ anchorBlockId: string;
113
+ effect: "deleted";
114
+ } | {
115
+ type: "tableColumn";
116
+ story: FolioDocumentOperationStory;
117
+ anchorBlockId: string;
118
+ effect: "deleted";
119
+ } | ({
120
+ type: "tableCells";
121
+ story: FolioDocumentOperationStory;
122
+ anchorBlockId: string;
123
+ effect: "merged";
124
+ } & ({
125
+ endAnchorBlockId: string;
126
+ rowCount?: never;
127
+ } | {
128
+ rowCount: number;
129
+ endAnchorBlockId?: never;
130
+ })) | {
131
+ type: "tableCell";
132
+ story: FolioDocumentOperationStory;
133
+ anchorBlockId: string;
134
+ effect: "split";
103
135
  };
104
136
  /** Input-ordered effect receipt for one successfully applied operation. */
105
137
  type FolioDocumentOperationReceipt = {
@@ -12,9 +12,19 @@ const FOLIO_DOCUMENT_OPERATION_TYPES = Object.freeze([
12
12
  "replaceBlock",
13
13
  "deleteBlock",
14
14
  "commentOnBlock",
15
- "insertSignatureTable"
15
+ "insertSignatureTable",
16
+ "insertTableRow",
17
+ "deleteTableRow",
18
+ "insertTableColumn",
19
+ "deleteTableColumn",
20
+ "mergeTableCells",
21
+ "splitTableCell"
22
+ ]);
23
+ const FOLIO_DOCUMENT_OPERATION_MODES = Object.freeze([
24
+ "direct",
25
+ "tracked-changes",
26
+ "suggested"
16
27
  ]);
17
- const FOLIO_DOCUMENT_OPERATION_MODES = Object.freeze(["direct", "tracked-changes"]);
18
28
  const FOLIO_DOCUMENT_OPERATION_STORIES = Object.freeze([
19
29
  "main",
20
30
  "header",
@@ -24,19 +34,26 @@ const FOLIO_DOCUMENT_OPERATION_STORIES = Object.freeze([
24
34
  ]);
25
35
  const FOLIO_DOCUMENT_OPERATION_PRECONDITIONS = Object.freeze(["blockTextHash"]);
26
36
  const FOLIO_DOCUMENT_OPERATION_BATCH_MODES = Object.freeze(["best-effort", "atomic"]);
27
- const DIRECT_AND_TRACKED_MODES = FOLIO_DOCUMENT_OPERATION_MODES;
28
- const DIRECT_ONLY_MODES = Object.freeze(["direct"]);
37
+ const DIRECT_AND_TRACKED_MODES = Object.freeze(["direct", "tracked-changes"]);
38
+ const DIRECT_TRACKED_AND_SUGGESTED_MODES = FOLIO_DOCUMENT_OPERATION_MODES;
39
+ const DIRECT_AND_SUGGESTED_MODES = Object.freeze(["direct", "suggested"]);
29
40
  const FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE = Object.freeze({
30
- replaceInBlock: DIRECT_AND_TRACKED_MODES,
31
- replaceRange: DIRECT_AND_TRACKED_MODES,
41
+ replaceInBlock: DIRECT_TRACKED_AND_SUGGESTED_MODES,
42
+ replaceRange: DIRECT_TRACKED_AND_SUGGESTED_MODES,
32
43
  commentOnRange: DIRECT_AND_TRACKED_MODES,
33
- formatRange: DIRECT_ONLY_MODES,
34
- insertAfterBlock: DIRECT_AND_TRACKED_MODES,
35
- insertBeforeBlock: DIRECT_AND_TRACKED_MODES,
36
- replaceBlock: DIRECT_AND_TRACKED_MODES,
37
- deleteBlock: DIRECT_AND_TRACKED_MODES,
44
+ formatRange: DIRECT_TRACKED_AND_SUGGESTED_MODES,
45
+ insertAfterBlock: DIRECT_TRACKED_AND_SUGGESTED_MODES,
46
+ insertBeforeBlock: DIRECT_TRACKED_AND_SUGGESTED_MODES,
47
+ replaceBlock: DIRECT_TRACKED_AND_SUGGESTED_MODES,
48
+ deleteBlock: DIRECT_TRACKED_AND_SUGGESTED_MODES,
38
49
  commentOnBlock: DIRECT_AND_TRACKED_MODES,
39
- insertSignatureTable: DIRECT_ONLY_MODES
50
+ insertSignatureTable: DIRECT_AND_SUGGESTED_MODES,
51
+ insertTableRow: DIRECT_TRACKED_AND_SUGGESTED_MODES,
52
+ deleteTableRow: DIRECT_TRACKED_AND_SUGGESTED_MODES,
53
+ insertTableColumn: DIRECT_TRACKED_AND_SUGGESTED_MODES,
54
+ deleteTableColumn: DIRECT_TRACKED_AND_SUGGESTED_MODES,
55
+ mergeTableCells: DIRECT_AND_TRACKED_MODES,
56
+ splitTableCell: DIRECT_AND_TRACKED_MODES
40
57
  });
41
58
  const DOCUMENT_OPERATION_CAPABILITIES = Object.freeze({
42
59
  version: 1,
@@ -51,8 +68,8 @@ const DOCUMENT_OPERATION_CAPABILITIES = Object.freeze({
51
68
  const getFolioDocumentOperationCapabilities = () => DOCUMENT_OPERATION_CAPABILITIES;
52
69
  const includesDocumentOperationMode = (supportedModes, mode) => supportedModes.includes(mode);
53
70
  const isFolioDocumentOperationModeSupported = (operationType, mode) => {
71
+ if (!Object.hasOwn(FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, operationType)) return false;
54
72
  const supportedModes = FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE[operationType];
55
- if (supportedModes === void 0) return false;
56
73
  return includesDocumentOperationMode(supportedModes, mode);
57
74
  };
58
75
  const isSupportedFolioDocumentOperationVersion = (value) => value === 1;
@@ -94,6 +111,15 @@ const readOptionalBoolean = (value, key, path) => {
94
111
  if (typeof candidate === "boolean") return candidate;
95
112
  return invalidBatch(`${path}.${key}`, "expected a boolean when provided");
96
113
  };
114
+ const readOptionalStringArray = (value, key, path) => {
115
+ const candidate = value[key];
116
+ if (candidate === void 0) return;
117
+ if (!Array.isArray(candidate)) return invalidBatch(`${path}.${key}`, "expected an array when provided");
118
+ return candidate.map((item, index) => {
119
+ if (typeof item === "string") return item;
120
+ return invalidBatch(`${path}.${key}[${index}]`, "expected a string");
121
+ });
122
+ };
97
123
  const readNonNegativeInteger = (value, key, path) => {
98
124
  const candidate = value[key];
99
125
  if (typeof candidate === "number" && Number.isInteger(candidate) && candidate >= 0) return candidate;
@@ -183,7 +209,8 @@ const COMMON_OPERATION_KEYS = [
183
209
  "blockId",
184
210
  "severity",
185
211
  "area",
186
- "precondition"
212
+ "precondition",
213
+ "suggestionId"
187
214
  ];
188
215
  const parseSignatureParties = (value, path) => {
189
216
  const parties = value["parties"];
@@ -211,10 +238,12 @@ const parseDocumentOperation = (value, index) => {
211
238
  const type = readString(value, "type", path);
212
239
  const reviewMeta = readReviewMeta(value, path);
213
240
  const precondition = readOptionalPrecondition(value, path);
241
+ const suggestionId = readOptionalString(value, "suggestionId", path);
214
242
  const comment = readOptionalComment(value, path);
215
243
  const operationMeta = {
216
244
  ...reviewMeta,
217
- ...precondition !== void 0 && { precondition }
245
+ ...precondition !== void 0 && { precondition },
246
+ ...suggestionId !== void 0 && { suggestionId }
218
247
  };
219
248
  if (type === "replaceRange") {
220
249
  assertAllowedKeys(value, path, [
@@ -225,7 +254,8 @@ const parseDocumentOperation = (value, index) => {
225
254
  "comment",
226
255
  "severity",
227
256
  "area",
228
- "precondition"
257
+ "precondition",
258
+ "suggestionId"
229
259
  ]);
230
260
  return {
231
261
  ...operationMeta,
@@ -263,7 +293,8 @@ const parseDocumentOperation = (value, index) => {
263
293
  "formatting",
264
294
  "severity",
265
295
  "area",
266
- "precondition"
296
+ "precondition",
297
+ "suggestionId"
267
298
  ]);
268
299
  return {
269
300
  ...operationMeta,
@@ -382,6 +413,98 @@ const parseDocumentOperation = (value, index) => {
382
413
  ...comment !== void 0 && { comment }
383
414
  };
384
415
  }
416
+ if (type === "insertTableRow") {
417
+ assertAllowedKeys(value, path, [
418
+ ...COMMON_OPERATION_KEYS,
419
+ "position",
420
+ "cellTexts"
421
+ ]);
422
+ const position = value["position"];
423
+ if (position !== void 0 && position !== "after" && position !== "before") return invalidBatch(`${path}.position`, "expected \"after\" or \"before\" when provided");
424
+ const cellTexts = readOptionalStringArray(value, "cellTexts", path);
425
+ return {
426
+ ...operationMeta,
427
+ id,
428
+ type,
429
+ blockId,
430
+ ...position !== void 0 && { position },
431
+ ...cellTexts !== void 0 && { cellTexts }
432
+ };
433
+ }
434
+ if (type === "deleteTableRow") {
435
+ assertAllowedKeys(value, path, COMMON_OPERATION_KEYS);
436
+ return {
437
+ ...operationMeta,
438
+ id,
439
+ type,
440
+ blockId
441
+ };
442
+ }
443
+ if (type === "insertTableColumn") {
444
+ assertAllowedKeys(value, path, [
445
+ ...COMMON_OPERATION_KEYS,
446
+ "position",
447
+ "cellTexts"
448
+ ]);
449
+ const position = value["position"];
450
+ if (position !== void 0 && position !== "after" && position !== "before") return invalidBatch(`${path}.position`, "expected \"after\" or \"before\" when provided");
451
+ const cellTexts = readOptionalStringArray(value, "cellTexts", path);
452
+ return {
453
+ ...operationMeta,
454
+ id,
455
+ type,
456
+ blockId,
457
+ ...position !== void 0 && { position },
458
+ ...cellTexts !== void 0 && { cellTexts }
459
+ };
460
+ }
461
+ if (type === "deleteTableColumn") {
462
+ assertAllowedKeys(value, path, COMMON_OPERATION_KEYS);
463
+ return {
464
+ ...operationMeta,
465
+ id,
466
+ type,
467
+ blockId
468
+ };
469
+ }
470
+ if (type === "mergeTableCells") {
471
+ assertAllowedKeys(value, path, [
472
+ ...COMMON_OPERATION_KEYS,
473
+ "endBlockId",
474
+ "rowCount"
475
+ ]);
476
+ const endBlockId = readOptionalString(value, "endBlockId", path);
477
+ const rawRowCount = value["rowCount"];
478
+ if (endBlockId === void 0 === (rawRowCount === void 0)) return invalidBatch(path, "expected exactly one of endBlockId or rowCount");
479
+ if (endBlockId !== void 0) {
480
+ if (endBlockId.length === 0) return invalidBatch(`${path}.endBlockId`, "expected a non-empty string");
481
+ return {
482
+ ...operationMeta,
483
+ id,
484
+ type,
485
+ blockId,
486
+ endBlockId
487
+ };
488
+ }
489
+ const rowCount = readNonNegativeInteger(value, "rowCount", path);
490
+ if (rowCount < 2) return invalidBatch(`${path}.rowCount`, "expected an integer greater than or equal to 2");
491
+ return {
492
+ ...operationMeta,
493
+ id,
494
+ type,
495
+ blockId,
496
+ rowCount
497
+ };
498
+ }
499
+ if (type === "splitTableCell") {
500
+ assertAllowedKeys(value, path, COMMON_OPERATION_KEYS);
501
+ return {
502
+ ...operationMeta,
503
+ id,
504
+ type,
505
+ blockId
506
+ };
507
+ }
385
508
  return invalidBatch(`${path}.type`, `unsupported operation type "${type}"`);
386
509
  };
387
510
  const parseFolioDocumentOperationBatch = (value) => {
@@ -397,7 +520,7 @@ const parseFolioDocumentOperationBatch = (value) => {
397
520
  const operations = value["operations"];
398
521
  if (!Array.isArray(operations)) return invalidBatch("$.operations", "expected an array");
399
522
  const mode = value["mode"];
400
- if (mode !== void 0 && mode !== "direct" && mode !== "tracked-changes") return invalidBatch("$.mode", "expected \"direct\" or \"tracked-changes\" when provided");
523
+ if (mode !== void 0 && mode !== "direct" && mode !== "tracked-changes" && mode !== "suggested") return invalidBatch("$.mode", "expected \"direct\", \"tracked-changes\", or \"suggested\" when provided");
401
524
  const atomic = readOptionalBoolean(value, "atomic", "$");
402
525
  const dryRun = readOptionalBoolean(value, "dryRun", "$");
403
526
  const parsedOperations = operations.map(parseDocumentOperation);
@@ -498,6 +621,51 @@ const getPrimaryAffectedTarget = (operation, story) => {
498
621
  position: operation.position ?? "after",
499
622
  content: "signatureTable"
500
623
  };
624
+ case "insertTableRow": return {
625
+ type: "insertion",
626
+ story,
627
+ anchorBlockId: operation.blockId,
628
+ position: operation.position ?? "after",
629
+ content: "tableRow"
630
+ };
631
+ case "deleteTableRow": return {
632
+ type: "tableRow",
633
+ story,
634
+ anchorBlockId: operation.blockId,
635
+ effect: "deleted"
636
+ };
637
+ case "insertTableColumn": return {
638
+ type: "insertion",
639
+ story,
640
+ anchorBlockId: operation.blockId,
641
+ position: operation.position ?? "after",
642
+ content: "tableColumn"
643
+ };
644
+ case "deleteTableColumn": return {
645
+ type: "tableColumn",
646
+ story,
647
+ anchorBlockId: operation.blockId,
648
+ effect: "deleted"
649
+ };
650
+ case "mergeTableCells": return operation.rowCount !== void 0 ? {
651
+ type: "tableCells",
652
+ story,
653
+ anchorBlockId: operation.blockId,
654
+ rowCount: operation.rowCount,
655
+ effect: "merged"
656
+ } : {
657
+ type: "tableCells",
658
+ story,
659
+ anchorBlockId: operation.blockId,
660
+ endAnchorBlockId: operation.endBlockId,
661
+ effect: "merged"
662
+ };
663
+ case "splitTableCell": return {
664
+ type: "tableCell",
665
+ story,
666
+ anchorBlockId: operation.blockId,
667
+ effect: "split"
668
+ };
501
669
  }
502
670
  };
503
671
  /** Build deterministic affected-target receipts from operations and their applied entries. */
@@ -1,10 +1,10 @@
1
1
  import { elementToXml, findChild, getChildElements, getLocalName, mergeXmlnsDeclarations } from "./xmlParser.js";
2
+ import { padDecimal } from "./numberingParser.js";
2
3
  import { parseBookmarkEnd, parseBookmarkStart } from "./bookmarkParser.js";
3
4
  import { parseSdtProperties } from "./sdtProperties.js";
4
5
  import { parseParagraph } from "./paragraphParser.js";
5
6
  import { appendBookmarkMarkerToLastParagraphInBlocks, prependBookmarkMarkersToFirstParagraphInBlocks } from "./bookmarkPlacement.js";
6
7
  import { convertBulletToUnicode } from "./bulletMarkers.js";
7
- import { padDecimal } from "./numberingParser.js";
8
8
  import { enrichParagraphTextBoxes } from "./paragraphTextBoxEnrichment.js";
9
9
  import { parseTable } from "./tableParser.js";
10
10
  //#region src/docx/blockContentParser.ts
@@ -53,7 +53,7 @@ const formatNumber = (value, numFmt) => {
53
53
  default: return String(value);
54
54
  }
55
55
  };
56
- const computeListMarker = (paragraph, { numbering, listCounters, abstractCounters, restartedNumIds, previousList }) => {
56
+ const computeListMarker = (paragraph, { numbering, listCounters, abstractCounters, restartedNumIds, previousList, siblingNumIdsByAbstractNumId }) => {
57
57
  const listRendering = paragraph.listRendering;
58
58
  if (!listRendering || !numbering) {
59
59
  previousList.abstractNumId = null;
@@ -73,6 +73,14 @@ const computeListMarker = (paragraph, { numbering, listCounters, abstractCounter
73
73
  const counters = listCounters.get(numId);
74
74
  if (!counters) return;
75
75
  const abstractNumId = numbering.getAbstractNumId(numId);
76
+ if (firstEncounter && abstractNumId !== null) {
77
+ let siblingNumIds = siblingNumIdsByAbstractNumId.get(abstractNumId);
78
+ if (!siblingNumIds) {
79
+ siblingNumIds = /* @__PURE__ */ new Set();
80
+ siblingNumIdsByAbstractNumId.set(abstractNumId, siblingNumIds);
81
+ }
82
+ siblingNumIds.add(numId);
83
+ }
76
84
  const styleNumbering = paragraph.formatting?.numPrFromStyle;
77
85
  let resumedAbstractCounters;
78
86
  const resumesRestartedInstance = firstEncounter && listRendering.startOverride === void 0 && abstractNumId !== null && previousList.abstractNumId === abstractNumId && previousList.numId !== null && previousList.numId !== numId && restartedNumIds.has(previousList.numId);
@@ -101,9 +109,13 @@ const computeListMarker = (paragraph, { numbering, listCounters, abstractCounter
101
109
  counters[level + 1] = (childCounter === void 0 || Number.isNaN(childCounter) ? 0 : childCounter) + childAdvances;
102
110
  }
103
111
  if (abstractNumId !== null) {
104
- if (resumedAbstractCounters) for (const [otherNumId, otherCounters] of listCounters) {
105
- if (otherNumId === numId || numbering.getAbstractNumId(otherNumId) !== abstractNumId || !otherCounters.every((value, index) => Object.is(value, resumedAbstractCounters[index]))) continue;
106
- for (let i = 0; i < otherCounters.length; i += 1) otherCounters[i] = counters[i] ?? NaN;
112
+ if (resumedAbstractCounters) {
113
+ const siblingNumIds = siblingNumIdsByAbstractNumId.get(abstractNumId);
114
+ for (const otherNumId of siblingNumIds ?? []) {
115
+ const otherCounters = listCounters.get(otherNumId);
116
+ if (otherNumId === numId || !otherCounters || !otherCounters.every((value, index) => Object.is(value, resumedAbstractCounters[index]))) continue;
117
+ for (let i = 0; i < otherCounters.length; i += 1) otherCounters[i] = counters[i] ?? NaN;
118
+ }
107
119
  }
108
120
  abstractCounters.set(abstractNumId, [...counters]);
109
121
  }
@@ -140,6 +152,7 @@ const parseBlockContent = (parent, styles, theme, numbering, rels, media, option
140
152
  fromStyle: false,
141
153
  numId: null
142
154
  },
155
+ siblingNumIdsByAbstractNumId: /* @__PURE__ */ new Map(),
143
156
  options: {
144
157
  ...options,
145
158
  rootXmlns: mergeXmlnsDeclarations(options?.rootXmlns ?? {}, parent)
@@ -154,13 +167,14 @@ const parseBlockContentWithState = (parent, styles, theme, numbering, rels, medi
154
167
  if (localName === "p") {
155
168
  const paragraph = parseParagraph(child, styles, theme, numbering, rels, media, state.options);
156
169
  prependPendingBookmarkMarkers(paragraph, pendingBookmarkMarkers);
157
- enrichParagraphTextBoxes(paragraph, child, styles, theme, numbering, rels, media);
170
+ enrichParagraphTextBoxes(paragraph, child, styles, theme, numbering, rels, media, parseTable);
158
171
  computeListMarker(paragraph, {
159
172
  numbering,
160
173
  listCounters: state.listCounters,
161
174
  abstractCounters: state.abstractCounters,
162
175
  restartedNumIds: state.restartedNumIds,
163
- previousList: state.previousList
176
+ previousList: state.previousList,
177
+ siblingNumIdsByAbstractNumId: state.siblingNumIdsByAbstractNumId
164
178
  });
165
179
  content.push(paragraph);
166
180
  continue;
@@ -75,7 +75,8 @@ function parseComments(commentsXml, styles, theme, rels, media, commentsExtensib
75
75
  for (const child of children) {
76
76
  if ((child.name?.replace(/^.*:/u, "") ?? "") !== "comment") continue;
77
77
  const id = Number.parseInt(getAttribute(child, "w", "id") ?? "0", 10);
78
- const author = getAttribute(child, "w", "author")?.trim() || "Unknown";
78
+ const rawAuthor = getAttribute(child, "w", "author");
79
+ const author = parseCommentAuthor(rawAuthor);
79
80
  const rawInitials = getAttribute(child, "w", "initials");
80
81
  const initials = rawInitials !== null ? String(rawInitials) : void 0;
81
82
  const rawDate = getAttribute(child, "w", "date");
@@ -123,5 +124,9 @@ function parseComments(commentsXml, styles, theme, rels, media, commentsExtensib
123
124
  }
124
125
  return comments;
125
126
  }
127
+ const parseCommentAuthor = (author) => {
128
+ if (author === "") return "";
129
+ return author?.trim() || "Unknown";
130
+ };
126
131
  //#endregion
127
132
  export { parseComments, parseCommentsExtended };
@@ -0,0 +1,6 @@
1
+ import { document_d_exports } from "../types/document.js";
2
+
3
+ //#region src/docx/commentRangeIntegrity.d.ts
4
+ declare const withoutOrphanCommentRanges: (doc: document_d_exports.Document) => document_d_exports.Document;
5
+ //#endregion
6
+ export { withoutOrphanCommentRanges };