@stll/folio-core 0.44.0 → 0.46.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/__fixtures__/paragraphs.js +2 -2
  2. package/dist/ai-edits/apply.js +59 -19
  3. package/dist/ai-edits/headless.js +2 -1
  4. package/dist/compare/compare.js +2 -5
  5. package/dist/compare/content-alignment.js +78 -53
  6. package/dist/compare/inline-atoms.js +34 -20
  7. package/dist/compare/scenario.js +2 -5
  8. package/dist/compare/types.d.ts +9 -1
  9. package/dist/compare/types.js +12 -1
  10. package/dist/compat/eigenpal.d.ts +2 -1
  11. package/dist/compat/eigenpal.js +2 -1
  12. package/dist/content-controls/checkboxDisplay.d.ts +11 -0
  13. package/dist/content-controls/checkboxDisplay.js +40 -0
  14. package/dist/content-controls/findContentControls.js +3 -1
  15. package/dist/content-controls/mutateContentControls.js +21 -4
  16. package/dist/controller/contentControlWidgetController.d.ts +1 -0
  17. package/dist/controller/contentControlWidgetController.js +3 -0
  18. package/dist/controller/hiddenEditorApi.js +3 -1
  19. package/dist/controller/hiddenEditorManager.d.ts +1 -1
  20. package/dist/controller/hiddenEditorManager.js +6 -3
  21. package/dist/display-list/build/buildDisplayList.js +20 -1
  22. package/dist/display-list/build/imagePrimitives.d.ts +1 -1
  23. package/dist/display-list/build/imagePrimitives.js +3 -1
  24. package/dist/display-list/build/paragraphPrimitives.js +21 -2
  25. package/dist/display-list/dom/renderDisplayListToDom.js +18 -10
  26. package/dist/display-list/types.d.ts +17 -0
  27. package/dist/document-operations.js +14 -3
  28. package/dist/docx/attributeRemainder.d.ts +43 -0
  29. package/dist/docx/attributeRemainder.js +65 -0
  30. package/dist/docx/blockContentParser.d.ts +1 -1
  31. package/dist/docx/blockContentParser.js +87 -63
  32. package/dist/docx/blockPlainText.d.ts +3 -4
  33. package/dist/docx/blockPlainText.js +1 -0
  34. package/dist/docx/bookmarkPlacement.js +2 -0
  35. package/dist/docx/borderParser.js +5 -5
  36. package/dist/docx/commentAnchorIndex.d.ts +30 -0
  37. package/dist/docx/commentAnchorIndex.js +50 -0
  38. package/dist/docx/commentParser.d.ts +1 -1
  39. package/dist/docx/commentParser.js +78 -50
  40. package/dist/docx/commentRangeIntegrity.d.ts +16 -1
  41. package/dist/docx/commentRangeIntegrity.js +42 -1
  42. package/dist/docx/commentRangeJoin.d.ts +9 -0
  43. package/dist/docx/commentRangeJoin.js +33 -0
  44. package/dist/docx/commentReferenceCompletion.d.ts +9 -0
  45. package/dist/docx/commentReferenceCompletion.js +47 -0
  46. package/dist/docx/commentReferenceNormalization.js +1 -0
  47. package/dist/docx/commentReplyMarkers.js +11 -19
  48. package/dist/docx/commentThreadKey.d.ts +18 -0
  49. package/dist/docx/commentThreadKey.js +22 -0
  50. package/dist/docx/compatibility.js +1 -0
  51. package/dist/docx/containerChildren.d.ts +111 -0
  52. package/dist/docx/containerChildren.gen.d.ts +28 -0
  53. package/dist/docx/containerChildren.gen.js +246 -0
  54. package/dist/docx/containerChildren.js +103 -0
  55. package/dist/docx/diagramPreview.js +87 -27
  56. package/dist/docx/documentParser.d.ts +1 -1
  57. package/dist/docx/documentParser.js +3 -3
  58. package/dist/docx/ensureParaIds.js +17 -7
  59. package/dist/docx/fieldParser.d.ts +1 -1
  60. package/dist/docx/fieldParser.js +4 -4
  61. package/dist/docx/fieldState.d.ts +26 -0
  62. package/dist/docx/fieldState.js +53 -0
  63. package/dist/docx/footnoteParser.d.ts +1 -1
  64. package/dist/docx/graphicFrameLocks.d.ts +16 -4
  65. package/dist/docx/graphicFrameLocks.js +19 -6
  66. package/dist/docx/groupDrawingParser.js +3 -3
  67. package/dist/docx/headerFooterParser.js +1 -1
  68. package/dist/docx/headerFooterReferenceNormalization.js +1 -0
  69. package/dist/docx/hyperlinkParser.d.ts +27 -8
  70. package/dist/docx/hyperlinkParser.js +78 -20
  71. package/dist/docx/imageParser.d.ts +9 -1
  72. package/dist/docx/imageParser.js +91 -20
  73. package/dist/docx/imageRawXml.d.ts +14 -1
  74. package/dist/docx/imageRawXml.js +30 -6
  75. package/dist/docx/inlineWrapperContent.d.ts +85 -0
  76. package/dist/docx/inlineWrapperContent.js +84 -0
  77. package/dist/docx/mathToMathml.js +12 -14
  78. package/dist/docx/nonVisualDrawingProps.d.ts +34 -0
  79. package/dist/docx/nonVisualDrawingProps.js +46 -0
  80. package/dist/docx/normalizeBaseDirection.js +10 -1
  81. package/dist/docx/paraIdAttribute.d.ts +21 -0
  82. package/dist/docx/paraIdAttribute.js +64 -0
  83. package/dist/docx/paragraphParser.d.ts +1 -1
  84. package/dist/docx/paragraphParser.js +277 -168
  85. package/dist/docx/paragraphPropertySource.js +5 -1
  86. package/dist/docx/paragraphTextBoxEnrichment.d.ts +1 -1
  87. package/dist/docx/paragraphTextBoxEnrichment.js +9 -52
  88. package/dist/docx/paragraphTraversal.js +7 -4
  89. package/dist/docx/parseWarningMessage.js +2 -1
  90. package/dist/docx/parser.js +2 -2
  91. package/dist/docx/preservedRunContent.d.ts +32 -0
  92. package/dist/docx/preservedRunContent.js +86 -0
  93. package/dist/docx/previewBudget.d.ts +64 -0
  94. package/dist/docx/previewBudget.js +88 -0
  95. package/dist/docx/renderedPageBreakNormalization.js +2 -4
  96. package/dist/docx/revisionIdNormalization.js +17 -5
  97. package/dist/docx/rezip.js +91 -36
  98. package/dist/docx/runParser.d.ts +1 -1
  99. package/dist/docx/runParser.js +16 -12
  100. package/dist/docx/sdtPropertiesPatch.js +24 -18
  101. package/dist/docx/sectionParser.js +8 -1
  102. package/dist/docx/sectionReferenceHistory.js +2 -2
  103. package/dist/docx/selectiveSave.js +6 -6
  104. package/dist/docx/selectiveXmlPatch.d.ts +46 -2
  105. package/dist/docx/selectiveXmlPatch.js +86 -39
  106. package/dist/docx/serializer/blockSdtSerializer.js +38 -26
  107. package/dist/docx/serializer/borderSerializer.d.ts +1 -1
  108. package/dist/docx/serializer/borderSerializer.js +15 -14
  109. package/dist/docx/serializer/commentSerializer.d.ts +41 -16
  110. package/dist/docx/serializer/commentSerializer.js +87 -92
  111. package/dist/docx/serializer/documentSerializer.js +8 -11
  112. package/dist/docx/serializer/fontTableSerializer.js +6 -6
  113. package/dist/docx/serializer/headerFooterSerializer.js +12 -14
  114. package/dist/docx/serializer/markupRangeAttributes.js +2 -2
  115. package/dist/docx/serializer/noteSerializer.js +8 -8
  116. package/dist/docx/serializer/numberingSerializer.js +7 -6
  117. package/dist/docx/serializer/paragraphSerializer.js +93 -72
  118. package/dist/docx/serializer/partNamespaces.js +2 -2
  119. package/dist/docx/serializer/runSerializer.js +73 -44
  120. package/dist/docx/serializer/sectionPropertiesSerializer.js +19 -14
  121. package/dist/docx/serializer/settingsSerializer.js +4 -3
  122. package/dist/docx/serializer/stylesSerializer.js +6 -6
  123. package/dist/docx/serializer/tableSerializer.js +28 -17
  124. package/dist/docx/serializer/textFormattingSerializer.js +29 -28
  125. package/dist/docx/serializer/themeSerializer.js +6 -6
  126. package/dist/docx/serializer/trackedChangeAttributes.js +2 -2
  127. package/dist/docx/serializer/xmlUtils.d.ts +1 -2
  128. package/dist/docx/serializer/xmlUtils.js +1 -13
  129. package/dist/docx/server/boundedArchive.d.ts +12 -0
  130. package/dist/docx/server/boundedArchive.js +20 -1
  131. package/dist/docx/server/createBilingualDocument.js +3 -1
  132. package/dist/docx/server/materializeYjsDocx.d.ts +1 -1
  133. package/dist/docx/server/materializeYjsDocx.js +9 -1
  134. package/dist/docx/server/migrateYjsAttrSchema.d.ts +55 -0
  135. package/dist/docx/server/migrateYjsAttrSchema.js +95 -0
  136. package/dist/docx/server/validateDocxConformance.js +22 -1
  137. package/dist/docx/shapeParser.js +12 -10
  138. package/dist/docx/tableParser.d.ts +1 -1
  139. package/dist/docx/tableParser.js +206 -85
  140. package/dist/docx/textBoxParser.d.ts +25 -2
  141. package/dist/docx/textBoxParser.js +59 -4
  142. package/dist/docx/unzip.d.ts +23 -0
  143. package/dist/docx/unzip.js +37 -26
  144. package/dist/docx/verbatimCapture.js +1 -1
  145. package/dist/docx/vmlImageParser.d.ts +17 -1
  146. package/dist/docx/vmlImageParser.js +20 -3
  147. package/dist/docx/vmlPreview.d.ts +1 -3
  148. package/dist/docx/vmlPreview.js +2 -30
  149. package/dist/docx/xmlEncoding.d.ts +5 -0
  150. package/dist/docx/xmlEncoding.js +12 -0
  151. package/dist/docx/xmlParser.d.ts +26 -2
  152. package/dist/docx/xmlParser.js +70 -27
  153. package/dist/docx/xmlResourceLimits.d.ts +89 -9
  154. package/dist/docx/xmlResourceLimits.js +105 -24
  155. package/dist/headless-layout.js +10 -1
  156. package/dist/index.d.ts +2 -1
  157. package/dist/index.js +2 -1
  158. package/dist/internal/pageBreakRunSourceDescendantIndex.js +5 -2
  159. package/dist/internal/paragraphFormattingSerialization.js +3 -2
  160. package/dist/layout-bridge/convert/toFlowBlocks.js +102 -12
  161. package/dist/layout-engine/measure/tableCellFloating.d.ts +2 -0
  162. package/dist/layout-engine/measure/tableCellFloating.js +2 -0
  163. package/dist/layout-engine/types.d.ts +23 -1
  164. package/dist/layout-painter/renderImage.d.ts +5 -1
  165. package/dist/layout-painter/renderImage.js +14 -6
  166. package/dist/layout-painter/renderPage.d.ts +2 -0
  167. package/dist/layout-painter/renderPage.js +4 -0
  168. package/dist/layout-painter/renderParagraph.d.ts +13 -1
  169. package/dist/layout-painter/renderParagraph.js +26 -6
  170. package/dist/managers/autoSaveCodec.d.ts +9 -1
  171. package/dist/managers/autoSaveCodec.js +14 -12
  172. package/dist/markdown/images.js +1 -4
  173. package/dist/markdown/renderBlock.js +1 -0
  174. package/dist/markdown/renderRuns.d.ts +1 -1
  175. package/dist/markdown/renderRuns.js +28 -5
  176. package/dist/markdown/renderTable.js +22 -5
  177. package/dist/markdown/trailers.js +4 -1
  178. package/dist/pdf/images.js +142 -6
  179. package/dist/prosemirror/attrs/index.d.ts +14 -3
  180. package/dist/prosemirror/attrs/index.js +224 -2
  181. package/dist/prosemirror/authoredTransformAttrs.d.ts +28 -0
  182. package/dist/prosemirror/authoredTransformAttrs.js +64 -0
  183. package/dist/prosemirror/commands/contentControls.js +10 -2
  184. package/dist/prosemirror/commands/image.d.ts +9 -2
  185. package/dist/prosemirror/commands/image.js +43 -28
  186. package/dist/prosemirror/commands/pageBreak.js +1 -1
  187. package/dist/prosemirror/commentReferenceAttrs.d.ts +8 -0
  188. package/dist/prosemirror/commentReferenceAttrs.js +33 -0
  189. package/dist/prosemirror/commentReferenceIntegrity.d.ts +47 -0
  190. package/dist/prosemirror/commentReferenceIntegrity.js +43 -0
  191. package/dist/prosemirror/conversion/fromProseDoc.d.ts +2 -13
  192. package/dist/prosemirror/conversion/fromProseDoc.js +338 -99
  193. package/dist/prosemirror/conversion/index.d.ts +2 -2
  194. package/dist/prosemirror/conversion/toProseDoc.d.ts +7 -9
  195. package/dist/prosemirror/conversion/toProseDoc.js +551 -327
  196. package/dist/prosemirror/extensions/StarterKit.js +8 -58
  197. package/dist/prosemirror/extensions/core/DocExtension.js +1 -1
  198. package/dist/prosemirror/extensions/core/ParagraphExtension.js +2 -1
  199. package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +45 -27
  200. package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.js +3 -1
  201. package/dist/prosemirror/extensions/features/ImagePasteExtension.js +5 -3
  202. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +1 -0
  203. package/dist/prosemirror/extensions/markRegistry.d.ts +41 -0
  204. package/dist/prosemirror/extensions/markRegistry.js +75 -0
  205. package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +2 -3
  206. package/dist/prosemirror/extensions/marks/InlineWrapperExtension.d.ts +18 -0
  207. package/dist/prosemirror/extensions/marks/InlineWrapperExtension.js +63 -0
  208. package/dist/prosemirror/extensions/marks/markUtils.d.ts +2 -1
  209. package/dist/prosemirror/extensions/marks/markUtils.js +47 -4
  210. package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.d.ts +11 -0
  211. package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +87 -0
  212. package/dist/prosemirror/extensions/nodes/FieldExtension.js +9 -7
  213. package/dist/prosemirror/extensions/nodes/ImageExtension.js +20 -0
  214. package/dist/prosemirror/extensions/nodes/PreservedBlockExtension.d.ts +32 -0
  215. package/dist/prosemirror/extensions/nodes/PreservedBlockExtension.js +67 -0
  216. package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.d.ts +16 -0
  217. package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.js +60 -0
  218. package/dist/prosemirror/extensions/nodes/ShapeExtension.js +10 -2
  219. package/dist/prosemirror/extensions/nodes/TableExtension.js +3 -2
  220. package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +13 -5
  221. package/dist/prosemirror/inlineWrapperStack.d.ts +39 -0
  222. package/dist/prosemirror/inlineWrapperStack.js +75 -0
  223. package/dist/prosemirror/pageBreakRunProjection.d.ts +17 -7
  224. package/dist/prosemirror/pageBreakRunProjection.js +19 -9
  225. package/dist/prosemirror/paragraphFormattingProvenance.d.ts +6 -3
  226. package/dist/prosemirror/paragraphFormattingProvenance.js +12 -3
  227. package/dist/prosemirror/replacedAnnotations.d.ts +59 -0
  228. package/dist/prosemirror/replacedAnnotations.js +165 -0
  229. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +3 -1
  230. package/dist/prosemirror/runFormattingInlineCarriers.js +5 -1
  231. package/dist/prosemirror/schema/index.d.ts +3 -3
  232. package/dist/prosemirror/schema/marks.d.ts +25 -1
  233. package/dist/prosemirror/schema/nodes.d.ts +139 -3
  234. package/dist/prosemirror/schema/nodes.js +16 -1
  235. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +2 -0
  236. package/dist/prosemirror/trackedRunInlineAtoms.js +2 -0
  237. package/dist/prosemirror/validation.js +16 -2
  238. package/dist/prosemirror/yjsDocumentMetadata.d.ts +73 -0
  239. package/dist/prosemirror/yjsDocumentMetadata.js +171 -0
  240. package/dist/prosemirror/zeroWidthAnchors.js +2 -0
  241. package/dist/render-dom/commentAnchorAttributes.d.ts +37 -0
  242. package/dist/render-dom/commentAnchorAttributes.js +54 -0
  243. package/dist/server.d.ts +3 -1
  244. package/dist/server.js +3 -1
  245. package/dist/types/content.d.ts +2 -2
  246. package/dist/utils/base64.d.ts +36 -0
  247. package/dist/utils/base64.js +40 -0
  248. package/dist/utils/clipboard.d.ts +9 -1
  249. package/dist/utils/clipboard.js +29 -2
  250. package/dist/utils/findReplace.js +1 -1
  251. package/dist/utils/imageLuminance.d.ts +15 -0
  252. package/dist/utils/imageLuminance.js +32 -0
  253. package/dist/utils/mergeDocumentContent.js +7 -17
  254. package/dist/utils/replaceText.js +1 -0
  255. package/dist/utils/units.d.ts +10 -1
  256. package/dist/utils/units.js +12 -1
  257. package/dist/utils/urlSecurity.d.ts +8 -2
  258. package/dist/utils/urlSecurity.js +21 -3
  259. package/package.json +2 -2
  260. package/dist/docx/blockRangeMarkers.d.ts +0 -36
  261. package/dist/docx/blockRangeMarkers.js +0 -59
  262. package/dist/prosemirror/yjsParagraphSourceContract.d.ts +0 -9
  263. package/dist/prosemirror/yjsParagraphSourceContract.js +0 -26
@@ -0,0 +1,87 @@
1
+ import { readCommentReferenceAttrs } from "../../commentReferenceAttrs.js";
2
+ import { planCommentReferenceRepairs } from "../../commentReferenceIntegrity.js";
3
+ import { createNodeExtension } from "../create.js";
4
+ import { Plugin } from "prosemirror-state";
5
+ //#region src/prosemirror/extensions/nodes/CommentReferenceExtension.ts
6
+ /** The node name, for callers asking whether a paragraph holds any content. */
7
+ const COMMENT_REFERENCE_NODE_NAME = "commentReference";
8
+ const surveyCommentReferences = (doc) => {
9
+ const references = [];
10
+ const markEnds = /* @__PURE__ */ new Map();
11
+ doc.descendants((node, position) => {
12
+ if (node.type.name === "commentReference") {
13
+ const attrs = readCommentReferenceAttrs(node);
14
+ references.push({
15
+ commentId: attrs.ok ? attrs.value.commentId : -1,
16
+ position,
17
+ size: node.nodeSize,
18
+ malformed: !attrs.ok
19
+ });
20
+ return false;
21
+ }
22
+ if (!node.isInline) return true;
23
+ for (const mark of node.marks) {
24
+ if (mark.type.name !== "comment") continue;
25
+ const commentId = mark.attrs["commentId"];
26
+ if (typeof commentId !== "number") continue;
27
+ markEnds.set(commentId, Math.max(markEnds.get(commentId) ?? 0, position + node.nodeSize));
28
+ }
29
+ return true;
30
+ });
31
+ return {
32
+ references,
33
+ markExtents: [...markEnds].map(([commentId, end]) => ({
34
+ commentId,
35
+ end
36
+ }))
37
+ };
38
+ };
39
+ const CommentReferenceExtension = createNodeExtension({
40
+ name: COMMENT_REFERENCE_NODE_NAME,
41
+ schemaNodeName: COMMENT_REFERENCE_NODE_NAME,
42
+ nodeSpec: (options) => ({
43
+ inline: true,
44
+ group: "inline",
45
+ marks: "_",
46
+ atom: true,
47
+ selectable: false,
48
+ attrs: { commentId: {} },
49
+ parseDOM: [{
50
+ tag: "span[data-docx-comment-reference]",
51
+ getAttrs(dom) {
52
+ const raw = dom.getAttribute("data-docx-comment-reference");
53
+ if (raw === null || !/^(?:0|[1-9]\d*)$/.test(raw)) return false;
54
+ const commentId = Number(raw);
55
+ return Number.isSafeInteger(commentId) ? { commentId } : false;
56
+ }
57
+ }],
58
+ toDOM(node) {
59
+ const attrs = readCommentReferenceAttrs(node);
60
+ return ["span", {
61
+ "data-docx-comment-reference": String(attrs.ok ? attrs.value.commentId : ""),
62
+ "aria-hidden": "true",
63
+ contenteditable: "false",
64
+ style: "display: none;",
65
+ ...options.getInternalClipboardToken ? { "data-docx-internal-clipboard": options.getInternalClipboardToken() } : {}
66
+ }];
67
+ }
68
+ }),
69
+ onSchemaReady: ({ schema }) => ({ plugins: [new Plugin({ appendTransaction(transactions, _oldState, newState) {
70
+ if (!transactions.some(({ docChanged }) => docChanged)) return null;
71
+ const referenceType = schema.nodes[COMMENT_REFERENCE_NODE_NAME];
72
+ if (!referenceType) return null;
73
+ const repairs = planCommentReferenceRepairs(surveyCommentReferences(newState.doc));
74
+ if (repairs.length === 0) return null;
75
+ const transaction = newState.tr;
76
+ for (const repair of repairs) {
77
+ if (repair.type === "delete") {
78
+ transaction.delete(repair.position, repair.position + repair.size);
79
+ continue;
80
+ }
81
+ transaction.insert(transaction.mapping.map(repair.position), referenceType.create({ commentId: repair.commentId }));
82
+ }
83
+ return transaction;
84
+ } })] })
85
+ });
86
+ //#endregion
87
+ export { COMMENT_REFERENCE_NODE_NAME, CommentReferenceExtension };
@@ -8,16 +8,18 @@ const createFieldAttrs = () => ({
8
8
  displayText: { default: "" },
9
9
  _numberedRefBaseline: { default: void 0 },
10
10
  fieldKind: { default: "simple" },
11
- fldLock: { default: false },
12
- dirty: { default: false }
11
+ fldLock: { default: null },
12
+ dirty: { default: null }
13
13
  });
14
+ /** A `data-` flag a pasted field carried: absent states nothing. */
15
+ const statedFlag = (value) => value === void 0 ? null : value === "true";
14
16
  const readFieldDomAttrs = (dom) => ({
15
17
  fieldType: dom.dataset["fieldType"] ?? "UNKNOWN",
16
18
  instruction: dom.dataset["instruction"] ?? "",
17
19
  displayText: dom.textContent ?? "",
18
20
  fieldKind: dom.dataset["fieldKind"] ?? "simple",
19
- fldLock: dom.dataset["fldLock"] === "true",
20
- dirty: dom.dataset["dirty"] === "true"
21
+ fldLock: statedFlag(dom.dataset["fldLock"]),
22
+ dirty: statedFlag(dom.dataset["dirty"])
21
23
  });
22
24
  const getFieldDomAttrs = (node) => {
23
25
  const { fieldType, instruction, fieldKind, fldLock, dirty } = expectFieldAttrs(node);
@@ -26,8 +28,8 @@ const getFieldDomAttrs = (node) => {
26
28
  "data-field-type": fieldType,
27
29
  "data-instruction": instruction,
28
30
  "data-field-kind": fieldKind,
29
- ...fldLock ? { "data-fld-lock": "true" } : {},
30
- ...dirty ? { "data-dirty": "true" } : {},
31
+ ...fldLock === void 0 ? {} : { "data-fld-lock": String(fldLock) },
32
+ ...dirty === void 0 ? {} : { "data-dirty": String(dirty) },
31
33
  style: "outline: 1px solid var(--doc-field-outline, rgba(200,200,200,0.4)); padding: 0 1px; border-radius: 2px;"
32
34
  };
33
35
  };
@@ -74,7 +76,7 @@ const StructuredFieldExtension = createNodeExtension({
74
76
  nodeSpec: (options) => ({
75
77
  inline: true,
76
78
  group: "inline",
77
- content: "(text | bookmarkBoundary | tab | symbol | hardBreak | pageBreakRun | image | shape | renderedPageBreak | textBoxAnchor)+",
79
+ content: "(text | bookmarkBoundary | tab | symbol | hardBreak | pageBreakRun | image | shape | renderedPageBreak | textBoxAnchor | preservedXml)+",
78
80
  atom: true,
79
81
  selectable: true,
80
82
  attrs: createFieldAttrs(),
@@ -1,3 +1,4 @@
1
+ import { imageLuminanceFilter } from "../../../utils/imageLuminance.js";
1
2
  import { expectImageAttrs } from "../../attrs/index.js";
2
3
  import { createNodeExtension } from "../create.js";
3
4
  //#region src/prosemirror/extensions/nodes/ImageExtension.ts
@@ -24,7 +25,12 @@ const ImageExtension = createNodeExtension({
24
25
  displayMode: { default: "inline" },
25
26
  cssFloat: { default: null },
26
27
  transform: { default: null },
28
+ docxRotation: { default: null },
29
+ docxFlipH: { default: null },
30
+ docxFlipV: { default: null },
27
31
  opacity: { default: null },
32
+ brightness: { default: null },
33
+ contrast: { default: null },
28
34
  distTop: { default: null },
29
35
  distBottom: { default: null },
30
36
  distLeft: { default: null },
@@ -39,8 +45,12 @@ const ImageExtension = createNodeExtension({
39
45
  paddingLeft: { default: null },
40
46
  position: { default: null },
41
47
  layoutInCell: { default: null },
48
+ decorative: { default: null },
49
+ hidden: { default: null },
50
+ docPrExtensions: { default: null },
42
51
  frameLocks: { default: null },
43
52
  borderWidth: { default: null },
53
+ _docxAuthoredEmu: { default: null },
44
54
  borderColor: { default: null },
45
55
  borderStyle: { default: null },
46
56
  wrapText: { default: null },
@@ -62,6 +72,10 @@ const ImageExtension = createNodeExtension({
62
72
  const borderWidthRaw = element.dataset["borderWidth"];
63
73
  const opacityRaw = element.dataset["opacity"];
64
74
  const opacityParsed = opacityRaw === void 0 ? NaN : Number(opacityRaw);
75
+ const brightnessRaw = element.dataset["brightness"];
76
+ const brightness = brightnessRaw === void 0 ? NaN : Number(brightnessRaw);
77
+ const contrastRaw = element.dataset["contrast"];
78
+ const contrast = contrastRaw === void 0 ? NaN : Number(contrastRaw);
65
79
  return {
66
80
  src: element.getAttribute("src") || "",
67
81
  ...alt ? { alt } : {},
@@ -74,6 +88,8 @@ const ImageExtension = createNodeExtension({
74
88
  ...cssFloat ? { cssFloat } : {},
75
89
  ...element.dataset["transform"] ? { transform: element.dataset["transform"] } : {},
76
90
  ...Number.isFinite(opacityParsed) ? { opacity: opacityParsed } : {},
91
+ ...Number.isFinite(brightness) ? { brightness } : {},
92
+ ...Number.isFinite(contrast) ? { contrast } : {},
77
93
  ...borderWidthRaw ? { borderWidth: Number(borderWidthRaw) } : {},
78
94
  ...element.dataset["borderColor"] ? { borderColor: element.dataset["borderColor"] } : {},
79
95
  ...element.dataset["borderStyle"] ? { borderStyle: element.dataset["borderStyle"] } : {}
@@ -94,6 +110,8 @@ const ImageExtension = createNodeExtension({
94
110
  if (attrs.cssFloat) domAttrs["data-css-float"] = attrs.cssFloat;
95
111
  if (attrs.transform) domAttrs["data-transform"] = attrs.transform;
96
112
  if (attrs.opacity != null) domAttrs["data-opacity"] = String(attrs.opacity);
113
+ if (attrs.brightness != null) domAttrs["data-brightness"] = String(attrs.brightness);
114
+ if (attrs.contrast != null) domAttrs["data-contrast"] = String(attrs.contrast);
97
115
  if (attrs.borderWidth) domAttrs["data-border-width"] = String(attrs.borderWidth);
98
116
  if (attrs.borderColor) domAttrs["data-border-color"] = attrs.borderColor;
99
117
  if (attrs.borderStyle) domAttrs["data-border-style"] = attrs.borderStyle;
@@ -130,6 +148,8 @@ const ImageExtension = createNodeExtension({
130
148
  }
131
149
  if (attrs.transform) styles.push(`transform: ${attrs.transform}`);
132
150
  if (attrs.opacity != null && attrs.opacity < 1) styles.push(`opacity: ${Math.max(0, attrs.opacity)}`);
151
+ const luminanceFilter = imageLuminanceFilter(attrs);
152
+ if (luminanceFilter !== void 0) styles.push(`filter: ${luminanceFilter}`);
133
153
  if (attrs.borderWidth && attrs.borderWidth > 0) {
134
154
  const bStyle = attrs.borderStyle || "solid";
135
155
  const bColor = attrs.borderColor || "#000000";
@@ -0,0 +1,32 @@
1
+ import { NodeExtension } from "../types.js";
2
+ //#region src/prosemirror/extensions/nodes/PreservedBlockExtension.d.ts
3
+ /**
4
+ * A zero-width block for markup folio keeps opaquely between two blocks.
5
+ *
6
+ * The block-level twin of the `preservedXml` inline atom. A `w:permStart`
7
+ * between two paragraphs, an `m:oMathPara`, a `w:altChunk`, a comment or move
8
+ * range that opens between blocks: the editor has no model for any of it and
9
+ * does not need one, because it only has to not lose it. So the node renders
10
+ * nothing, takes no selection and holds no text.
11
+ *
12
+ * **Position is structure, not an attribute.** The node sits between the same
13
+ * two blocks it sat between in the source, and ProseMirror's own mapping keeps
14
+ * it there: inserting, splitting or deleting a neighbour moves the markup the
15
+ * way a reader would expect, and nothing has to keep an index honest. The
16
+ * alternative — an index into the container recorded on the node — drifts the
17
+ * first time anything around it changes, and a drifting index is how markup
18
+ * ends up in the wrong place rather than merely lost.
19
+ *
20
+ * Deleting a *neighbour* therefore leaves the markup attached to whatever now
21
+ * follows it; only a selection that covers the node itself removes it, which
22
+ * is the same rule the editor applies to every other block.
23
+ *
24
+ * The integrity plugin removes a node that can never write markup back: bad
25
+ * attributes, or an empty payload left by a paste through the DOM. Keeping one
26
+ * would leave a zero-width block in the document that serializes to nothing.
27
+ */
28
+ /** The node name, for callers asking what a container holds. */
29
+ declare const PRESERVED_BLOCK_NODE_NAME = "preservedBlock";
30
+ declare const PreservedBlockExtension: (options?: Partial<Record<string, unknown>> | undefined) => NodeExtension;
31
+ //#endregion
32
+ export { PRESERVED_BLOCK_NODE_NAME, PreservedBlockExtension };
@@ -0,0 +1,67 @@
1
+ import { expectPreservedBlockAttrs, readPreservedBlockAttrs } from "../../attrs/index.js";
2
+ import { createNodeExtension } from "../create.js";
3
+ import { Plugin } from "prosemirror-state";
4
+ //#region src/prosemirror/extensions/nodes/PreservedBlockExtension.ts
5
+ /** The node name, for callers asking what a container holds. */
6
+ const PRESERVED_BLOCK_NODE_NAME = "preservedBlock";
7
+ /**
8
+ * A node that can never write markup back.
9
+ *
10
+ * Either the attributes do not read at all, or `xml` is empty: a copy that
11
+ * came back from a paste with its payload stripped. Keeping one would put a
12
+ * zero-width block in the document that serializes to nothing, so the plugin
13
+ * removes it rather than letting it ride along.
14
+ */
15
+ const isUnwritable = (node) => {
16
+ const attrs = readPreservedBlockAttrs(node);
17
+ return !attrs.ok || attrs.value.xml === "";
18
+ };
19
+ const collectUnwritableBlocks = (doc) => {
20
+ const unwritable = [];
21
+ doc.descendants((node, position) => {
22
+ if (node.type.name !== "preservedBlock") return true;
23
+ if (isUnwritable(node)) unwritable.push({
24
+ position,
25
+ node
26
+ });
27
+ return false;
28
+ });
29
+ return unwritable;
30
+ };
31
+ const PreservedBlockExtension = createNodeExtension({
32
+ name: PRESERVED_BLOCK_NODE_NAME,
33
+ schemaNodeName: PRESERVED_BLOCK_NODE_NAME,
34
+ nodeSpec: {
35
+ group: "block",
36
+ atom: true,
37
+ selectable: false,
38
+ attrs: { xml: {} },
39
+ parseDOM: [{
40
+ tag: "div[data-docx-preserved-block]",
41
+ getAttrs(dom) {
42
+ if (!(dom instanceof HTMLElement)) return false;
43
+ const xml = dom.dataset["docxPreservedBlock"];
44
+ return xml === void 0 || xml === "" ? false : { xml };
45
+ }
46
+ }],
47
+ toDOM(node) {
48
+ const { xml } = expectPreservedBlockAttrs(node);
49
+ return ["div", {
50
+ "data-docx-preserved-block": xml,
51
+ "aria-hidden": "true",
52
+ contenteditable: "false",
53
+ style: "display: none;"
54
+ }];
55
+ }
56
+ },
57
+ onSchemaReady: () => ({ plugins: [new Plugin({ appendTransaction(transactions, _oldState, newState) {
58
+ if (!transactions.some(({ docChanged }) => docChanged)) return null;
59
+ const unwritable = collectUnwritableBlocks(newState.doc);
60
+ if (unwritable.length === 0) return null;
61
+ const transaction = newState.tr;
62
+ for (const { node, position } of unwritable.toSorted((first, second) => second.position - first.position)) transaction.delete(position, position + node.nodeSize);
63
+ return transaction;
64
+ } })] })
65
+ });
66
+ //#endregion
67
+ export { PRESERVED_BLOCK_NODE_NAME, PreservedBlockExtension };
@@ -0,0 +1,16 @@
1
+ import { NodeExtension } from "../types.js";
2
+ //#region src/prosemirror/extensions/nodes/PreservedXmlExtension.d.ts
3
+ /**
4
+ * An opaque inline atom for a run child folio does not model.
5
+ *
6
+ * The editor cannot edit markup it has no model for, and it does not have to:
7
+ * it only has to not lose it. The node carries the captured bytes untouched
8
+ * and shows the visible text the markup puts on the line (`w:ruby` renders its
9
+ * `w:rubyBase` there), so the round trip keeps both the document's text and
10
+ * the document's markup.
11
+ */
12
+ /** The node name, for callers asking what a paragraph holds. */
13
+ declare const PRESERVED_XML_NODE_NAME = "preservedXml";
14
+ declare const PreservedXmlExtension: (options?: Partial<Record<string, unknown>> | undefined) => NodeExtension;
15
+ //#endregion
16
+ export { PRESERVED_XML_NODE_NAME, PreservedXmlExtension };
@@ -0,0 +1,60 @@
1
+ import { expectPreservedXmlAttrs } from "../../attrs/index.js";
2
+ import { PRESERVED_XML_LEVELS } from "../../schema/nodes.js";
3
+ import { createNodeExtension } from "../create.js";
4
+ //#region src/prosemirror/extensions/nodes/PreservedXmlExtension.ts
5
+ /**
6
+ * An opaque inline atom for a run child folio does not model.
7
+ *
8
+ * The editor cannot edit markup it has no model for, and it does not have to:
9
+ * it only has to not lose it. The node carries the captured bytes untouched
10
+ * and shows the visible text the markup puts on the line (`w:ruby` renders its
11
+ * `w:rubyBase` there), so the round trip keeps both the document's text and
12
+ * the document's markup.
13
+ */
14
+ /** The node name, for callers asking what a paragraph holds. */
15
+ const PRESERVED_XML_NODE_NAME = "preservedXml";
16
+ const PreservedXmlExtension = createNodeExtension({
17
+ name: PRESERVED_XML_NODE_NAME,
18
+ schemaNodeName: PRESERVED_XML_NODE_NAME,
19
+ nodeSpec: {
20
+ inline: true,
21
+ group: "inline",
22
+ atom: true,
23
+ marks: "_",
24
+ selectable: false,
25
+ attrs: {
26
+ xml: {},
27
+ text: { default: "" },
28
+ level: { default: PRESERVED_XML_LEVELS.run }
29
+ },
30
+ parseDOM: [{
31
+ tag: "span[data-docx-preserved-xml]",
32
+ getAttrs(node) {
33
+ if (!(node instanceof HTMLElement)) return false;
34
+ const xml = node.dataset["docxPreservedXml"];
35
+ if (xml === void 0 || xml === "") return false;
36
+ const level = node.dataset["docxPreservedLevel"] === PRESERVED_XML_LEVELS.inline ? PRESERVED_XML_LEVELS.inline : PRESERVED_XML_LEVELS.run;
37
+ return {
38
+ xml,
39
+ text: node.dataset["docxPreservedText"] ?? "",
40
+ level
41
+ };
42
+ }
43
+ }],
44
+ toDOM(node) {
45
+ const { xml, text, level } = expectPreservedXmlAttrs(node);
46
+ return [
47
+ "span",
48
+ {
49
+ "data-docx-preserved-xml": xml,
50
+ "data-docx-preserved-level": level,
51
+ ...text === "" ? {} : { "data-docx-preserved-text": text },
52
+ contenteditable: "false"
53
+ },
54
+ text
55
+ ];
56
+ }
57
+ }
58
+ });
59
+ //#endregion
60
+ export { PRESERVED_XML_NODE_NAME, PreservedXmlExtension };
@@ -371,22 +371,30 @@ const ShapeExtension = createNodeExtension({
371
371
  geometryAdjustments: { default: null },
372
372
  _docxRunFormatting: { default: null },
373
373
  shapeId: { default: null },
374
+ shapeName: { default: null },
375
+ alt: { default: null },
376
+ title: { default: null },
374
377
  width: { default: 100 },
375
378
  height: { default: 80 },
379
+ _docxAuthoredEmu: { default: null },
376
380
  fillColor: { default: null },
377
381
  fillColorValue: { default: null },
378
382
  fillType: { default: "solid" },
379
383
  gradientType: { default: null },
380
384
  gradientAngle: { default: null },
381
385
  gradientStops: { default: null },
382
- outlineWidth: { default: 1 },
386
+ outlineWidth: { default: null },
383
387
  outlineColor: { default: "var(--doc-shape-outline, #000000)" },
384
388
  outlineColorValue: { default: null },
385
- outlineStyle: { default: "solid" },
389
+ outlineStyle: { default: null },
386
390
  outlineCap: { default: null },
391
+ outlineJoin: { default: null },
387
392
  outlineHeadEnd: { default: null },
388
393
  outlineTailEnd: { default: null },
389
394
  transform: { default: null },
395
+ docxRotation: { default: null },
396
+ docxFlipH: { default: null },
397
+ docxFlipV: { default: null },
390
398
  displayMode: { default: "inline" },
391
399
  cssFloat: { default: null },
392
400
  wrapType: { default: "inline" },
@@ -206,6 +206,7 @@ const tableRowSpec = {
206
206
  _resolvedJustification: { default: null },
207
207
  _originalFormatting: { default: null },
208
208
  trPrChange: { default: null },
209
+ _preservedAttributes: { default: null },
209
210
  trIns: { default: null },
210
211
  trDel: { default: null }
211
212
  },
@@ -308,7 +309,7 @@ function buildCellWidthStyles(attrs) {
308
309
  return styles;
309
310
  }
310
311
  const tableCellSpec = {
311
- content: "(paragraph | table | textBox)+",
312
+ content: "(paragraph | table | textBox | preservedBlock)+",
312
313
  tableRole: "cell",
313
314
  isolating: true,
314
315
  attrs: {
@@ -366,7 +367,7 @@ const tableCellSpec = {
366
367
  }
367
368
  };
368
369
  const tableHeaderSpec = {
369
- content: "(paragraph | table | textBox)+",
370
+ content: "(paragraph | table | textBox | preservedBlock)+",
370
371
  tableRole: "header_cell",
371
372
  isolating: true,
372
373
  attrs: {
@@ -77,19 +77,26 @@ const TextBoxExtension = createNodeExtension({
77
77
  attrs: {
78
78
  width: { default: 200 },
79
79
  height: { default: null },
80
+ _docxAuthoredEmu: { default: null },
80
81
  autoFit: { default: null },
81
82
  wordArt: { default: null },
82
83
  textWrap: { default: null },
83
84
  textBoxId: { default: null },
85
+ textBoxName: { default: null },
86
+ alt: { default: null },
87
+ title: { default: null },
84
88
  fillColor: { default: null },
85
89
  outlineWidth: { default: null },
86
90
  outlineColor: { default: null },
87
91
  outlineStyle: { default: null },
88
92
  transform: { default: null },
89
- marginTop: { default: 4 },
90
- marginBottom: { default: 4 },
91
- marginLeft: { default: 7 },
92
- marginRight: { default: 7 },
93
+ docxRotation: { default: null },
94
+ docxFlipH: { default: null },
95
+ docxFlipV: { default: null },
96
+ marginTop: { default: null },
97
+ marginBottom: { default: null },
98
+ marginLeft: { default: null },
99
+ marginRight: { default: null },
93
100
  verticalAlign: { default: null },
94
101
  displayMode: { default: "inline" },
95
102
  cssFloat: { default: null },
@@ -105,7 +112,8 @@ const TextBoxExtension = createNodeExtension({
105
112
  _docxAnchorId: { default: null },
106
113
  _docxTextBodyContentState: { default: { type: "authored" } },
107
114
  _docxTrackedChange: { default: null },
108
- _docxInlineSdts: { default: null }
115
+ _docxInlineSdts: { default: null },
116
+ _preservedAttributes: { default: null }
109
117
  },
110
118
  parseDOM: [{
111
119
  tag: "div.docx-textbox",
@@ -0,0 +1,39 @@
1
+ import { document_d_exports } from "../types/document.js";
2
+ import { InlineWrapperLayer } from "./schema/marks.js";
3
+ //#region src/prosemirror/inlineWrapperStack.d.ts
4
+ /** The DOM attribute that carries a serialised stack through copy and paste. */
5
+ declare const INLINE_WRAPPER_STACK_ATTRIBUTE = "data-inline-wrapper";
6
+ /** A layer with its keys in canonical order, absent fields left absent. */
7
+ declare const inlineWrapperLayer: (layer: InlineWrapperLayer) => InlineWrapperLayer;
8
+ /**
9
+ * The model member a layer describes, holding `content`.
10
+ *
11
+ * The inverse of the `WrapperLayer` projection: `toProseDoc` takes the model
12
+ * member apart into a layer and its content, and the save leg puts one back
13
+ * together. Both directions live here so a wrapper kind is spelled once.
14
+ */
15
+ declare const inlineWrapperMember: (layer: InlineWrapperLayer, content: document_d_exports.InlineWrapper["content"]) => document_d_exports.InlineWrapper;
16
+ /** `layers` in canonical form, or `null` when there is no wrapper to record. */
17
+ declare const inlineWrapperStack: (layers: readonly InlineWrapperLayer[]) => readonly InlineWrapperLayer[] | null;
18
+ declare const serializeInlineWrapperStack: (stack: readonly InlineWrapperLayer[]) => string;
19
+ /**
20
+ * The key two stacks share exactly when they are the same nest of wrappers.
21
+ *
22
+ * The save leg groups adjacent inline leaves by it, so it has to be the
23
+ * factory's canonical spelling rather than whatever order an attrs object
24
+ * happens to carry: two leaves inside one `w:bdo` that keyed differently would
25
+ * be written as two `w:bdo` elements. The empty stack keys as the empty string,
26
+ * which is what "inside no wrapper" compares as.
27
+ */
28
+ declare const inlineWrapperStackKey: (stack: readonly InlineWrapperLayer[]) => string;
29
+ /**
30
+ * A stack read back from the DOM, or `null` when the markup carries none.
31
+ *
32
+ * Paste from outside the editor is the ordinary case: the attribute is absent,
33
+ * so the pasted leaf carries no wrapper. Markup that states the attribute but
34
+ * not a stack this build validates is read the same way — the text is what
35
+ * matters, and inventing a wrapper around it would change the document.
36
+ */
37
+ declare const parseInlineWrapperStack: (serialized: string | null | undefined) => readonly InlineWrapperLayer[] | null;
38
+ //#endregion
39
+ export { INLINE_WRAPPER_STACK_ATTRIBUTE, inlineWrapperLayer, inlineWrapperMember, inlineWrapperStack, inlineWrapperStackKey, parseInlineWrapperStack, serializeInlineWrapperStack };
@@ -0,0 +1,75 @@
1
+ import { readInlineWrapperStack } from "./attrs/index.js";
2
+ import { Result, panic } from "better-result";
3
+ //#region src/prosemirror/inlineWrapperStack.ts
4
+ /**
5
+ * The one place an inline-wrapper layer is built, and the codec that carries a
6
+ * stack through the DOM.
7
+ *
8
+ * Two layers describing the same wrapper have to be the same value, because
9
+ * `fromProseDoc` groups inline leaves into runs by `JSON.stringify` over their
10
+ * mark attrs: one wrapper spelled with its keys in two orders would split one
11
+ * run into two. Object key order is insertion order in JavaScript, so the
12
+ * factory fixes it and every construction site goes through the factory —
13
+ * including the one that reads a stack back out of the DOM, where `JSON.parse`
14
+ * preserves whatever order the markup happened to carry.
15
+ */
16
+ /** The DOM attribute that carries a serialised stack through copy and paste. */
17
+ const INLINE_WRAPPER_STACK_ATTRIBUTE = "data-inline-wrapper";
18
+ /** A layer with its keys in canonical order, absent fields left absent. */
19
+ const inlineWrapperLayer = (layer) => {
20
+ switch (layer.kind) {
21
+ case "bidi": return layer.direction === void 0 ? {
22
+ kind: "bidi",
23
+ control: layer.control
24
+ } : {
25
+ kind: "bidi",
26
+ control: layer.control,
27
+ direction: layer.direction
28
+ };
29
+ default:
30
+ layer.kind;
31
+ panic(`Unsupported inline wrapper layer: ${JSON.stringify(layer)}`);
32
+ }
33
+ };
34
+ /**
35
+ * The model member a layer describes, holding `content`.
36
+ *
37
+ * The inverse of the `WrapperLayer` projection: `toProseDoc` takes the model
38
+ * member apart into a layer and its content, and the save leg puts one back
39
+ * together. Both directions live here so a wrapper kind is spelled once.
40
+ */
41
+ const inlineWrapperMember = (layer, content) => ({
42
+ ...inlineWrapperLayer(layer),
43
+ type: "inlineWrapper",
44
+ content
45
+ });
46
+ /** `layers` in canonical form, or `null` when there is no wrapper to record. */
47
+ const inlineWrapperStack = (layers) => layers.length === 0 ? null : layers.map(inlineWrapperLayer);
48
+ const serializeInlineWrapperStack = (stack) => JSON.stringify(stack);
49
+ /**
50
+ * The key two stacks share exactly when they are the same nest of wrappers.
51
+ *
52
+ * The save leg groups adjacent inline leaves by it, so it has to be the
53
+ * factory's canonical spelling rather than whatever order an attrs object
54
+ * happens to carry: two leaves inside one `w:bdo` that keyed differently would
55
+ * be written as two `w:bdo` elements. The empty stack keys as the empty string,
56
+ * which is what "inside no wrapper" compares as.
57
+ */
58
+ const inlineWrapperStackKey = (stack) => stack.length === 0 ? "" : serializeInlineWrapperStack(stack.map(inlineWrapperLayer));
59
+ /**
60
+ * A stack read back from the DOM, or `null` when the markup carries none.
61
+ *
62
+ * Paste from outside the editor is the ordinary case: the attribute is absent,
63
+ * so the pasted leaf carries no wrapper. Markup that states the attribute but
64
+ * not a stack this build validates is read the same way — the text is what
65
+ * matters, and inventing a wrapper around it would change the document.
66
+ */
67
+ const parseInlineWrapperStack = (serialized) => {
68
+ if (!serialized) return null;
69
+ const parsed = Result.try(() => JSON.parse(serialized));
70
+ if (parsed.isErr()) return null;
71
+ const stack = readInlineWrapperStack(parsed.value);
72
+ return stack.ok ? stack.value.map(inlineWrapperLayer) : null;
73
+ };
74
+ //#endregion
75
+ export { INLINE_WRAPPER_STACK_ATTRIBUTE, inlineWrapperLayer, inlineWrapperMember, inlineWrapperStack, inlineWrapperStackKey, parseInlineWrapperStack, serializeInlineWrapperStack };
@@ -2,17 +2,27 @@ import { document_d_exports } from "../types/document.js";
2
2
  import { ParagraphAttrs } from "./schema/nodes.js";
3
3
  import { Node } from "prosemirror-model";
4
4
  //#region src/prosemirror/pageBreakRunProjection.d.ts
5
+ /**
6
+ * Paragraph shapes whose explicit page-break run the editor lays out
7
+ * approximately.
8
+ *
9
+ * Layout splits a paragraph into fragments at its breaks, and a paragraph
10
+ * property that describes the paragraph as a whole then applies to each
11
+ * fragment. That is an approximation, not a loss: the run is projected, it is
12
+ * saved, and the document opens. Folio used to refuse these instead, which
13
+ * meant a file Word opens could not be opened, laid out or exported at all.
14
+ */
5
15
  declare const PAGE_BREAK_RUN_PARAGRAPH_PROJECTION_MESSAGES: {
6
- readonly borders: "A bordered paragraph containing an explicit page-break run cannot be projected";
7
- readonly frame: "A framed paragraph containing an explicit page-break run cannot be projected";
8
- readonly outline: "An outline paragraph containing an explicit page-break run cannot be projected";
9
- readonly textBoxAnchor: "A paragraph whose text-box anchor follows an explicit page-break run cannot be projected";
16
+ readonly borders: "A bordered paragraph is split at its explicit page-break run, so its border is drawn around each part";
17
+ readonly frame: "A framed paragraph is split at its explicit page-break run, so its frame applies to each part";
18
+ readonly outline: "An outline paragraph is split at its explicit page-break run, so each part carries the outline level";
19
+ readonly textBoxAnchor: "A text-box anchor following an explicit page-break run is hosted by the paragraph's first part";
10
20
  };
11
21
  type PageBreakRunParagraphProjectionReason = keyof typeof PAGE_BREAK_RUN_PARAGRAPH_PROJECTION_MESSAGES;
12
22
  type PageBreakRunParagraphProjectionDisposition = {
13
- status: "supported";
23
+ status: "exact";
14
24
  } | {
15
- status: "unsupported";
25
+ status: "approximate";
16
26
  reason: PageBreakRunParagraphProjectionReason;
17
27
  message: (typeof PAGE_BREAK_RUN_PARAGRAPH_PROJECTION_MESSAGES)[keyof typeof PAGE_BREAK_RUN_PARAGRAPH_PROJECTION_MESSAGES];
18
28
  };
@@ -25,7 +35,7 @@ type PageBreakRunParagraphFeatures = {
25
35
  * Layout splits such a paragraph into fragments at its breaks, and only the
26
36
  * first fragment keeps the paragraph's block id, which is what an anchor
27
37
  * resolves its host through. An anchor before the first break is therefore
28
- * projected faithfully; one after it would lose its host.
38
+ * laid out exactly; one after it falls back to the first fragment.
29
39
  */
30
40
  textBoxAnchorAfterPageBreak: boolean;
31
41
  };