@stll/folio-core 0.35.1 → 0.37.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 (236) hide show
  1. package/README.md +59 -1
  2. package/dist/ai-edits/apply.js +878 -377
  3. package/dist/ai-edits/block-identity.d.ts +4 -1
  4. package/dist/ai-edits/block-identity.js +4 -1
  5. package/dist/ai-edits/blockRange.js +14 -14
  6. package/dist/ai-edits/clean-text.d.ts +40 -1
  7. package/dist/ai-edits/clean-text.js +52 -2
  8. package/dist/ai-edits/headless.d.ts +3 -1
  9. package/dist/ai-edits/headless.js +141 -73
  10. package/dist/ai-edits/index.d.ts +3 -3
  11. package/dist/ai-edits/index.js +2 -2
  12. package/dist/ai-edits/read.js +38 -20
  13. package/dist/ai-edits/snapshot.d.ts +14 -6
  14. package/dist/ai-edits/snapshot.js +105 -20
  15. package/dist/ai-edits/table-cell-mutations.js +1 -1
  16. package/dist/ai-edits/table-row-column-mutations.js +7 -0
  17. package/dist/ai-edits/table-template.d.ts +11 -1
  18. package/dist/ai-edits/table-template.js +49 -17
  19. package/dist/ai-edits/types.d.ts +62 -61
  20. package/dist/ai-edits/word-diff.d.ts +18 -3
  21. package/dist/ai-edits/word-diff.js +556 -67
  22. package/dist/ai-suggestions/conflict.js +1 -4
  23. package/dist/ai-suggestions/text-positions.d.ts +8 -0
  24. package/dist/ai-suggestions/text-positions.js +27 -5
  25. package/dist/compare/__fixtures__/body-sequence.js +3 -4
  26. package/dist/compare/column-alignment.d.ts +13 -13
  27. package/dist/compare/column-alignment.js +78 -39
  28. package/dist/compare/compare.d.ts +4 -3
  29. package/dist/compare/compare.js +48 -21
  30. package/dist/compare/content-alignment.d.ts +95 -0
  31. package/dist/compare/content-alignment.js +1450 -0
  32. package/dist/compare/content-types.d.ts +100 -0
  33. package/dist/compare/content-types.js +0 -0
  34. package/dist/compare/content.d.ts +209 -0
  35. package/dist/compare/content.js +885 -0
  36. package/dist/compare/formatting.d.ts +5 -5
  37. package/dist/compare/formatting.js +6 -4
  38. package/dist/compare/plan.d.ts +6 -1
  39. package/dist/compare/plan.js +171 -566
  40. package/dist/compare/scenario.d.ts +2 -2
  41. package/dist/compare/types.d.ts +3 -3
  42. package/dist/compare/verification.d.ts +8 -9
  43. package/dist/compare/verification.js +72 -50
  44. package/dist/compat/eigenpal.d.ts +5 -3
  45. package/dist/compat/eigenpal.js +3 -2
  46. package/dist/controller/headerFooterEditorManager.js +18 -10
  47. package/dist/controller/hiddenEditorApi.js +1 -1
  48. package/dist/controller/hiddenEditorManager.d.ts +7 -2
  49. package/dist/controller/hiddenEditorManager.js +15 -6
  50. package/dist/controller/layoutPipeline.js +5 -3
  51. package/dist/controller/noteEditorManager.js +12 -7
  52. package/dist/display-list/build/headerFooterPrimitives.js +1 -0
  53. package/dist/display-list/build/storyPrimitives.d.ts +5 -2
  54. package/dist/display-list/build/storyPrimitives.js +60 -3
  55. package/dist/display-list/build/tablePrimitives.js +30 -0
  56. package/dist/display-list/primitives.d.ts +1 -1
  57. package/dist/document-operations.d.ts +8 -4
  58. package/dist/document-operations.js +104 -12
  59. package/dist/docx/blockContentParser.js +6 -27
  60. package/dist/docx/commentParser.js +2 -4
  61. package/dist/docx/commentRangeIntegrity.js +2 -4
  62. package/dist/docx/documentClone.d.ts +2 -0
  63. package/dist/docx/documentClone.js +2 -0
  64. package/dist/docx/ensureParaIds.js +9 -4
  65. package/dist/docx/headerFooterParser.js +2 -4
  66. package/dist/docx/normalizeBaseDirection.js +5 -7
  67. package/dist/docx/numberingParser.d.ts +3 -1
  68. package/dist/docx/numberingParser.js +4 -1
  69. package/dist/docx/paragraphParser.js +34 -35
  70. package/dist/docx/paragraphPropertySource.d.ts +49 -0
  71. package/dist/docx/paragraphPropertySource.js +113 -0
  72. package/dist/docx/paragraphTraversal.js +30 -34
  73. package/dist/docx/rezip.d.ts +0 -8
  74. package/dist/docx/rezip.js +41 -16
  75. package/dist/docx/runConsolidator.js +2 -4
  76. package/dist/docx/runParser.js +6 -17
  77. package/dist/docx/sectionParser.js +1 -15
  78. package/dist/docx/serializer/paragraphSerializer.js +289 -30
  79. package/dist/docx/serializer/runSerializer.js +6 -12
  80. package/dist/docx/serializer/sectionPropertiesSerializer.js +2 -10
  81. package/dist/docx/serializer/tableSerializer.js +4 -23
  82. package/dist/docx/serializer/trackedChangeAttributes.d.ts +11 -0
  83. package/dist/docx/serializer/trackedChangeAttributes.js +31 -0
  84. package/dist/docx/server/build.d.ts +1 -1
  85. package/dist/docx/server/createBilingualDocument.js +8 -10
  86. package/dist/docx/server/evaluateDocxXmlPatchProposal.js +22 -13
  87. package/dist/docx/server/validateDocxConformance.js +17 -13
  88. package/dist/docx/tableParser.js +1 -37
  89. package/dist/docx/trackedChangeInfo.d.ts +11 -0
  90. package/dist/docx/trackedChangeInfo.js +38 -0
  91. package/dist/docx/verbatimCapture.d.ts +20 -9
  92. package/dist/docx/verbatimCapture.js +208 -8
  93. package/dist/docx/xmlParser.d.ts +3 -1
  94. package/dist/docx/xmlParser.js +6 -1
  95. package/dist/docx/xmlSafety.d.ts +1 -1
  96. package/dist/docx/xmlSafety.js +157 -0
  97. package/dist/headless-layout.js +5 -4
  98. package/dist/index.d.ts +5 -3
  99. package/dist/index.js +3 -2
  100. package/dist/internal/headlessRevisionResolution.d.ts +23 -0
  101. package/dist/internal/headlessRevisionResolution.js +155 -0
  102. package/dist/internal/headlessRevisionResolutionGuard.d.ts +12 -0
  103. package/dist/internal/headlessRevisionResolutionGuard.js +28 -0
  104. package/dist/internal/pageBreakRunDescendantIndex.d.ts +9 -0
  105. package/dist/internal/pageBreakRunDescendantIndex.js +27 -0
  106. package/dist/internal/pageBreakRunPartition.d.ts +26 -0
  107. package/dist/internal/pageBreakRunPartition.js +35 -0
  108. package/dist/internal/pageBreakRunSourceDescendantIndex.d.ts +15 -0
  109. package/dist/internal/pageBreakRunSourceDescendantIndex.js +126 -0
  110. package/dist/internal/sectionEndpointResolution.d.ts +32 -0
  111. package/dist/internal/sectionEndpointResolution.js +38 -0
  112. package/dist/layout-bridge/convert/footnoteLayout.js +1 -0
  113. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +16 -4
  114. package/dist/layout-bridge/convert/headerFooterLayout.js +52 -9
  115. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +4 -0
  116. package/dist/layout-bridge/convert/toFlowBlocks.js +391 -82
  117. package/dist/layout-bridge/dom/clickToPositionDom.d.ts +8 -1
  118. package/dist/layout-bridge/dom/clickToPositionDom.js +114 -40
  119. package/dist/layout-bridge/dom/textStreamDom.d.ts +24 -0
  120. package/dist/layout-bridge/dom/textStreamDom.js +75 -0
  121. package/dist/layout-bridge/headerFooterLayout.js +16 -30
  122. package/dist/layout-engine/index.js +12 -3
  123. package/dist/layout-engine/measure/tableFragmentBorderGeometry.d.ts +17 -0
  124. package/dist/layout-engine/measure/tableFragmentBorderGeometry.js +24 -0
  125. package/dist/layout-engine/renderedBreakReconciliation.js +1 -1
  126. package/dist/layout-engine/types.d.ts +7 -0
  127. package/dist/layout-painter/imageLayout.d.ts +1 -1
  128. package/dist/layout-painter/renderTable.js +20 -0
  129. package/dist/markdown/renderBlock.js +7 -10
  130. package/dist/model.d.ts +1 -1
  131. package/dist/paged-layout/rangeProjection.js +6 -9
  132. package/dist/paged-layout/transactionDirtyRange.d.ts +3 -1
  133. package/dist/paged-layout/transactionDirtyRange.js +23 -1
  134. package/dist/prosemirror/attrs/index.d.ts +7 -3
  135. package/dist/prosemirror/attrs/index.js +128 -7
  136. package/dist/prosemirror/bookmarkBoundaryIntegrity.d.ts +9 -0
  137. package/dist/prosemirror/bookmarkBoundaryIntegrity.js +22 -0
  138. package/dist/prosemirror/commands/comments.d.ts +10 -1
  139. package/dist/prosemirror/commands/comments.js +551 -87
  140. package/dist/prosemirror/commands/formatPainter.d.ts +45 -10
  141. package/dist/prosemirror/commands/formatPainter.js +319 -63
  142. package/dist/prosemirror/commands/index.d.ts +2 -2
  143. package/dist/prosemirror/commands/pageBreak.d.ts +5 -2
  144. package/dist/prosemirror/commands/pageBreak.js +18 -36
  145. package/dist/prosemirror/commands/propertyChangeScope.d.ts +27 -3
  146. package/dist/prosemirror/commands/propertyChangeScope.js +85 -14
  147. package/dist/prosemirror/conversion/fromProseDoc.d.ts +8 -5
  148. package/dist/prosemirror/conversion/fromProseDoc.js +935 -223
  149. package/dist/prosemirror/conversion/runShadingMark.js +2 -2
  150. package/dist/prosemirror/conversion/toProseDoc.d.ts +26 -1
  151. package/dist/prosemirror/conversion/toProseDoc.js +439 -291
  152. package/dist/prosemirror/extensions/StarterKit.js +4 -0
  153. package/dist/prosemirror/extensions/core/ParagraphExtension.js +54 -6
  154. package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +7 -1
  155. package/dist/prosemirror/extensions/features/ListExtension.js +95 -123
  156. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +19 -6
  157. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +27 -1
  158. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +134 -30
  159. package/dist/prosemirror/extensions/features/pasteCleanup.js +9 -15
  160. package/dist/prosemirror/extensions/marks/BoldExtension.js +4 -3
  161. package/dist/prosemirror/extensions/marks/CharacterStyleExtension.d.ts +4 -7
  162. package/dist/prosemirror/extensions/marks/CharacterStyleExtension.js +5 -11
  163. package/dist/prosemirror/extensions/marks/FontSizeExtension.js +3 -3
  164. package/dist/prosemirror/extensions/marks/ItalicExtension.js +4 -3
  165. package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.d.ts +13 -0
  166. package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.js +39 -0
  167. package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.d.ts +7 -1
  168. package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.js +67 -21
  169. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +2 -0
  170. package/dist/prosemirror/extensions/marks/markUtils.d.ts +8 -1
  171. package/dist/prosemirror/extensions/marks/markUtils.js +88 -2
  172. package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.js +44 -3
  173. package/dist/prosemirror/extensions/nodes/FieldExtension.js +1 -1
  174. package/dist/prosemirror/extensions/nodes/HardBreakExtension.js +15 -4
  175. package/dist/prosemirror/extensions/nodes/PageBreakExtension.d.ts +6 -0
  176. package/dist/prosemirror/extensions/nodes/PageBreakExtension.js +6 -0
  177. package/dist/prosemirror/extensions/nodes/PageBreakRunExtension.d.ts +6 -0
  178. package/dist/prosemirror/extensions/nodes/PageBreakRunExtension.js +36 -0
  179. package/dist/prosemirror/findReplaceSelection.js +8 -3
  180. package/dist/prosemirror/index.d.ts +3 -3
  181. package/dist/prosemirror/listMarker.d.ts +26 -1
  182. package/dist/prosemirror/listMarker.js +108 -14
  183. package/dist/prosemirror/pageBreakRunProjection.d.ts +28 -0
  184. package/dist/prosemirror/pageBreakRunProjection.js +47 -0
  185. package/dist/prosemirror/paraText.js +6 -0
  186. package/dist/prosemirror/paragraphAlignment.d.ts +12 -0
  187. package/dist/prosemirror/paragraphAlignment.js +13 -0
  188. package/dist/prosemirror/paragraphSpacing.d.ts +29 -0
  189. package/dist/prosemirror/paragraphSpacing.js +125 -0
  190. package/dist/prosemirror/plugins/documentNumbering.d.ts +8 -0
  191. package/dist/prosemirror/plugins/documentNumbering.js +18 -0
  192. package/dist/prosemirror/plugins/pmTextScan.d.ts +3 -2
  193. package/dist/prosemirror/plugins/pmTextScan.js +14 -4
  194. package/dist/prosemirror/plugins/suggestionMode.js +9 -11
  195. package/dist/prosemirror/rebaseParagraphRunFormatting.d.ts +16 -0
  196. package/dist/prosemirror/rebaseParagraphRunFormatting.js +61 -0
  197. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +64 -0
  198. package/dist/prosemirror/runFormattingInlineCarriers.js +121 -0
  199. package/dist/prosemirror/runFormattingProvenance.d.ts +12 -0
  200. package/dist/prosemirror/runFormattingProvenance.js +48 -0
  201. package/dist/prosemirror/runFormattingReconciliation.d.ts +25 -0
  202. package/dist/prosemirror/runFormattingReconciliation.js +54 -0
  203. package/dist/prosemirror/runPropertyChangeResolution.d.ts +18 -0
  204. package/dist/prosemirror/runPropertyChangeResolution.js +18 -0
  205. package/dist/prosemirror/runStyleFormatting.d.ts +50 -0
  206. package/dist/prosemirror/runStyleFormatting.js +105 -0
  207. package/dist/prosemirror/schema/index.d.ts +3 -3
  208. package/dist/prosemirror/schema/marks.d.ts +84 -9
  209. package/dist/prosemirror/schema/marks.js +73 -1
  210. package/dist/prosemirror/schema/nodes.d.ts +30 -6
  211. package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +14 -2
  212. package/dist/prosemirror/styles/resolvedStyleAttrs.js +45 -23
  213. package/dist/prosemirror/styles/styleResolver.d.ts +10 -13
  214. package/dist/prosemirror/styles/styleResolver.js +3 -3
  215. package/dist/prosemirror/styles/styleToggleCascade.d.ts +8 -1
  216. package/dist/prosemirror/styles/styleToggleCascade.js +24 -1
  217. package/dist/prosemirror/tableGridMutation.d.ts +20 -0
  218. package/dist/prosemirror/tableGridMutation.js +30 -0
  219. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +31 -0
  220. package/dist/prosemirror/trackedRunInlineAtoms.js +39 -0
  221. package/dist/prosemirror/utils/visualLineNavigation.js +27 -31
  222. package/dist/prosemirror/validation.js +23 -4
  223. package/dist/redline.js +4 -1
  224. package/dist/render-dom/HeaderFooterSelectionOverlay.js +20 -20
  225. package/dist/render-dom/RenderedDomContext.js +17 -34
  226. package/dist/server.d.ts +4 -4
  227. package/dist/server.js +2 -2
  228. package/dist/style-engine/styleEngine.d.ts +1 -1
  229. package/dist/utils/clipboard.js +1 -1
  230. package/dist/utils/findReplace.js +38 -21
  231. package/dist/utils/mergeDocumentContent.js +3 -3
  232. package/dist/utils/replaceText.js +2 -1
  233. package/dist/version-comparison.d.ts +38 -44
  234. package/dist/version-comparison.js +270 -399
  235. package/dist/watermark/index.js +2 -4
  236. package/package.json +8 -2
@@ -1,8 +1,165 @@
1
1
  import { XMLValidator } from "fast-xml-parser";
2
2
  //#region src/docx/xmlSafety.ts
3
3
  const DOCTYPE_PATTERN = /<!DOCTYPE(?:\s|>)/iu;
4
+ const BUILT_IN_ENTITIES = /* @__PURE__ */ new Set([
5
+ "amp",
6
+ "apos",
7
+ "gt",
8
+ "lt",
9
+ "quot"
10
+ ]);
11
+ const DECIMAL_CHARACTER_REFERENCE = /^#[0-9]+$/u;
12
+ const HEX_CHARACTER_REFERENCE = /^#[xX][0-9A-Fa-f]+$/u;
13
+ const NCNAME = /^[\p{L}_][\p{L}\p{N}._\-\u00b7\p{M}]*$/u;
14
+ const BYTE_ORDER_MARK = "";
15
+ const ENCODING_NAME = String.raw`[A-Za-z][A-Za-z0-9._-]*`;
16
+ const XML_DECLARATION = new RegExp(String.raw`^<\?xml[ \t\r\n]+version[ \t\r\n]*=[ \t\r\n]*(?:"1\.0"|'1\.0')(?:[ \t\r\n]+encoding[ \t\r\n]*=[ \t\r\n]*(?:"${ENCODING_NAME}"|'${ENCODING_NAME}'))?(?:[ \t\r\n]+standalone[ \t\r\n]*=[ \t\r\n]*(?:"(?:yes|no)"|'(?:yes|no)'))?[ \t\r\n]*\?>$`, "u");
17
+ const isXmlCharacter = (codePoint) => codePoint === 9 || codePoint === 10 || codePoint === 13 || codePoint >= 32 && codePoint <= 55295 || codePoint >= 57344 && codePoint <= 65533 || codePoint >= 65536 && codePoint <= 1114111;
18
+ const validEntity = (entity) => {
19
+ if (BUILT_IN_ENTITIES.has(entity)) return true;
20
+ if (!DECIMAL_CHARACTER_REFERENCE.test(entity) && !HEX_CHARACTER_REFERENCE.test(entity)) return false;
21
+ const digits = entity[1]?.toLowerCase() === "x" ? entity.slice(2) : entity.slice(1);
22
+ const significantDigits = digits.replace(/^0+/u, "") || "0";
23
+ const hexadecimal = entity[1]?.toLowerCase() === "x";
24
+ if (digits.length === 0 || significantDigits.length > (hexadecimal ? 6 : 7)) return false;
25
+ return isXmlCharacter(Number.parseInt(significantDigits, hexadecimal ? 16 : 10));
26
+ };
27
+ const hasForbiddenEntity = (xml) => {
28
+ let cursor = 0;
29
+ while (cursor < xml.length) {
30
+ if (xml.startsWith("<!--", cursor)) {
31
+ const end = xml.indexOf("-->", cursor + 4);
32
+ cursor = end === -1 ? xml.length : end + 3;
33
+ continue;
34
+ }
35
+ if (xml.startsWith("<![CDATA[", cursor)) {
36
+ const end = xml.indexOf("]]>", cursor + 9);
37
+ cursor = end === -1 ? xml.length : end + 3;
38
+ continue;
39
+ }
40
+ if (xml.startsWith("<?", cursor)) {
41
+ const end = xml.indexOf("?>", cursor + 2);
42
+ cursor = end === -1 ? xml.length : end + 2;
43
+ continue;
44
+ }
45
+ if (xml[cursor] !== "&") {
46
+ cursor += 1;
47
+ continue;
48
+ }
49
+ const end = xml.indexOf(";", cursor + 1);
50
+ if (end === -1) return true;
51
+ if (!validEntity(xml.slice(cursor + 1, end))) return true;
52
+ cursor = end + 1;
53
+ }
54
+ return false;
55
+ };
56
+ const isValidQName = (name) => {
57
+ const parts = name.split(":");
58
+ return parts.length <= 2 && parts.every((part) => NCNAME.test(part));
59
+ };
60
+ const containsOnlyXmlCharacters = (xml) => {
61
+ for (const character of xml) {
62
+ const codePoint = character.codePointAt(0);
63
+ if (codePoint === void 0 || !isXmlCharacter(codePoint)) return false;
64
+ }
65
+ return true;
66
+ };
67
+ const isWhitespace = (character) => character === " " || character === " " || character === "\r" || character === "\n";
68
+ const scanName = (xml, start) => {
69
+ let cursor = start;
70
+ while (cursor < xml.length && !isWhitespace(xml[cursor]) && xml[cursor] !== ">" && xml[cursor] !== "/" && xml[cursor] !== "=" && xml[cursor] !== "?") cursor += 1;
71
+ const name = xml.slice(start, cursor);
72
+ return name !== "" && isValidQName(name) ? {
73
+ name,
74
+ next: cursor
75
+ } : null;
76
+ };
77
+ /**
78
+ * Reject lexical forms that fast-xml-parser's permissive validator repairs.
79
+ * This is deliberately a small XML lexer, not a second tree parser: structural
80
+ * nesting remains XMLValidator's job.
81
+ */
82
+ const hasInvalidXmlLexicalForm = (xml) => {
83
+ if (!containsOnlyXmlCharacters(xml)) return true;
84
+ const byteOrderMark = xml.indexOf(BYTE_ORDER_MARK);
85
+ if (byteOrderMark > 0 || byteOrderMark === 0 && xml.indexOf(BYTE_ORDER_MARK, 1) !== -1) return true;
86
+ let cursor = 0;
87
+ while (cursor < xml.length) {
88
+ const opening = xml.indexOf("<", cursor);
89
+ const textEnd = opening === -1 ? xml.length : opening;
90
+ if (xml.slice(cursor, textEnd).includes("]]>") || opening === -1) return xml.slice(cursor, textEnd).includes("]]>");
91
+ if (xml.startsWith("<!--", opening)) {
92
+ const end = xml.indexOf("-->", opening + 4);
93
+ if (end === -1) return true;
94
+ const body = xml.slice(opening + 4, end);
95
+ if (body.includes("--") || body.endsWith("-")) return true;
96
+ cursor = end + 3;
97
+ continue;
98
+ }
99
+ if (xml.startsWith("<![CDATA[", opening)) {
100
+ const end = xml.indexOf("]]>", opening + 9);
101
+ if (end === -1) return true;
102
+ cursor = end + 3;
103
+ continue;
104
+ }
105
+ if (xml.startsWith("<?", opening)) {
106
+ const end = xml.indexOf("?>", opening + 2);
107
+ if (end === -1) return true;
108
+ let targetEnd = opening + 2;
109
+ while (targetEnd < end && !isWhitespace(xml[targetEnd]) && xml[targetEnd] !== "?") targetEnd += 1;
110
+ const target = xml.slice(opening + 2, targetEnd);
111
+ if (!NCNAME.test(target)) return true;
112
+ if (target.toLowerCase() === "xml") {
113
+ if (opening !== (xml.startsWith(BYTE_ORDER_MARK) ? 1 : 0) || target !== "xml" || !XML_DECLARATION.test(xml.slice(opening, end + 2))) return true;
114
+ }
115
+ cursor = end + 2;
116
+ continue;
117
+ }
118
+ if (xml.startsWith("<!", opening)) return true;
119
+ let tagCursor = opening + 1;
120
+ const closing = xml[tagCursor] === "/";
121
+ if (closing) tagCursor += 1;
122
+ const tagName = scanName(xml, tagCursor);
123
+ if (!tagName) return true;
124
+ tagCursor = tagName.next;
125
+ if (closing) {
126
+ while (isWhitespace(xml[tagCursor])) tagCursor += 1;
127
+ if (xml[tagCursor] !== ">") return true;
128
+ cursor = tagCursor + 1;
129
+ continue;
130
+ }
131
+ while (tagCursor < xml.length) {
132
+ while (isWhitespace(xml[tagCursor])) tagCursor += 1;
133
+ if (xml[tagCursor] === ">") {
134
+ cursor = tagCursor + 1;
135
+ break;
136
+ }
137
+ if (xml[tagCursor] === "/" && xml[tagCursor + 1] === ">") {
138
+ cursor = tagCursor + 2;
139
+ break;
140
+ }
141
+ const attribute = scanName(xml, tagCursor);
142
+ if (!attribute) return true;
143
+ if (attribute.name.startsWith("xmlns:") && (!NCNAME.test(attribute.name.slice(6)) || attribute.name.slice(6).includes(":"))) return true;
144
+ tagCursor = attribute.next;
145
+ while (isWhitespace(xml[tagCursor])) tagCursor += 1;
146
+ if (xml[tagCursor] !== "=") return true;
147
+ tagCursor += 1;
148
+ while (isWhitespace(xml[tagCursor])) tagCursor += 1;
149
+ const quote = xml[tagCursor];
150
+ if (quote !== "\"" && quote !== "'") return true;
151
+ const valueEnd = xml.indexOf(quote, tagCursor + 1);
152
+ if (valueEnd === -1 || xml.slice(tagCursor + 1, valueEnd).includes("<")) return true;
153
+ tagCursor = valueEnd + 1;
154
+ }
155
+ if (tagCursor >= xml.length && cursor !== xml.length) return true;
156
+ }
157
+ return false;
158
+ };
4
159
  const getDocxXmlSafetyIssue = (xml) => {
5
160
  if (DOCTYPE_PATTERN.test(xml)) return "doctype-forbidden";
161
+ if (hasForbiddenEntity(xml)) return "entity-forbidden";
162
+ if (hasInvalidXmlLexicalForm(xml)) return "not-well-formed";
6
163
  return XMLValidator.validate(xml) === true ? null : "not-well-formed";
7
164
  };
8
165
  //#endregion
@@ -88,7 +88,8 @@ const buildFlowOptions = (document, pageContentHeight) => {
88
88
  const settings = document.package.settings;
89
89
  const options = {
90
90
  pageContentHeight,
91
- fontAlternates: buildFontAlternates(document.package.fontTable)
91
+ fontAlternates: buildFontAlternates(document.package.fontTable),
92
+ ...document.package.styles ? { styles: document.package.styles } : {}
92
93
  };
93
94
  const theme = document.package.theme;
94
95
  if (theme) options.theme = theme;
@@ -118,8 +119,8 @@ const buildBlockLookup = (blocks, measures) => new Map(blocks.flatMap((block, in
118
119
  measure
119
120
  }]];
120
121
  }));
121
- const buildStoryOptions = (document, flowOptions) => ({
122
- ...document.package.styles ? { styles: document.package.styles } : {},
122
+ const buildStoryOptions = (flowOptions) => ({
123
+ ...flowOptions.styles === void 0 ? {} : { styles: flowOptions.styles },
123
124
  ...flowOptions.theme === void 0 ? {} : { theme: flowOptions.theme },
124
125
  ...flowOptions.fontAlternates === void 0 ? {} : { fontAlternates: flowOptions.fontAlternates },
125
126
  ...flowOptions.defaultTabStopTwips === void 0 ? {} : { defaultTabStopTwips: flowOptions.defaultTabStopTwips },
@@ -240,7 +241,7 @@ const layoutDocxHeadless = async (input, options = {}) => {
240
241
  const contentWidth = pageSize.w - margins.left - margins.right;
241
242
  const pageContentHeight = pageSize.h - margins.top - margins.bottom;
242
243
  const flowOptions = buildFlowOptions(document, pageContentHeight);
243
- const storyOptions = buildStoryOptions(document, flowOptions);
244
+ const storyOptions = buildStoryOptions(flowOptions);
244
245
  const laidOut = Result.try(() => {
245
246
  const authored = toFlowBlocks(projected.value, flowOptions);
246
247
  const footnotes = document.package.footnotes ?? [];
package/dist/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import { document_d_exports } from "./types/document.js";
2
- import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIBlockTableLocation, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditNormalization, FolioAIEditNormalizationCode, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAISignatureParty } from "./ai-edits/types.js";
2
+ import { FolioContentBlock, FolioContentContainerPathEntry, FolioContentIdStability, FolioContentInlineBooleanProperty, FolioContentInlineFormatting, FolioContentInlineFormattingPatch, FolioContentLineSpacingRule, FolioContentParagraphAlignment, FolioContentParagraphSpacing, FolioContentRun, FolioContentSnapshot, FolioContentTableLocation } from "./compare/content-types.js";
3
+ import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIBlockStructuralBoundary, FolioAIBlockTableLocation, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditNormalization, FolioAIEditNormalizationCode, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAIInlineBooleanProperty, FolioAIInlineFormatting, FolioAIInlineFormattingPatch, FolioAIParagraphSpacing, FolioAISignatureParty } from "./ai-edits/types.js";
3
4
  import { WORD_DIFF_GRANULARITIES, WordDiffGranularity, WordDiffNormalization, WordDiffOptions, WordDiffSegment, diffWordSegments } from "./ai-edits/word-diff.js";
4
5
  import { FolioAIEditApplyOutcome, FolioRevisionStamp, FolioWordDiffOptions, applyFolioAIEditOperations } from "./ai-edits/apply.js";
5
- import { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationResultBase, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "./document-operations.js";
6
+ import { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationResultBase, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "./document-operations.js";
6
7
  import { createFolioAIEditSnapshot, hashFolioAIBlockText, isFolioAIContentBlock, normalizeFolioAIBlockText } from "./ai-edits/snapshot.js";
7
8
  import { DeriveBlockIdInput, FolioBlockId, currentFolioBlockId, deriveBlockId, getFolioParaIdFromBlockId, isFolioBlockId, isSequentialFolioBlockId } from "./types/block-id.js";
8
9
  import "./ai-edits/index.js";
@@ -10,6 +11,7 @@ import { AIBarStatus, AIChatMode, AICitation, AICitationSource, AIGenerateInput,
10
11
  import { ApplyResult, applySuggestions } from "./ai-suggestions/apply.js";
11
12
  import { ResolvedAnchor, isSuggestionStale, resolveSuggestionAnchor } from "./ai-suggestions/conflict.js";
12
13
  import { PositionalText, buildPositionalText } from "./ai-suggestions/text-positions.js";
14
+ import { CompareContentOptions, FOLIO_CONTENT_COMPARISON_LIMITS, FolioContentBlockProperty, FolioContentComparison, FolioContentComparisonError, FolioContentComparisonEvent, FolioContentComparisonLimit, FolioContentComparisonLimitError, FolioContentFormatRange, FolioContentFormattingChange, FolioContentParagraphFormattingPatch, FolioContentStructuralChange, FolioContentTextSegment, InvalidFolioContentComparisonError, compareContent } from "./compare/content.js";
13
15
  import { COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareVerification, CompareVerificationCause, CompareVerificationFailure, CompareVerificationInvariant, FinalParagraphMarkRevision } from "./compare/verification.js";
14
16
  import { COMPARE_UNSUPPORTED_REASONS, CompareChange, CompareChangeLocation, CompareDocxApplyError, CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, CompareFormatRange, CompareResult, CompareUnsupportedPart, CompareUnsupportedReason, InvalidCompareDocxOptionsError } from "./compare/types.js";
15
17
  import { MAX_COMPARE_OPERATIONS, compareDocx } from "./compare/compare.js";
@@ -38,4 +40,4 @@ import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled
38
40
  import { DOCX_CONFORMANCE_CLASSES } from "@stll/docx-core/model";
39
41
  type Document = document_d_exports.Document;
40
42
  type DocxConformanceClass = document_d_exports.DocxConformanceClass;
41
- export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type BlockRect, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, type CompareChange, type CompareChangeLocation, CompareDocxApplyError, type CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, type CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, type CompareFormatRange, type CompareResult, type CompareUnsupportedPart, type CompareUnsupportedReason, type CompareVerification, type CompareVerificationCause, type CompareVerificationFailure, type CompareVerificationInvariant, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, type FinalParagraphMarkRevision, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIBlockTableLocation, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyOutcome, type FolioAIEditApplyResult, type FolioAIEditNormalization, type FolioAIEditNormalizationCode, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAISignatureParty, type FolioBlockId, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationResultBase, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type FolioRevisionStamp, type FolioWordDiffOptions, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidCompareDocxOptionsError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, type WordDiffGranularity, type WordDiffNormalization, type WordDiffOptions, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
43
+ export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type BlockRect, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, type CompareChange, type CompareChangeLocation, type CompareContentOptions, CompareDocxApplyError, type CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, type CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, type CompareFormatRange, type CompareResult, type CompareUnsupportedPart, type CompareUnsupportedReason, type CompareVerification, type CompareVerificationCause, type CompareVerificationFailure, type CompareVerificationInvariant, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_CONTENT_COMPARISON_LIMITS, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, type FinalParagraphMarkRevision, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIBlockStructuralBoundary, type FolioAIBlockTableLocation, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyOutcome, type FolioAIEditApplyResult, type FolioAIEditNormalization, type FolioAIEditNormalizationCode, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAIInlineBooleanProperty, type FolioAIInlineFormatting, type FolioAIInlineFormattingPatch, type FolioAIParagraphSpacing, type FolioAISignatureParty, type FolioBlockId, type FolioContentBlock, type FolioContentBlockProperty, type FolioContentComparison, type FolioContentComparisonError, type FolioContentComparisonEvent, type FolioContentComparisonLimit, FolioContentComparisonLimitError, type FolioContentContainerPathEntry, type FolioContentFormatRange, type FolioContentFormattingChange, type FolioContentIdStability, type FolioContentInlineBooleanProperty, type FolioContentInlineFormatting, type FolioContentInlineFormattingPatch, type FolioContentLineSpacingRule, type FolioContentParagraphAlignment, type FolioContentParagraphFormattingPatch, type FolioContentParagraphSpacing, type FolioContentRun, type FolioContentSnapshot, type FolioContentStructuralChange, type FolioContentTableLocation, type FolioContentTextSegment, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationResultBase, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type FolioRevisionStamp, type FolioWordDiffOptions, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidCompareDocxOptionsError, InvalidFolioContentComparisonError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, type WordDiffGranularity, type WordDiffNormalization, type WordDiffOptions, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareContent, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
package/dist/index.js CHANGED
@@ -6,9 +6,10 @@ import { isSuggestionStale, resolveSuggestionAnchor } from "./ai-suggestions/con
6
6
  import { buildPositionalText } from "./ai-suggestions/text-positions.js";
7
7
  import { DEFAULT_AI_SUGGESTION_PRESETS } from "./ai-suggestions/types.js";
8
8
  import { MAX_COMPARE_OPERATIONS, compareDocx } from "./compare/compare.js";
9
+ import { FOLIO_CONTENT_COMPARISON_LIMITS, FolioContentComparisonLimitError, InvalidFolioContentComparisonError, compareContent } from "./compare/content.js";
9
10
  import { COMPARE_UNSUPPORTED_REASONS, CompareDocxApplyError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, InvalidCompareDocxOptionsError } from "./compare/types.js";
10
11
  import { COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS } from "./compare/verification.js";
11
- import { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "./document-operations.js";
12
+ import { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "./document-operations.js";
12
13
  import { inspectDocxCompatibility } from "./docx/compatibility.js";
13
14
  import { createDocx } from "./docx/rezip.js";
14
15
  import { buildEmbeddedFontFamilyMap, extractEmbeddedFonts, getEmbeddedFontFaces, scopeEmbeddedFontFamily } from "./fonts/embeddedFonts.js";
@@ -31,4 +32,4 @@ import { createEmptyDocument } from "./utils/createDocument.js";
31
32
  import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled } from "./utils/fontResolver.js";
32
33
  import { mergeDocumentContent } from "./utils/mergeDocumentContent.js";
33
34
  import { DOCX_CONFORMANCE_CLASSES } from "@stll/docx-core/model";
34
- export { COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareDocxApplyError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, InvalidCompareDocxOptionsError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, STELLA_STYLE_SET_NAME, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
35
+ export { COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareDocxApplyError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, FOLIO_CONTENT_COMPARISON_LIMITS, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, FolioContentComparisonLimitError, InvalidCompareDocxOptionsError, InvalidFolioContentComparisonError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, STELLA_STYLE_SET_NAME, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareContent, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
@@ -0,0 +1,23 @@
1
+ import { RunStyleResolver } from "../prosemirror/runStyleFormatting.js";
2
+ import { Transaction } from "prosemirror-state";
3
+ import { MarkType } from "prosemirror-model";
4
+ //#region src/internal/headlessRevisionResolution.d.ts
5
+ type HeadlessRevisionResolutionMode = "accept" | "reject";
6
+ type HeadlessDeleteRange = {
7
+ from: number;
8
+ to: number;
9
+ };
10
+ type HeadlessInlineChangeTracking = {
11
+ ranges: readonly HeadlessDeleteRange[];
12
+ mappingFrom: number;
13
+ };
14
+ type AppendHeadlessInlineResolutionOptions = {
15
+ tr: Transaction;
16
+ mode: HeadlessRevisionResolutionMode;
17
+ keepType: MarkType | undefined;
18
+ removeType: MarkType | undefined;
19
+ styleResolver: RunStyleResolver | null;
20
+ };
21
+ declare const appendHeadlessInlineResolution: ({ tr, mode, keepType, removeType, styleResolver }: AppendHeadlessInlineResolutionOptions) => HeadlessInlineChangeTracking | null;
22
+ //#endregion
23
+ export { HeadlessInlineChangeTracking, HeadlessRevisionResolutionMode, appendHeadlessInlineResolution };
@@ -0,0 +1,155 @@
1
+ import { recreateProseNodeWithParagraphPropertySource } from "../docx/paragraphPropertySource.js";
2
+ import { expectRunPropertyChangeMarkAttrs } from "../prosemirror/attrs/index.js";
3
+ import { RUN_FORMATTING_MARK_NAMES } from "../prosemirror/runFormattingMarkNames.js";
4
+ import { reconstructRejectedRunFormattingMarks } from "../prosemirror/runPropertyChangeResolution.js";
5
+ import { paragraphRunStyleContext } from "../prosemirror/runStyleFormatting.js";
6
+ import { panic } from "better-result";
7
+ import { Fragment, Slice } from "prosemirror-model";
8
+ import { ReplaceStep, StepMap } from "prosemirror-transform";
9
+ //#region src/internal/headlessRevisionResolution.ts
10
+ const EMPTY_PARAGRAPH_RUN_STYLE_CONTEXT = {
11
+ baseParagraphFormatting: void 0,
12
+ paragraphFormatting: void 0,
13
+ paragraphMarkFormatting: void 0,
14
+ paragraphMarkPrecedesStyle: false
15
+ };
16
+ const resolveParagraphRunStyleScope = (scope, styleResolver) => {
17
+ if (!scope) return EMPTY_PARAGRAPH_RUN_STYLE_CONTEXT;
18
+ scope.resolved ??= paragraphRunStyleContext(scope.paragraph, styleResolver);
19
+ return scope.resolved;
20
+ };
21
+ /**
22
+ * A synchronous headless replacement with the granular position map of the
23
+ * inline deletions it applies. It must never enter history or collaboration;
24
+ * map and serialization fail loudly if that invariant is broken.
25
+ */
26
+ var HeadlessInlineResolutionStep = class HeadlessInlineResolutionStep extends ReplaceStep {
27
+ positionMap;
28
+ constructor(from, to, slice, positionMap) {
29
+ super(from, to, slice);
30
+ this.positionMap = positionMap;
31
+ }
32
+ getMap() {
33
+ return this.positionMap;
34
+ }
35
+ invert(doc) {
36
+ return new HeadlessInlineResolutionStep(this.from, this.from + this.slice.size, doc.slice(this.from, this.to), this.positionMap.invert());
37
+ }
38
+ map(_mapping) {
39
+ return panic("A headless revision-resolution step cannot be mapped");
40
+ }
41
+ toJSON() {
42
+ return panic("A headless revision-resolution step cannot be serialized");
43
+ }
44
+ };
45
+ const marksEqual = (left, right) => left.length === right.length && left.every((mark, index) => {
46
+ const candidate = right[index];
47
+ return candidate !== void 0 && mark.eq(candidate);
48
+ });
49
+ const rebuildNode = (source, attrs, content, marks = source.marks) => recreateProseNodeWithParagraphPropertySource(source, {
50
+ attrs,
51
+ content,
52
+ marks
53
+ });
54
+ const resolveInlineNode = ({ node, context, paragraphScope }) => {
55
+ let marks = node.marks;
56
+ const runPropertyChangeMark = marks.find((mark) => mark.type.name === "runPropertyChange");
57
+ if (runPropertyChangeMark) {
58
+ const { changes } = expectRunPropertyChangeMarkAttrs(runPropertyChangeMark);
59
+ if (changes.length > 0) {
60
+ marks = marks.filter((mark) => mark !== runPropertyChangeMark);
61
+ if (context.mode === "reject") {
62
+ marks = marks.filter((mark) => !RUN_FORMATTING_MARK_NAMES.has(mark.type.name));
63
+ const previousFormatting = changes.at(0)?.previousFormatting;
64
+ for (const previousMark of reconstructRejectedRunFormattingMarks({
65
+ node,
66
+ paragraphContext: resolveParagraphRunStyleScope(paragraphScope, context.styleResolver),
67
+ previousFormatting,
68
+ styleResolver: context.styleResolver
69
+ })) marks = previousMark.addToSet(marks);
70
+ }
71
+ }
72
+ }
73
+ if (context.removeType && node.marks.some((mark) => mark.type === context.removeType)) return null;
74
+ if (context.keepType) marks = marks.filter((mark) => mark.type !== context.keepType);
75
+ return marksEqual(marks, node.marks) ? node : node.mark(marks);
76
+ };
77
+ const resolveInlineContent = ({ node, position, context, inheritedParagraphScope }) => {
78
+ const paragraphScope = node.type.name === "paragraph" && context.mode === "reject" ? { paragraph: node } : inheritedParagraphScope;
79
+ let resolvedNode = node;
80
+ if (node.isInline) {
81
+ const resolved = resolveInlineNode({
82
+ node,
83
+ context,
84
+ paragraphScope
85
+ });
86
+ if (resolved === null) {
87
+ context.deleteRanges.push({
88
+ from: position,
89
+ to: position + node.nodeSize
90
+ });
91
+ return null;
92
+ }
93
+ resolvedNode = resolved;
94
+ if (resolvedNode.isLeaf) return resolvedNode;
95
+ }
96
+ const children = [];
97
+ const contentStart = resolvedNode.type.name === "doc" ? 0 : position + 1;
98
+ let contentChanged = false;
99
+ resolvedNode.forEach((child, offset) => {
100
+ const resolved = resolveInlineContent({
101
+ node: child,
102
+ position: contentStart + offset,
103
+ context,
104
+ ...paragraphScope !== void 0 ? { inheritedParagraphScope: paragraphScope } : {}
105
+ });
106
+ if (resolved) {
107
+ children.push(resolved);
108
+ contentChanged ||= resolved !== child;
109
+ } else contentChanged = true;
110
+ });
111
+ if (!contentChanged) return resolvedNode;
112
+ if (resolvedNode.type.name === "paragraph") context.changedParagraphRanges.push({
113
+ from: position,
114
+ to: position + resolvedNode.nodeSize
115
+ });
116
+ return rebuildNode(node, resolvedNode.attrs, Fragment.fromArray(children), resolvedNode.marks);
117
+ };
118
+ const coalesceDeleteRanges = (deleteRanges) => {
119
+ const coalesced = [];
120
+ for (const range of deleteRanges) {
121
+ const previous = coalesced.at(-1);
122
+ if (previous && range.from <= previous.to) previous.to = Math.max(previous.to, range.to);
123
+ else coalesced.push({ ...range });
124
+ }
125
+ return coalesced;
126
+ };
127
+ const appendHeadlessInlineResolution = ({ tr, mode, keepType, removeType, styleResolver }) => {
128
+ const context = {
129
+ mode,
130
+ keepType,
131
+ removeType,
132
+ deleteRanges: [],
133
+ changedParagraphRanges: [],
134
+ styleResolver
135
+ };
136
+ const resolved = resolveInlineContent({
137
+ node: tr.doc,
138
+ position: -1,
139
+ context
140
+ });
141
+ if (!resolved || resolved.eq(tr.doc)) return null;
142
+ const positionMap = new StepMap(coalesceDeleteRanges(context.deleteRanges).flatMap(({ from, to }) => [
143
+ from,
144
+ to - from,
145
+ 0
146
+ ]));
147
+ const mappingFrom = tr.steps.length;
148
+ tr.step(new HeadlessInlineResolutionStep(0, tr.doc.content.size, new Slice(resolved.content, 0, 0), positionMap));
149
+ return {
150
+ ranges: context.changedParagraphRanges,
151
+ mappingFrom
152
+ };
153
+ };
154
+ //#endregion
155
+ export { appendHeadlessInlineResolution };
@@ -0,0 +1,12 @@
1
+ import { EditorState, Plugin } from "prosemirror-state";
2
+ //#region src/internal/headlessRevisionResolutionGuard.d.ts
3
+ /**
4
+ * Whether a state can consume an unmapped replacement before it returns.
5
+ * Only the internal headless plugin set opts in; history and collaboration
6
+ * plugins always keep the state on the legacy editor-command path.
7
+ */
8
+ declare const stateAllowsHeadlessRevisionResolution: (state: EditorState) => boolean;
9
+ /** Build the private plugin set for synchronous headless review states. */
10
+ declare const pluginsForHeadlessRevisionResolution: (plugins: readonly Plugin[]) => readonly Plugin[];
11
+ //#endregion
12
+ export { pluginsForHeadlessRevisionResolution, stateAllowsHeadlessRevisionResolution };
@@ -0,0 +1,28 @@
1
+ import { Plugin, PluginKey } from "prosemirror-state";
2
+ //#region src/internal/headlessRevisionResolutionGuard.ts
3
+ const UNSAFE_PLUGIN_KEY_PREFIXES = [
4
+ "collab$",
5
+ "history$",
6
+ "y-sync$",
7
+ "y-undo$"
8
+ ];
9
+ const headlessRevisionResolutionKey = new PluginKey("folioHeadlessRevisionResolution");
10
+ const headlessRevisionResolutionPlugin = new Plugin({ key: headlessRevisionResolutionKey });
11
+ const pluginRuntimeKey = (plugin) => {
12
+ const key = Reflect.get(plugin, "key");
13
+ return typeof key === "string" ? key : null;
14
+ };
15
+ const retainsOrTransportsSteps = (plugin) => {
16
+ const key = pluginRuntimeKey(plugin);
17
+ return key !== null && UNSAFE_PLUGIN_KEY_PREFIXES.some((prefix) => key.startsWith(prefix));
18
+ };
19
+ /**
20
+ * Whether a state can consume an unmapped replacement before it returns.
21
+ * Only the internal headless plugin set opts in; history and collaboration
22
+ * plugins always keep the state on the legacy editor-command path.
23
+ */
24
+ const stateAllowsHeadlessRevisionResolution = (state) => headlessRevisionResolutionKey.get(state) === headlessRevisionResolutionPlugin && !state.plugins.some(retainsOrTransportsSteps);
25
+ /** Build the private plugin set for synchronous headless review states. */
26
+ const pluginsForHeadlessRevisionResolution = (plugins) => [...plugins.filter((plugin) => !retainsOrTransportsSteps(plugin)), headlessRevisionResolutionPlugin];
27
+ //#endregion
28
+ export { pluginsForHeadlessRevisionResolution, stateAllowsHeadlessRevisionResolution };
@@ -0,0 +1,9 @@
1
+ import { Node } from "prosemirror-model";
2
+ //#region src/internal/pageBreakRunDescendantIndex.d.ts
3
+ type PageBreakRunDescendantIndex = {
4
+ firstPageBreakRunPosition: (node: Node) => number | undefined;
5
+ };
6
+ /** Build one identity-scoped index for a single layout conversion. */
7
+ declare const buildPageBreakRunDescendantIndex: (doc: Node) => PageBreakRunDescendantIndex;
8
+ //#endregion
9
+ export { PageBreakRunDescendantIndex, buildPageBreakRunDescendantIndex };
@@ -0,0 +1,27 @@
1
+ //#region src/internal/pageBreakRunDescendantIndex.ts
2
+ const indexesPageBreakDescendants = (node) => {
3
+ switch (node.type.name) {
4
+ case "paragraph":
5
+ case "tableCell":
6
+ case "tableHeader":
7
+ case "textBox": return true;
8
+ default: return false;
9
+ }
10
+ };
11
+ /** Build one identity-scoped index for a single layout conversion. */
12
+ const buildPageBreakRunDescendantIndex = (doc) => {
13
+ const positions = /* @__PURE__ */ new WeakMap();
14
+ const visitNode = (node, startPos) => {
15
+ let firstPosition = node.type.name === "pageBreakRun" ? startPos : void 0;
16
+ node.forEach((child, offset) => {
17
+ const descendantPosition = visitNode(child, startPos + 1 + offset);
18
+ firstPosition ??= descendantPosition;
19
+ });
20
+ if (firstPosition !== void 0 && indexesPageBreakDescendants(node)) positions.set(node, firstPosition);
21
+ return firstPosition;
22
+ };
23
+ visitNode(doc, -1);
24
+ return { firstPageBreakRunPosition: (node) => positions.get(node) };
25
+ };
26
+ //#endregion
27
+ export { buildPageBreakRunDescendantIndex };
@@ -0,0 +1,26 @@
1
+ //#region src/internal/pageBreakRunPartition.d.ts
2
+ type PositionedRun = {
3
+ pmStart?: number;
4
+ pmEnd?: number;
5
+ };
6
+ type PositionedPageBreak = {
7
+ pmStart: number;
8
+ pmEnd: number;
9
+ };
10
+ type PageBreakRunPartition<TRun, TPageBreak> = {
11
+ before: TRun[];
12
+ pageBreak: TPageBreak;
13
+ };
14
+ type PageBreakRunPartitionResult<TRun, TPageBreak> = {
15
+ type: "partitioned";
16
+ partitions: PageBreakRunPartition<TRun, TPageBreak>[];
17
+ remaining: TRun[];
18
+ } | {
19
+ type: "overlap";
20
+ pageBreak: TPageBreak;
21
+ run: TRun;
22
+ };
23
+ /** Partition ordered runs with one monotonic cursor; each run is consumed once and peeked once. */
24
+ declare const partitionRunsAtPageBreaks: <TRun extends PositionedRun, TPageBreak extends PositionedPageBreak>(runs: readonly TRun[], pageBreaks: readonly TPageBreak[]) => PageBreakRunPartitionResult<TRun, TPageBreak>;
25
+ //#endregion
26
+ export { PageBreakRunPartition, PageBreakRunPartitionResult, partitionRunsAtPageBreaks };
@@ -0,0 +1,35 @@
1
+ //#region src/internal/pageBreakRunPartition.ts
2
+ /** Partition ordered runs with one monotonic cursor; each run is consumed once and peeked once. */
3
+ const partitionRunsAtPageBreaks = (runs, pageBreaks) => {
4
+ const partitions = [];
5
+ let nextRunIndex = 0;
6
+ for (const pageBreak of pageBreaks) {
7
+ const before = [];
8
+ while (nextRunIndex < runs.length) {
9
+ const run = runs[nextRunIndex];
10
+ if (!run) break;
11
+ if (run.pmEnd !== void 0 && run.pmEnd <= pageBreak.pmStart) {
12
+ before.push(run);
13
+ nextRunIndex += 1;
14
+ continue;
15
+ }
16
+ if (run.pmStart !== void 0 && run.pmStart >= pageBreak.pmEnd) break;
17
+ return {
18
+ type: "overlap",
19
+ pageBreak,
20
+ run
21
+ };
22
+ }
23
+ partitions.push({
24
+ before,
25
+ pageBreak
26
+ });
27
+ }
28
+ return {
29
+ type: "partitioned",
30
+ partitions,
31
+ remaining: runs.slice(nextRunIndex)
32
+ };
33
+ };
34
+ //#endregion
35
+ export { partitionRunsAtPageBreaks };
@@ -0,0 +1,15 @@
1
+ import { document_d_exports } from "../types/document.js";
2
+ //#region src/internal/pageBreakRunSourceDescendantIndex.d.ts
3
+ type PageBreakRunSourceDescendantIndex = {
4
+ containsPageBreakRun: (content: readonly document_d_exports.BlockContent[]) => boolean;
5
+ paragraphFeatures: (paragraph: document_d_exports.Paragraph) => PageBreakRunSourceParagraphFeatures;
6
+ };
7
+ type PageBreakRunSourceParagraphFeatures = {
8
+ hasPageBreakRun: boolean;
9
+ hasTextBoxShape: boolean;
10
+ pageBreakSharesTextBoxShape: boolean;
11
+ };
12
+ /** Index authored page-break descendants once for one source conversion. */
13
+ declare const buildPageBreakRunSourceDescendantIndex: (rootContent: readonly document_d_exports.BlockContent[]) => PageBreakRunSourceDescendantIndex;
14
+ //#endregion
15
+ export { PageBreakRunSourceDescendantIndex, PageBreakRunSourceParagraphFeatures, buildPageBreakRunSourceDescendantIndex };