@stll/folio-core 0.59.0 → 0.61.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 (226) hide show
  1. package/README.md +23 -1
  2. package/dist/ai-edits/apply.js +139 -32
  3. package/dist/ai-edits/headless.d.ts +3 -0
  4. package/dist/ai-edits/headless.js +57 -63
  5. package/dist/ai-edits/note-story-inventory.d.ts +7 -0
  6. package/dist/ai-edits/note-story-inventory.js +11 -0
  7. package/dist/ai-edits/read.js +16 -9
  8. package/dist/ai-edits/revisionStretches.js +52 -1
  9. package/dist/ai-edits/table-row-column-mutations.js +6 -1
  10. package/dist/compare/reproducible-package.js +2 -1
  11. package/dist/compare/verification.js +1 -0
  12. package/dist/compat/eigenpal.d.ts +4 -2
  13. package/dist/compat/eigenpal.js +2 -2
  14. package/dist/controller/canonicalClipboard.js +2 -1
  15. package/dist/controller/canonicalListRendering.d.ts +4 -6
  16. package/dist/controller/canonicalListRendering.js +3 -157
  17. package/dist/controller/canonicalSession.js +3 -2
  18. package/dist/controller/canonicalStructure.js +10 -7
  19. package/dist/controller/fontReadiness.js +1 -1
  20. package/dist/controller/headerFooterEditorManager.d.ts +1 -0
  21. package/dist/controller/headerFooterEditorManager.js +11 -0
  22. package/dist/controller/hiddenEditorManager.d.ts +1 -1
  23. package/dist/controller/hiddenEditorManager.js +3 -1
  24. package/dist/controller/layoutPipeline.d.ts +3 -1
  25. package/dist/controller/layoutPipeline.js +19 -4
  26. package/dist/controller/layoutSession.d.ts +4 -1
  27. package/dist/display-list/build/fontTable.js +7 -5
  28. package/dist/display-list/build/furniture.d.ts +1 -0
  29. package/dist/display-list/build/furniture.js +1 -0
  30. package/dist/display-list/build/imagePrimitives.js +3 -6
  31. package/dist/display-list/build/watermarkPrimitives.d.ts +2 -1
  32. package/dist/display-list/build/watermarkPrimitives.js +9 -3
  33. package/dist/display-list/editor/pageRenderer.js +1 -0
  34. package/dist/docx/bookmarkIdNormalization.d.ts +10 -0
  35. package/dist/docx/bookmarkIdNormalization.js +100 -0
  36. package/dist/docx/bookmarkParser.js +4 -2
  37. package/dist/docx/canonicalStoryRepack.js +3 -2
  38. package/dist/docx/commentTextParagraph.d.ts +6 -0
  39. package/dist/docx/commentTextParagraph.js +15 -0
  40. package/dist/docx/conformance.js +6 -1
  41. package/dist/docx/diagramPreview.js +2 -1
  42. package/dist/docx/documentParser.d.ts +13 -1
  43. package/dist/docx/documentParser.js +1 -1
  44. package/dist/docx/encryption/compoundFile.d.ts +0 -8
  45. package/dist/docx/encryption/compoundFile.js +2 -1
  46. package/dist/docx/encryption/cryptoBytes.d.ts +2 -2
  47. package/dist/docx/encryption/cryptoBytes.js +3 -18
  48. package/dist/docx/encryption/encryptionInfo.d.ts +0 -5
  49. package/dist/docx/encryption/encryptionInfo.js +2 -1
  50. package/dist/docx/ensureParaIds.js +2 -1
  51. package/dist/docx/groupDrawingParser.js +6 -1
  52. package/dist/docx/importedIdCollisions.d.ts +136 -0
  53. package/dist/docx/importedIdCollisions.js +215 -0
  54. package/dist/docx/listModelNormalization.d.ts +10 -0
  55. package/dist/docx/listModelNormalization.js +166 -0
  56. package/dist/docx/metadataPrivacy.js +3 -2
  57. package/dist/docx/metafileRaster.js +2 -1
  58. package/dist/docx/numberingParser.js +2 -2
  59. package/dist/docx/packageParts.js +6 -5
  60. package/dist/docx/paragraphParser.js +6 -4
  61. package/dist/docx/paragraphPropertySource.js +1 -2
  62. package/dist/docx/parseContext.d.ts +2 -1
  63. package/dist/docx/parseContext.js +1 -0
  64. package/dist/docx/parseWarningMessage.js +1 -0
  65. package/dist/docx/parser.js +10 -5
  66. package/dist/docx/preservedRunContent.js +11 -2
  67. package/dist/docx/relsParser.js +1 -1
  68. package/dist/docx/removeHeaderFooterParts.js +8 -7
  69. package/dist/docx/replyToComment.js +3 -13
  70. package/dist/docx/rezip.js +90 -90
  71. package/dist/docx/runParser.js +12 -6
  72. package/dist/docx/runPropertyPresence.d.ts +11 -0
  73. package/dist/docx/runPropertyPresence.js +14 -0
  74. package/dist/docx/selectedXmlIdentityScan.d.ts +10 -0
  75. package/dist/docx/selectedXmlIdentityScan.js +36 -0
  76. package/dist/docx/selectiveSave.js +19 -17
  77. package/dist/docx/selectiveXmlPatch.js +44 -52
  78. package/dist/docx/serializer/commentSerializer.d.ts +3 -1
  79. package/dist/docx/serializer/commentSerializer.js +11 -2
  80. package/dist/docx/serializer/runSerializer.js +5 -4
  81. package/dist/docx/serializer/tableSerializer.js +2 -1
  82. package/dist/docx/serializer/trackedChangeAttributes.d.ts +1 -3
  83. package/dist/docx/serializer/trackedChangeAttributes.js +1 -11
  84. package/dist/docx/server/applyDocxXmlPatchProposal.js +2 -2
  85. package/dist/docx/server/boundedArchive.js +2 -1
  86. package/dist/docx/server/evaluateDocxXmlPatchProposal.js +2 -1
  87. package/dist/docx/server/inspectDocxPackage.js +5 -1
  88. package/dist/docx/server/validateDocxConformance.js +2 -1
  89. package/dist/docx/tableParser.js +7 -4
  90. package/dist/docx/tableRowPropertyPresence.d.ts +9 -0
  91. package/dist/docx/tableRowPropertyPresence.js +15 -0
  92. package/dist/docx/unzip.js +2 -1
  93. package/dist/docx/xmlEncoding.js +6 -5
  94. package/dist/fonts/embeddedFontFingerprint.d.ts +5 -0
  95. package/dist/fonts/embeddedFontFingerprint.js +18 -0
  96. package/dist/fonts/embeddedFonts.d.ts +1 -1
  97. package/dist/fonts/embeddedFonts.js +1 -1
  98. package/dist/fonts/fontsourceFaces.js +2 -1
  99. package/dist/fonts/headlessMeasure.js +0 -0
  100. package/dist/fonts/sfnt/parse.js +6 -9
  101. package/dist/fonts/sfnt/subset.js +2 -1
  102. package/dist/fonts/sfnt/tables.js +2 -3
  103. package/dist/fonts/sfnt/woff.js +2 -1
  104. package/dist/headless-layout.js +1 -0
  105. package/dist/index.d.ts +4 -2
  106. package/dist/index.js +2 -2
  107. package/dist/internal/revisionResolutionInline.d.ts +2 -1
  108. package/dist/internal/revisionResolutionInline.js +22 -1
  109. package/dist/internal/wholeStoryRevisionResolution.js +24 -7
  110. package/dist/layout-bridge/convert/flowConversionShared.d.ts +4 -0
  111. package/dist/layout-bridge/convert/footnoteLayout.d.ts +5 -1
  112. package/dist/layout-bridge/convert/footnoteLayout.js +16 -3
  113. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +6 -0
  114. package/dist/layout-bridge/convert/headerFooterLayout.js +13 -14
  115. package/dist/layout-bridge/convert/paragraphConversion.js +8 -1
  116. package/dist/layout-bridge/convert/paragraphRuns.js +2 -1
  117. package/dist/layout-bridge/convert/toFlowBlocks.js +25 -1
  118. package/dist/layout-engine/measure/cache.js +39 -7
  119. package/dist/layout-engine/measure/crossRunWords.js +12 -2
  120. package/dist/layout-engine/measure/lineTypography.js +1 -0
  121. package/dist/layout-engine/measure/listMarkerWidth.d.ts +1 -0
  122. package/dist/layout-engine/measure/listMarkerWidth.js +1 -0
  123. package/dist/layout-engine/measure/measureContainer.js +3 -4
  124. package/dist/layout-engine/measure/measureHelpers.d.ts +6 -9
  125. package/dist/layout-engine/measure/measureHelpers.js +21 -18
  126. package/dist/layout-engine/measure/measureParagraph.js +2 -0
  127. package/dist/layout-engine/measure/measureTypes.d.ts +2 -0
  128. package/dist/layout-engine/types.d.ts +4 -1
  129. package/dist/layout-painter/renderPage.d.ts +1 -0
  130. package/dist/layout-painter/renderPage.js +11 -3
  131. package/dist/layout-painter/renderParagraph.js +13 -3
  132. package/dist/layout-painter/renderWatermark.d.ts +1 -0
  133. package/dist/layout-painter/renderWatermark.js +7 -3
  134. package/dist/managers/AutoSaveManager.js +2 -1
  135. package/dist/managers/EditorModeManager.d.ts +10 -1
  136. package/dist/managers/EditorModeManager.js +15 -1
  137. package/dist/managers/TableSelectionManager.d.ts +1 -1
  138. package/dist/managers/autoSaveCodec.js +2 -6
  139. package/dist/managers/editorShortcuts.d.ts +2 -1
  140. package/dist/managers/editorShortcuts.js +2 -1
  141. package/dist/managers/reviewDisplayMode.d.ts +8 -0
  142. package/dist/managers/reviewDisplayMode.js +15 -0
  143. package/dist/paged-layout/pageText.d.ts +11 -2
  144. package/dist/paged-layout/pageText.js +8 -3
  145. package/dist/pdf/fonts.js +5 -14
  146. package/dist/pdf/images.js +3 -2
  147. package/dist/pdf/objects.d.ts +0 -11
  148. package/dist/pdf/objects.js +7 -9
  149. package/dist/pdf/writePdf.js +2 -1
  150. package/dist/prosemirror/canonicalSelectionRange.d.ts +4 -1
  151. package/dist/prosemirror/canonicalSelectionRange.js +9 -3
  152. package/dist/prosemirror/commands/comments.js +51 -13
  153. package/dist/prosemirror/containerFinalParagraph.d.ts +8 -8
  154. package/dist/prosemirror/containerFinalParagraph.js +8 -8
  155. package/dist/prosemirror/conversion/fromProseDoc.js +9 -4
  156. package/dist/prosemirror/conversion/toProseDoc.js +4 -4
  157. package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.d.ts +8 -2
  158. package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +39 -3
  159. package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.d.ts +8 -2
  160. package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.js +4 -3
  161. package/dist/prosemirror/extensions/features/ImageDragExtension.js +4 -3
  162. package/dist/prosemirror/extensions/features/JoinedRunStyleExtension.js +4 -3
  163. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.d.ts +9 -3
  164. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +6 -5
  165. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +8 -2
  166. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +11 -3
  167. package/dist/prosemirror/extensions/marks/RunIdentityExtension.js +4 -3
  168. package/dist/prosemirror/extensions/marks/markUtils.js +1 -1
  169. package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +16 -2
  170. package/dist/prosemirror/findReplaceSelection.d.ts +11 -1
  171. package/dist/prosemirror/findReplaceSelection.js +15 -1
  172. package/dist/prosemirror/markupViewProjection.d.ts +10 -1
  173. package/dist/prosemirror/markupViewProjection.js +21 -3
  174. package/dist/prosemirror/pluginKeyOwner.d.ts +13 -0
  175. package/dist/prosemirror/pluginKeyOwner.js +35 -0
  176. package/dist/prosemirror/plugins/aiCitationDecorations.d.ts +11 -4
  177. package/dist/prosemirror/plugins/aiCitationDecorations.js +16 -3
  178. package/dist/prosemirror/plugins/aiSuggestionDecorations.d.ts +11 -4
  179. package/dist/prosemirror/plugins/aiSuggestionDecorations.js +18 -3
  180. package/dist/prosemirror/plugins/anonymizationDecorations.d.ts +11 -11
  181. package/dist/prosemirror/plugins/anonymizationDecorations.js +23 -13
  182. package/dist/prosemirror/plugins/autocompleteSuggestion.d.ts +8 -2
  183. package/dist/prosemirror/plugins/autocompleteSuggestion.js +27 -5
  184. package/dist/prosemirror/plugins/contentControlWidgets.d.ts +8 -2
  185. package/dist/prosemirror/plugins/contentControlWidgets.js +4 -3
  186. package/dist/prosemirror/plugins/createDocScanPlugin.d.ts +6 -5
  187. package/dist/prosemirror/plugins/createDocScanPlugin.js +1 -1
  188. package/dist/prosemirror/plugins/documentNumbering.js +5 -3
  189. package/dist/prosemirror/plugins/documentStyleState.d.ts +8 -2
  190. package/dist/prosemirror/plugins/documentStyleState.js +2 -2
  191. package/dist/prosemirror/plugins/documentStyles.js +1 -1
  192. package/dist/prosemirror/plugins/selectionTracker.d.ts +8 -2
  193. package/dist/prosemirror/plugins/selectionTracker.js +4 -3
  194. package/dist/prosemirror/plugins/suggestionMode.d.ts +8 -2
  195. package/dist/prosemirror/plugins/suggestionMode.js +4 -3
  196. package/dist/prosemirror/plugins/templateDirectives.d.ts +8 -2
  197. package/dist/prosemirror/plugins/templateDirectives.js +19 -4
  198. package/dist/prosemirror/plugins/templatePreviewValues.d.ts +8 -2
  199. package/dist/prosemirror/plugins/templatePreviewValues.js +27 -5
  200. package/dist/prosemirror/plugins/templateSlashMenu.d.ts +8 -2
  201. package/dist/prosemirror/plugins/templateSlashMenu.js +23 -5
  202. package/dist/prosemirror/plugins/transactionInvariants.js +29 -4
  203. package/dist/prosemirror/replacedAnnotations.d.ts +15 -1
  204. package/dist/prosemirror/replacedAnnotations.js +71 -12
  205. package/dist/prosemirror/runFormattingReconciliation.d.ts +3 -1
  206. package/dist/prosemirror/runFormattingReconciliation.js +10 -2
  207. package/dist/prosemirror/runIdentityAcrossRevisions.d.ts +5 -7
  208. package/dist/prosemirror/runIdentityAcrossRevisions.js +66 -38
  209. package/dist/prosemirror/runPropertyChangeResolution.js +13 -1
  210. package/dist/utils/base64.d.ts +1 -31
  211. package/dist/utils/base64.js +19 -33
  212. package/dist/utils/clipboard.js +5 -4
  213. package/dist/utils/colorResolver.js +11 -2
  214. package/dist/utils/findReplace.d.ts +5 -0
  215. package/dist/utils/fontLoader.d.ts +2 -2
  216. package/dist/utils/fontLoader.js +2 -7
  217. package/dist/utils/fontResolver.d.ts +7 -3
  218. package/dist/utils/fontResolver.js +6 -8
  219. package/dist/utils/replaceText.js +21 -4
  220. package/dist/utils/sliceText.d.ts +2 -0
  221. package/dist/utils/sliceText.js +2 -0
  222. package/dist/utils/textEncoding.d.ts +2 -0
  223. package/dist/utils/textEncoding.js +2 -0
  224. package/dist/utils/tiffConverter.d.ts +0 -9
  225. package/dist/utils/tiffConverter.js +2 -4
  226. package/package.json +73 -31
@@ -1,3 +1,4 @@
1
+ import { encodeUtf8 } from "../../utils/textEncoding.js";
1
2
  import { getDocxXmlSafetyIssue } from "../xmlSafety.js";
2
3
  import { DocxArchiveError } from "./boundedArchive.js";
3
4
  import { FolioDocxPackageInspectionError, inspectDocxPackage } from "./inspectDocxPackage.js";
@@ -264,7 +265,7 @@ const evaluateDocxXmlPatchProposal = async ({ bytes, proposal: rawProposal, allo
264
265
  });
265
266
  }
266
267
  if (exceedsPartLowerBound || totalLimitReported) continue;
267
- const replacementBytes = new TextEncoder().encode(replacement.replacementXml);
268
+ const replacementBytes = encodeUtf8(replacement.replacementXml);
268
269
  const exceedsEncodedPart = replacementBytes.byteLength > limits.maxPartBytes;
269
270
  const nextEncodedTotalBytes = encodedTotalBytes + replacementBytes.byteLength;
270
271
  if (exceedsEncodedPart) issues.push({
@@ -1,3 +1,4 @@
1
+ import { decodeText } from "../../utils/textEncoding.js";
1
2
  import { getAttributeAnyPrefix, getLocalName, parseXmlDocument } from "../xmlParser.js";
2
3
  import { DocxArchiveError, loadDocxArchive } from "./boundedArchive.js";
3
4
  import { Result, TaggedError } from "better-result";
@@ -33,7 +34,10 @@ const decodeXml = (bytes, part) => {
33
34
  if (bytes.length >= 2 && (bytes[0] === 255 && bytes[1] === 254 || bytes[0] === 60 && bytes[1] === 0)) encoding = "utf-16le";
34
35
  else if (bytes.length >= 2 && (bytes[0] === 254 && bytes[1] === 255 || bytes[0] === 0 && bytes[1] === 60)) encoding = "utf-16be";
35
36
  const decoded = Result.try({
36
- try: () => new TextDecoder(encoding, { fatal: true }).decode(bytes),
37
+ try: () => decodeText(bytes, {
38
+ encoding,
39
+ fatal: true
40
+ }),
37
41
  catch: (cause) => new FolioDocxPackageInspectionError({
38
42
  message: `Failed to decode XML package part "${part}"`,
39
43
  code: "xml-decode-failed",
@@ -1,3 +1,4 @@
1
+ import { decodeText } from "../../utils/textEncoding.js";
1
2
  import { detectDocxConformanceClass } from "../conformance.js";
2
3
  import { DOCX_CONTAINER_TYPES, detectDocxContainerType } from "../encryption/containerFormat.js";
3
4
  import { DocxModelValidationError, validateFolioDocumentModel } from "../modelValidation.js";
@@ -131,7 +132,7 @@ const readPartForInspection = async (archive, part) => {
131
132
  } catch (error) {
132
133
  if (!(error instanceof XmlResourceLimitError) || error.limit !== "syntax") throw error;
133
134
  const bytes = await archive.readEntryUint8(part);
134
- return bytes === null ? null : new TextDecoder("utf-8", { ignoreBOM: true }).decode(bytes);
135
+ return bytes === null ? null : decodeText(bytes, { ignoreBOM: true });
135
136
  }
136
137
  };
137
138
  const validateXmlParts = async (archive, report) => {
@@ -11,10 +11,11 @@ import { captureSdtSiblingMarkers, parseSdtProperties } from "./sdtProperties.js
11
11
  import { parseShading } from "./shadingParser.js";
12
12
  import { findChildAnySpelling } from "./strictNames.js";
13
13
  import { TABLE_LOOK_FLAGS } from "./tableLook.js";
14
+ import { isEmptyRowPropertiesAttribute, retainsEmptyRowProperties } from "./tableRowPropertyPresence.js";
14
15
  import { parsePropertyChangeInfo, parseTrackedChangeInfo } from "./trackedChangeInfo.js";
15
16
  import { percentageSpelling, transitionalSlotEncoding } from "./transitionalSpelling.js";
16
17
  import { captureVerbatimXml } from "./verbatimCapture.js";
17
- import { WORDPROCESSINGML_NAMESPACE_URIS, cloneElement, findChild, findChildren, findWordprocessingChild, getAttribute, getAttributeByNamespaceUri, getLocalName, mergeXmlnsDeclarations, parseBooleanElement, parseNumericAttribute, parseOnOffAttribute, parseTableMeasurementValue, selectAlternateContentBranch } from "./xmlParser.js";
18
+ import { WORDPROCESSINGML_NAMESPACE_URIS, cloneElement, findChild, findChildren, findWordprocessingChild, getAttribute, getAttributeByNamespaceUri, getChildElements, getLocalName, mergeXmlnsDeclarations, parseBooleanElement, parseNumericAttribute, parseOnOffAttribute, parseTableMeasurementValue, selectAlternateContentBranch } from "./xmlParser.js";
18
19
  import { PARSE_WARNING_CODES } from "@stll/docx-core/model";
19
20
  //#region src/docx/tableParser.ts
20
21
  /**
@@ -637,6 +638,8 @@ function parseTableRowProperties(trPrElement) {
637
638
  context: formatting
638
639
  });
639
640
  if (preserved) formatting.preserved = preserved;
641
+ const children = getChildElements(trPrElement);
642
+ if (Object.keys(formatting).length === 0 && children.length > 0 && Object.keys(trPrElement.attributes ?? {}).every((name) => name === "xmlns" || name.startsWith("xmlns:")) && children.every((child) => WORDPROCESSINGML_NAMESPACE_URIS.has(child.namespaceUri ?? "") && REVISION_PROPERTY_CHILDREN.has(getLocalName(child.name)))) return void 0;
640
643
  return withSourceXml(formatting, trPrElement);
641
644
  }
642
645
  /**
@@ -1099,7 +1102,7 @@ function parseTableRow(trElement, styles, theme, numbering, rels, media, options
1099
1102
  const exceptionChanges = parseTablePropertyExceptionChanges(tblPrExElement, exceptions);
1100
1103
  if (exceptionChanges !== void 0) row.tablePropertyExceptionChanges = exceptionChanges;
1101
1104
  const trPrElement = findChild(trElement, "w", "trPr");
1102
- const formatting = parseTableRowProperties(trPrElement);
1105
+ const formatting = parseTableRowProperties(trPrElement) ?? (trPrElement && retainsEmptyRowProperties(trElement) ? withSourceXml({}, trPrElement) : void 0);
1103
1106
  if (formatting) row.formatting = formatting;
1104
1107
  const rowPropChanges = parseTableRowPropertyChanges(trPrElement, formatting);
1105
1108
  if (rowPropChanges !== void 0) row.propertyChanges = rowPropChanges;
@@ -1126,8 +1129,8 @@ function parseTableRow(trElement, styles, theme, numbering, rels, media, options
1126
1129
  const remainingAttributes = attributeRemainder({
1127
1130
  element: trElement,
1128
1131
  modelled: NO_MODELLED_ATTRIBUTES
1129
- });
1130
- if (remainingAttributes) row.preservedAttributes = remainingAttributes;
1132
+ })?.filter((attribute) => !isEmptyRowPropertiesAttribute(attribute));
1133
+ if (remainingAttributes?.length) row.preservedAttributes = remainingAttributes;
1131
1134
  return row;
1132
1135
  }
1133
1136
  /**
@@ -0,0 +1,9 @@
1
+ import { document_d_exports } from "../types/document.js";
2
+ import { XmlElement } from "./xmlParser.js";
3
+ //#region src/docx/tableRowPropertyPresence.d.ts
4
+ declare const EMPTY_ROW_PROPERTIES_ATTRIBUTE = "emptyRowProperties";
5
+ declare const retainsEmptyRowProperties: (element: XmlElement) => boolean;
6
+ declare const serializeEmptyRowProperties: (row: document_d_exports.TableRow) => string[];
7
+ declare const isEmptyRowPropertiesAttribute: ({ namespace, name }: Pick<document_d_exports.PreservedAttribute, "namespace" | "name">) => boolean;
8
+ //#endregion
9
+ export { EMPTY_ROW_PROPERTIES_ATTRIBUTE, isEmptyRowPropertiesAttribute, retainsEmptyRowProperties, serializeEmptyRowProperties };
@@ -0,0 +1,15 @@
1
+ import { OOXML_NAMESPACES } from "./serializer/partNamespaces.js";
2
+ import { getAttributeByNamespaceUri } from "./xmlParser.js";
3
+ import { EMPTY_PROPERTY_SETS } from "@stll/docx-core/ops";
4
+ //#region src/docx/tableRowPropertyPresence.ts
5
+ const EMPTY_ROW_PROPERTIES_ATTRIBUTE = "emptyRowProperties";
6
+ const HISTORY_NAMESPACES = /* @__PURE__ */ new Set([OOXML_NAMESPACES.folio.uri]);
7
+ const retainsEmptyRowProperties = (element) => getAttributeByNamespaceUri(element, HISTORY_NAMESPACES, EMPTY_ROW_PROPERTIES_ATTRIBUTE) === EMPTY_PROPERTY_SETS.KEEP;
8
+ const serializeEmptyRowProperties = (row) => {
9
+ if (row.formatting === void 0 || row.structuralChange === void 0 && !row.propertyChanges?.length) return [];
10
+ const { sourceXml: _source, ...properties } = row.formatting;
11
+ return Object.keys(properties).length === 0 ? [`folio:${EMPTY_ROW_PROPERTIES_ATTRIBUTE}="${EMPTY_PROPERTY_SETS.KEEP}"`] : [];
12
+ };
13
+ const isEmptyRowPropertiesAttribute = ({ namespace, name }) => namespace === OOXML_NAMESPACES.folio.uri && name === "emptyRowProperties";
14
+ //#endregion
15
+ export { EMPTY_ROW_PROPERTIES_ATTRIBUTE, isEmptyRowPropertiesAttribute, retainsEmptyRowProperties, serializeEmptyRowProperties };
@@ -1,4 +1,5 @@
1
1
  import { bytesToDataUrl } from "../utils/base64.js";
2
+ import { encodeUtf8 } from "../utils/textEncoding.js";
2
3
  import { compressionRatioLimitFor, countCentralDirectoryRecords, createInflationBudget, exceedsCompressionRatio, getZipEntrySizes, inflateEntryWithinLimits, isStoredZipEntry } from "./archiveInflation.js";
3
4
  import { DOCX_CONTAINER_TYPES, detectDocxContainerType } from "./encryption/containerFormat.js";
4
5
  import { openDocxBuffer } from "./encryption/openEncryptedDocx.js";
@@ -286,7 +287,7 @@ const replaceRawDocxXmlParts = async (content, parts) => {
286
287
  writeZipPart({
287
288
  zip: content.originalZip,
288
289
  path,
289
- data: xmlContent
290
+ data: encodeUtf8(xmlContent)
290
291
  });
291
292
  identitiesChanged = true;
292
293
  }
@@ -1,12 +1,13 @@
1
+ import { decodeText } from "../utils/textEncoding.js";
1
2
  //#region src/docx/xmlEncoding.ts
2
3
  /** Decode the UTF-8 and UTF-16 encodings XML processors must recognize. */
3
4
  const decodeXmlBytes = (bytes) => {
4
- if (bytes[0] === 255 && bytes[1] === 254) return new TextDecoder("utf-16le").decode(bytes.subarray(2));
5
- if (bytes[0] === 254 && bytes[1] === 255) return new TextDecoder("utf-16be").decode(bytes.subarray(2));
6
- if (bytes[0] === 60 && bytes[1] === 0 && bytes[2] === 63 && bytes[3] === 0) return new TextDecoder("utf-16le").decode(bytes);
7
- if (bytes[0] === 0 && bytes[1] === 60 && bytes[2] === 0 && bytes[3] === 63) return new TextDecoder("utf-16be").decode(bytes);
5
+ if (bytes[0] === 255 && bytes[1] === 254) return decodeText(bytes.subarray(2), { encoding: "utf-16le" });
6
+ if (bytes[0] === 254 && bytes[1] === 255) return decodeText(bytes.subarray(2), { encoding: "utf-16be" });
7
+ if (bytes[0] === 60 && bytes[1] === 0 && bytes[2] === 63 && bytes[3] === 0) return decodeText(bytes, { encoding: "utf-16le" });
8
+ if (bytes[0] === 0 && bytes[1] === 60 && bytes[2] === 0 && bytes[3] === 63) return decodeText(bytes, { encoding: "utf-16be" });
8
9
  const utf8Offset = bytes[0] === 239 && bytes[1] === 187 && bytes[2] === 191 ? 3 : 0;
9
- return new TextDecoder("utf-8").decode(bytes.subarray(utf8Offset));
10
+ return decodeText(bytes.subarray(utf8Offset), { encoding: "utf-8" });
10
11
  };
11
12
  //#endregion
12
13
  export { decodeXmlBytes };
@@ -0,0 +1,5 @@
1
+ //#region src/fonts/embeddedFontFingerprint.d.ts
2
+ /** Callers replace owned maps on font changes; mutating a published map is unsupported. */
3
+ declare const embeddedFontFingerprint: (families: ReadonlyMap<string, string>) => string;
4
+ //#endregion
5
+ export { embeddedFontFingerprint };
@@ -0,0 +1,18 @@
1
+ //#region src/fonts/embeddedFontFingerprint.ts
2
+ /** Immutable editor-owned lookups share content fingerprints without retaining disposed editors. */
3
+ const fingerprints = /* @__PURE__ */ new WeakMap();
4
+ /** Callers replace owned maps on font changes; mutating a published map is unsupported. */
5
+ const embeddedFontFingerprint = (families) => {
6
+ const cached = fingerprints.get(families);
7
+ if (cached !== void 0) return cached;
8
+ const entries = [...families].sort(([left], [right]) => {
9
+ if (left < right) return -1;
10
+ if (left > right) return 1;
11
+ return 0;
12
+ });
13
+ const fingerprint = JSON.stringify(entries);
14
+ fingerprints.set(families, fingerprint);
15
+ return fingerprint;
16
+ };
17
+ //#endregion
18
+ export { embeddedFontFingerprint };
@@ -66,7 +66,7 @@ declare function getEmbeddedFontFaces(parts: EmbeddedFontParts, docNonce?: strin
66
66
  /**
67
67
  * Build the original DOCX font name → scoped registered family map for a set
68
68
  * of resolved embedded faces. Callers thread this into font resolution (see
69
- * `utils/fontResolver.ts`'s `setEmbeddedFontFamilyMap`) so the document's own
69
+ * the editor-owned layout session) so the document's own
70
70
  * runs — which still carry the original name — keep resolving to the scoped
71
71
  * face that was actually registered on `document.fonts`.
72
72
  */
@@ -111,7 +111,7 @@ function getEmbeddedFontFaces(parts, docNonce = generateHexId()) {
111
111
  /**
112
112
  * Build the original DOCX font name → scoped registered family map for a set
113
113
  * of resolved embedded faces. Callers thread this into font resolution (see
114
- * `utils/fontResolver.ts`'s `setEmbeddedFontFamilyMap`) so the document's own
114
+ * the editor-owned layout session) so the document's own
115
115
  * runs — which still carry the original name — keep resolving to the scoped
116
116
  * face that was actually registered on `document.fonts`.
117
117
  */
@@ -1,6 +1,7 @@
1
1
  import { bytesToDataUrl } from "../utils/base64.js";
2
2
  import { FONT_MAPPING } from "../utils/fontLoader.js";
3
3
  import { parseFontFamilyList, resolveFontFamily } from "../utils/fontResolver.js";
4
+ import { decodeText } from "../utils/textEncoding.js";
4
5
  //#region src/fonts/fontsourceFaces.ts
5
6
  /**
6
7
  * The subsets served, in resolution priority: a code point two subsets cover
@@ -78,7 +79,7 @@ const parseRangeToken = (token) => {
78
79
  const parseRangeList = (declared) => declared.split(",").flatMap(parseRangeToken);
79
80
  const parseDeclaredRanges = (bytes) => {
80
81
  const ranges = /* @__PURE__ */ new Map();
81
- const parsed = JSON.parse(new TextDecoder().decode(bytes));
82
+ const parsed = JSON.parse(decodeText(bytes));
82
83
  if (typeof parsed !== "object" || parsed === null) return ranges;
83
84
  for (const [subset, declared] of Object.entries(parsed)) if (typeof declared === "string") ranges.set(subset, parseRangeList(declared));
84
85
  return ranges;
Binary file
@@ -1,3 +1,4 @@
1
+ import { decodeText } from "../../utils/textEncoding.js";
1
2
  import { SFNT_TABLE, SFNT_VERSION, fitsInView, readLocaOffsets, readSfntDirectory, readSfntVersion } from "./tables.js";
2
3
  import { Result, TaggedError } from "better-result";
3
4
  //#region src/fonts/sfnt/parse.ts
@@ -344,17 +345,13 @@ const sanitizePostScriptName = (raw) => {
344
345
  return name.slice(0, MAX_POSTSCRIPT_NAME_LENGTH);
345
346
  };
346
347
  const decodeUtf16Be = (view, offset, length) => {
347
- let text = "";
348
- for (let index = 0; index + 1 < length; index += 2) text += String.fromCharCode(view.getUint16(offset + index));
349
- return text;
348
+ return decodeText(new Uint8Array(view.buffer, view.byteOffset + offset, length - length % 2), {
349
+ encoding: "utf-16be",
350
+ ignoreBOM: true
351
+ });
350
352
  };
351
353
  const decodeMacRomanAscii = (view, offset, length) => {
352
- let text = "";
353
- for (let index = 0; index < length; index++) {
354
- const code = view.getUint8(offset + index);
355
- text += code < 128 ? String.fromCharCode(code) : "";
356
- }
357
- return text;
354
+ return decodeText(new Uint8Array(view.buffer, view.byteOffset + offset, length).filter((byte) => byte < 128), { encoding: "binary" });
358
355
  };
359
356
  /**
360
357
  * name id 6, preferring the Windows UTF-16BE record over the Macintosh one.
@@ -1,3 +1,4 @@
1
+ import { encodeBinaryString } from "../../utils/textEncoding.js";
1
2
  import { SFNT_TABLE, SFNT_VERSION, fitsInView, readLocaOffsets, readSfntDirectory } from "./tables.js";
2
3
  import { Result, TaggedError, panic } from "better-result";
3
4
  //#region src/fonts/sfnt/subset.ts
@@ -223,7 +224,7 @@ const assembleSfnt = (tables) => {
223
224
  let dataOffset = 12 + directorySize;
224
225
  let headOffset = -1;
225
226
  for (const table of sorted) {
226
- for (let index = 0; index < table.tag.length; index++) view.setUint8(entry + index, table.tag.charCodeAt(index));
227
+ output.set(encodeBinaryString(table.tag), entry);
227
228
  view.setUint32(entry + 4, checksumOf(table.data));
228
229
  view.setUint32(entry + 8, dataOffset);
229
230
  view.setUint32(entry + 12, table.data.byteLength);
@@ -1,3 +1,4 @@
1
+ import { decodeText } from "../../utils/textEncoding.js";
1
2
  import { Result, TaggedError } from "better-result";
2
3
  //#region src/fonts/sfnt/tables.ts
3
4
  /**
@@ -65,9 +66,7 @@ const fitsInView = (view, offset, length) => Number.isInteger(offset) && Number.
65
66
  /** The four-byte tag at `offset`, or `""` when it does not fit. */
66
67
  const readTag = (view, offset) => {
67
68
  if (!fitsInView(view, offset, TAG_LENGTH)) return "";
68
- let tag = "";
69
- for (let index = 0; index < TAG_LENGTH; index++) tag += String.fromCharCode(view.getUint8(offset + index));
70
- return tag;
69
+ return decodeText(new Uint8Array(view.buffer, view.byteOffset + offset, TAG_LENGTH), { encoding: "binary" });
71
70
  };
72
71
  /** The leading version word, or `undefined` when the buffer is shorter than it. */
73
72
  const readSfntVersion = (bytes) => {
@@ -1,3 +1,4 @@
1
+ import { encodeBinaryString } from "../../utils/textEncoding.js";
1
2
  import { SFNT_VERSION, readSfntVersion, readTag } from "./tables.js";
2
3
  import { Result, TaggedError } from "better-result";
3
4
  import { inflateSync } from "node:zlib";
@@ -76,7 +77,7 @@ const buildSfnt = (flavor, tables) => {
76
77
  let entry = 12;
77
78
  let dataOffset = 12 + directorySize;
78
79
  for (const table of sorted) {
79
- for (let index = 0; index < table.tag.length; index++) view.setUint8(entry + index, table.tag.charCodeAt(index));
80
+ output.set(encodeBinaryString(table.tag), entry);
80
81
  view.setUint32(entry + 4, table.checksum);
81
82
  view.setUint32(entry + 8, dataOffset);
82
83
  view.setUint32(entry + 12, table.data.byteLength);
@@ -108,6 +108,7 @@ const buildBlockLookup = (blocks, measures) => new Map(blocks.flatMap((block, in
108
108
  }]];
109
109
  }));
110
110
  const buildStoryOptions = (flowOptions) => ({
111
+ ...flowOptions.embeddedFontFamilyMap === void 0 ? {} : { embeddedFontFamilyMap: flowOptions.embeddedFontFamilyMap },
111
112
  ...flowOptions.defaultSize === void 0 ? {} : { defaultSize: flowOptions.defaultSize },
112
113
  ...flowOptions.styles === void 0 ? {} : { styles: flowOptions.styles },
113
114
  ...flowOptions.theme === void 0 ? {} : { theme: flowOptions.theme },
package/dist/index.d.ts CHANGED
@@ -38,9 +38,11 @@ import { ImageMeta, ImageRef, MarkdownOptions, MarkdownResult } from "./markdown
38
38
  import { fromMarkdown } from "./markdown/fromMarkdown.js";
39
39
  import { toMarkdown, toMarkdownResult } from "./markdown/index.js";
40
40
  import { EmbeddedFont, EmbeddedFontParts, buildEmbeddedFontFamilyMap, extractEmbeddedFonts, getEmbeddedFontFaces, scopeEmbeddedFontFamily } from "./fonts/embeddedFonts.js";
41
- import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled } from "./utils/fontResolver.js";
41
+ import { getGoogleFontsEnabled, setGoogleFontsEnabled } from "./utils/fontResolver.js";
42
42
  import { FOLIO_YJS_ATTR_SCHEMA_VERSION, FolioYjsAttrSchemaVersion, FolioYjsAttrSchemaVersionError } from "./prosemirror/yjsDocumentMetadata.js";
43
+ import { EditorReadOnlyReason } from "./managers/EditorModeManager.js";
44
+ import { ReviewDisplayMode } from "./managers/reviewDisplayMode.js";
43
45
  import { DOCX_CONFORMANCE_CLASSES } from "@stll/docx-core/model";
44
46
  type Document = document_d_exports.Document;
45
47
  type DocxConformanceClass = document_d_exports.DocxConformanceClass;
46
- 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_REVISION_FORMATS, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, type CompareChange, type CompareChangeLocation, type CompareCompatibility, type CompareContentOptions, CompareDocxApplyError, type CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, type CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, type CompareFolioRequirement, type CompareResult, type CompareRevisionFormat, type CompareUnsupportedPart, type CompareUnsupportedReason, type CompareVerification, type CompareVerificationCause, type CompareVerificationFailure, type CompareVerificationInvariant, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DEFAULT_OUTLINE_DEPTH, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, DRAWING_SAFETY_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentPropertiesOptions, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type DocxDrawingClassification, type DrawingSafetyClass, 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, FOLIO_YJS_ATTR_SCHEMA_VERSION, type FinalParagraphMarkRevision, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIBlockStructuralBoundary, type FolioAIBlockTableLocation, type FolioAIComment, type FolioAIDiagnosticBlock, 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 FolioAIParagraphBlock, 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 FolioContentInlineComparisonResult, type FolioContentInlineFormatting, type FolioContentInlineFormattingPatch, FolioContentInlinePresentationProjectionError, type FolioContentLineSpacingRule, type FolioContentParagraphAlignment, type FolioContentParagraphFormattingPatch, type FolioContentParagraphKind, type FolioContentParagraphSpacing, type FolioContentRun, type FolioContentSnapshot, type FolioContentStatedNumbering, 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 FolioUndefinedReferencePolicy, type FolioWordDiffOptions, type FolioYjsAttrSchemaVersion, FolioYjsAttrSchemaVersionError, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidCompareDocxOptionsError, InvalidFolioContentComparisonError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, type MarkdownOptions, type MarkdownResult, type OutlineDepth, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewHiddenRange, 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, filterHeadingsByDepth, 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 };
48
+ 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_REVISION_FORMATS, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, type CompareChange, type CompareChangeLocation, type CompareCompatibility, type CompareContentOptions, CompareDocxApplyError, type CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, type CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, type CompareFolioRequirement, type CompareResult, type CompareRevisionFormat, type CompareUnsupportedPart, type CompareUnsupportedReason, type CompareVerification, type CompareVerificationCause, type CompareVerificationFailure, type CompareVerificationInvariant, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DEFAULT_OUTLINE_DEPTH, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, DRAWING_SAFETY_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentPropertiesOptions, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type DocxDrawingClassification, type DrawingSafetyClass, type EditorReadOnlyReason, 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, FOLIO_YJS_ATTR_SCHEMA_VERSION, type FinalParagraphMarkRevision, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIBlockStructuralBoundary, type FolioAIBlockTableLocation, type FolioAIComment, type FolioAIDiagnosticBlock, 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 FolioAIParagraphBlock, 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 FolioContentInlineComparisonResult, type FolioContentInlineFormatting, type FolioContentInlineFormattingPatch, FolioContentInlinePresentationProjectionError, type FolioContentLineSpacingRule, type FolioContentParagraphAlignment, type FolioContentParagraphFormattingPatch, type FolioContentParagraphKind, type FolioContentParagraphSpacing, type FolioContentRun, type FolioContentSnapshot, type FolioContentStatedNumbering, 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 FolioUndefinedReferencePolicy, type FolioWordDiffOptions, type FolioYjsAttrSchemaVersion, FolioYjsAttrSchemaVersionError, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidCompareDocxOptionsError, InvalidFolioContentComparisonError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, type MarkdownOptions, type MarkdownResult, type OutlineDepth, type PositionalText, type ResolvedAnchor, type ReviewDisplayMode, STELLA_STYLE_SET_NAME, type TemplatePreviewHiddenRange, 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, filterHeadingsByDepth, 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, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
package/dist/index.js CHANGED
@@ -31,8 +31,8 @@ import { STELLA_STYLE_SET_NAME, createStellaStyleDocumentPreset, createStellaSty
31
31
  import { DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION } from "./style-sets/types.js";
32
32
  import { currentFolioBlockId, deriveBlockId, getFolioParaIdFromBlockId, isFolioBlockId, isSequentialFolioBlockId } from "./types/block-id.js";
33
33
  import { createEmptyDocument } from "./utils/createDocument.js";
34
- import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled } from "./utils/fontResolver.js";
34
+ import { getGoogleFontsEnabled, setGoogleFontsEnabled } from "./utils/fontResolver.js";
35
35
  import { mergeDocumentContent } from "./utils/mergeDocumentContent.js";
36
36
  import { DEFAULT_OUTLINE_DEPTH, filterHeadingsByDepth } from "./utils/outlineDepth.js";
37
37
  import { DOCX_CONFORMANCE_CLASSES } from "@stll/docx-core/model";
38
- export { COMPARE_REVISION_FORMATS, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareDocxApplyError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DEFAULT_OUTLINE_DEPTH, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, DRAWING_SAFETY_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, FOLIO_YJS_ATTR_SCHEMA_VERSION, FolioContentComparisonLimitError, FolioContentInlinePresentationProjectionError, FolioYjsAttrSchemaVersionError, 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, filterHeadingsByDepth, 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 };
38
+ export { COMPARE_REVISION_FORMATS, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareDocxApplyError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DEFAULT_OUTLINE_DEPTH, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, DRAWING_SAFETY_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, FOLIO_YJS_ATTR_SCHEMA_VERSION, FolioContentComparisonLimitError, FolioContentInlinePresentationProjectionError, FolioYjsAttrSchemaVersionError, 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, filterHeadingsByDepth, 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, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
@@ -8,13 +8,14 @@ type RevisionRange = {
8
8
  to: number;
9
9
  };
10
10
  type ResolveInlineRevisionsOptions = {
11
+ pointComments: Set<number>;
11
12
  doc: Node;
12
13
  mode: RevisionResolutionMode;
13
14
  keepType: MarkType | undefined;
14
15
  removeType: MarkType | undefined;
15
16
  styleResolver: RunStyleResolver | null;
16
17
  };
17
- declare const resolveInlineRevisions: ({ doc, mode, keepType, removeType, styleResolver }: ResolveInlineRevisionsOptions) => {
18
+ declare const resolveInlineRevisions: ({ pointComments, doc, mode, keepType, removeType, styleResolver }: ResolveInlineRevisionsOptions) => {
18
19
  resolved: Node;
19
20
  positionMap: StepMap;
20
21
  ranges: RevisionRange[];
@@ -6,6 +6,7 @@ import "../prosemirror/extensions/nodes/SdtExtension.js";
6
6
  import { canonicalFieldNode } from "../prosemirror/fieldRepresentation.js";
7
7
  import { resolvedPreservedXmlAttrs } from "../prosemirror/preservedXmlReview.js";
8
8
  import { continuedRunMarks } from "../prosemirror/rejoinRunCarriers.js";
9
+ import { commentPoint } from "../prosemirror/replacedAnnotations.js";
9
10
  import { RUN_FORMATTING_MARK_NAMES } from "../prosemirror/runFormattingMarkNames.js";
10
11
  import { reconstructRejectedRunFormattingMarks, restoreHistoricalRunFormatting } from "../prosemirror/runPropertyChangeResolution.js";
11
12
  import { paragraphRunStyleContext } from "../prosemirror/runStyleFormatting.js";
@@ -158,6 +159,25 @@ const resolveInlineContent = ({ node, position, context, inheritedParagraphScope
158
159
  contentChanged = true;
159
160
  resolvedBoundaries.add(children.length);
160
161
  }
162
+ if (resolved === null && child.isInline) {
163
+ const anchors = [];
164
+ for (const mark of child.marks) {
165
+ const id = mark.attrs["commentId"];
166
+ if (mark.type.name !== "comment" || !context.pointComments.delete(id)) continue;
167
+ anchors.push(commentPoint(child.type.schema, id));
168
+ }
169
+ if (anchors.length > 0) {
170
+ const fragment = Fragment.fromArray(anchors);
171
+ const range = context.replacementRanges.at(-1);
172
+ if (!range || range.from !== contentStart + offset) panic("Missing resolved inline range");
173
+ range.newSize = fragment.size;
174
+ range.slice = new Slice(fragment, 0, 0);
175
+ for (const anchor of anchors) {
176
+ children.push(anchor);
177
+ positions.push(contentStart + offset);
178
+ }
179
+ }
180
+ }
161
181
  if (resolved) {
162
182
  children.push(resolved);
163
183
  positions.push(contentStart + offset);
@@ -228,8 +248,9 @@ const coalesceReplacementRanges = (replacementRanges) => {
228
248
  }
229
249
  return coalesced;
230
250
  };
231
- const resolveInlineRevisions = ({ doc, mode, keepType, removeType, styleResolver }) => {
251
+ const resolveInlineRevisions = ({ pointComments, doc, mode, keepType, removeType, styleResolver }) => {
232
252
  const context = {
253
+ pointComments,
233
254
  mode,
234
255
  keepType,
235
256
  removeType,
@@ -6,6 +6,7 @@ import { resolveAllTableChanges } from "../prosemirror/commands/resolveAllTableC
6
6
  import { resolveAllNodePropertyChangeAttrs } from "../prosemirror/commands/resolveNodePropertyChangeAttrs.js";
7
7
  import { resolveParagraphChangeAttrs } from "../prosemirror/commands/resolveParagraphProperties.js";
8
8
  import { rebaseParagraphRunContent } from "../prosemirror/rebaseParagraphRuns.js";
9
+ import { createResolvedCommentPointCollector } from "../prosemirror/replacedAnnotations.js";
9
10
  import { expandRunFormattingCarrier } from "../prosemirror/runFormattingInlineCarriers.js";
10
11
  import { readAuthoredRunFormatting, reconcileRunFormattingMarks } from "../prosemirror/runFormattingReconciliation.js";
11
12
  import { paragraphRunStyleContext } from "../prosemirror/runStyleFormatting.js";
@@ -19,9 +20,14 @@ import { Fragment, Slice } from "prosemirror-model";
19
20
  import { Mapping, ReplaceStep, StepMap, Transform } from "prosemirror-transform";
20
21
  //#region src/internal/wholeStoryRevisionResolution.ts
21
22
  const resolveProperties = ({ doc, mode, styleResolver, numbering, steps, changedRanges }) => {
23
+ const collector = createResolvedCommentPointCollector({
24
+ removes: (node) => mode === "accept" && doc.type.schema.marks["deletion"]?.isInSet(node.marks) !== void 0,
25
+ retiresStructure: () => mode === "accept"
26
+ });
22
27
  let structural = false;
23
28
  let runsIntoTable = false;
24
- const walk = (node, position) => {
29
+ const walk = ({ node, position, eligibleComments = true, previous }) => {
30
+ const childComments = eligibleComments && collector.visit(node, position, previous);
25
31
  if (node.isText) return node;
26
32
  if (!runsIntoTable && !node.isTextblock) {
27
33
  for (let index = 0; index + 1 < node.childCount; index++) if (runsIntoFollowingTable(node.child(index), node.child(index + 1), mode)) {
@@ -80,9 +86,15 @@ const resolveProperties = ({ doc, mode, styleResolver, numbering, steps, changed
80
86
  }
81
87
  const children = [];
82
88
  let changed = false;
83
- const visitChild = (child, childPosition) => {
89
+ const visitChild = (child, childPosition, previousChild) => {
84
90
  const replacement = rebased.get(child) ?? child;
85
- if (rebased.size === 0) return walk(replacement, childPosition);
91
+ if (rebased.size === 0) return walk({
92
+ node: replacement,
93
+ position: childPosition,
94
+ eligibleComments: childComments,
95
+ ...previousChild ? { previous: previousChild } : {}
96
+ });
97
+ if (childComments) collector.visit(child, childPosition, previousChild);
86
98
  recordNodeResolution({
87
99
  before: child,
88
100
  after: replacement,
@@ -94,17 +106,21 @@ const resolveProperties = ({ doc, mode, styleResolver, numbering, steps, changed
94
106
  replacement.forEach((inner, offset) => nested.push(visitChild(inner, childPosition + 1 + offset)));
95
107
  return recreateProseNodeWithParagraphPropertySource(replacement, { content: nested });
96
108
  };
97
- resolved.forEach((child, offset) => {
98
- const result = visitChild(child, position + 1 + offset);
109
+ resolved.forEach((child, offset, index) => {
110
+ const result = visitChild(child, position + 1 + offset, index > 0 ? node.maybeChild(index - 1) ?? void 0 : void 0);
99
111
  children.push(result);
100
112
  changed ||= result !== child;
101
113
  });
102
114
  return changed ? recreateProseNodeWithParagraphPropertySource(resolved, { content: children }) : resolved;
103
115
  };
104
116
  return {
105
- resolved: walk(doc, -1),
117
+ resolved: walk({
118
+ node: doc,
119
+ position: -1
120
+ }),
106
121
  structural,
107
- runsIntoTable
122
+ runsIntoTable,
123
+ pointComments: new Set(collector.finish().keys())
108
124
  };
109
125
  };
110
126
  const structuralReplacementMap = ({ replacements, tables, bookmarkJoins, origin }) => {
@@ -536,6 +552,7 @@ const resolveStoryRevisions = ({ doc, mode, styleResolver, numbering }) => {
536
552
  });
537
553
  const properties = propertyResult.resolved;
538
554
  const inline = resolveInlineRevisions({
555
+ pointComments: propertyResult.pointComments,
539
556
  doc: properties,
540
557
  mode,
541
558
  styleResolver,
@@ -9,6 +9,10 @@ import { Node } from "prosemirror-model";
9
9
  * Options for the conversion.
10
10
  */
11
11
  type ToFlowBlocksOptions = {
12
+ /** Paint comment anchors and highlights; false leaves authored marks intact. */
13
+ showCommentHighlights?: boolean;
14
+ /** Embedded families owned by this editor, never ambient process state. */
15
+ embeddedFontFamilyMap?: ReadonlyMap<string, string>;
12
16
  /** Default font family. */
13
17
  defaultFont?: string;
14
18
  /** Default font size in points. */
@@ -1,10 +1,14 @@
1
1
  import { document_d_exports } from "../../types/document.js";
2
+ import { DisplayMode } from "../../managers/EditorModeManager.js";
2
3
  import { FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, FlowBlock, FootnoteContent, Measure, Page } from "../../layout-engine/types.js";
3
4
  import { ToFlowBlocksOptions } from "./flowConversionShared.js";
4
5
  import "./toFlowBlocks.js";
5
6
  //#region src/layout-bridge/convert/footnoteLayout.d.ts
6
7
  type MeasureBlocksFn = (blocks: FlowBlock[], contentWidth: number) => Measure[];
7
- type ConvertFootnoteOptions = {
8
+ type ConvertFootnoteOptions = Pick<ToFlowBlocksOptions, "embeddedFontFamilyMap"> & {
9
+ /** Whether comment highlights are painted. Defaults to true. */
10
+ showCommentHighlights?: boolean;
11
+ markupView?: DisplayMode;
8
12
  styles?: document_d_exports.StyleDefinitions | null;
9
13
  numbering?: document_d_exports.NumberingDefinitions;
10
14
  theme?: document_d_exports.Theme | null;
@@ -2,6 +2,8 @@ import { measureParagraph } from "../../layout-engine/measure/measureParagraph.j
2
2
  import { layoutTextBoxContent } from "../../layout-engine/measure/textBoxParagraphLayout.js";
3
3
  import { DEFAULT_TEXTBOX_MARGINS, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, isFloatingImageRun, resolveTableWidthPx } from "../../layout-engine/types.js";
4
4
  import { footnoteToProseDoc } from "../../prosemirror/conversion/toProseDoc.js";
5
+ import { projectStoryMarkupView } from "../../prosemirror/markupViewProjection.js";
6
+ import { remapMarkupViewBlocks } from "./markupViewFlow.js";
5
7
  import { collectNoteRefs } from "./noteReferences.js";
6
8
  import { toFlowBlocks } from "./toFlowBlocks.js";
7
9
  //#region src/layout-bridge/convert/footnoteLayout.ts
@@ -204,20 +206,29 @@ function convertNoteStoryToFlowBlocks(content, options, referenceMarkText) {
204
206
  if (options.theme !== void 0) proseOptions.theme = options.theme;
205
207
  if (options.numbering !== void 0) proseOptions.numbering = options.numbering;
206
208
  const pmDoc = footnoteToProseDoc(content, proseOptions);
207
- const flowOptions = {};
209
+ const flowOptions = { showCommentHighlights: options.showCommentHighlights !== false && options.markupView !== "no-markup" && options.markupView !== "original" };
208
210
  if (options.defaultSize !== void 0) flowOptions.defaultSize = options.defaultSize;
209
211
  if (options.styles) flowOptions.styles = options.styles;
210
212
  if (options.theme !== void 0) flowOptions.theme = options.theme;
213
+ if (options.embeddedFontFamilyMap !== void 0) flowOptions.embeddedFontFamilyMap = options.embeddedFontFamilyMap;
211
214
  if (options.fontAlternates !== void 0) flowOptions.fontAlternates = options.fontAlternates;
212
215
  if (options.defaultTabStopTwips !== void 0) flowOptions.defaultTabStopTwips = options.defaultTabStopTwips;
213
216
  if (options.lineBreakRules) flowOptions.lineBreakRules = options.lineBreakRules;
214
217
  if (options.justificationCompatibility) flowOptions.justificationCompatibility = options.justificationCompatibility;
215
218
  if (options.tableIndentCompatibility) flowOptions.tableIndentCompatibility = options.tableIndentCompatibility;
216
219
  if (options.automaticHyphenation) flowOptions.automaticHyphenation = options.automaticHyphenation;
217
- const hasReferenceMark = containsNoteReferenceMark(pmDoc);
220
+ const projection = projectStoryMarkupView({
221
+ doc: pmDoc,
222
+ markupView: options.markupView ?? "all-markup",
223
+ styles: options.styles,
224
+ numbering: options.numbering
225
+ });
226
+ const viewDoc = projection.type === "resolved" ? projection.doc : pmDoc;
227
+ const hasReferenceMark = containsNoteReferenceMark(viewDoc);
218
228
  if (hasReferenceMark && referenceMarkText !== void 0) flowOptions.noteReferenceMarkText = referenceMarkText;
229
+ const converted = toFlowBlocks(viewDoc, flowOptions);
219
230
  return {
220
- flowBlocks: preserveAuthoredFootnoteTerminalParagraph(toFlowBlocks(pmDoc, flowOptions)),
231
+ flowBlocks: preserveAuthoredFootnoteTerminalParagraph(projection.type === "resolved" ? remapMarkupViewBlocks(converted, projection) : converted),
221
232
  hasReferenceMark
222
233
  };
223
234
  }
@@ -392,6 +403,8 @@ function createFootnoteNumberRun(displayNumber, paragraph) {
392
403
  fontSize: firstFormattedRun?.fontSize ?? paragraph.attrs?.defaultFontSize ?? FOOTNOTE_FONT_SIZE,
393
404
  superscript: true
394
405
  };
406
+ const embeddedFontFamilyMap = firstFormattedRun?.embeddedFontFamilyMap ?? paragraph.attrs?.embeddedFontFamilyMap;
407
+ if (embeddedFontFamilyMap) numberRun.embeddedFontFamilyMap = embeddedFontFamilyMap;
395
408
  const fontFamily = firstFormattedRun?.fontFamily ?? paragraph.attrs?.defaultFontFamily;
396
409
  if (fontFamily) numberRun.fontFamily = fontFamily;
397
410
  const alternateFontFamily = firstFormattedRun?.fontFamily !== void 0 ? firstFormattedRun.alternateFontFamily : paragraph.attrs?.defaultAlternateFontFamily;
@@ -1,4 +1,5 @@
1
1
  import { document_d_exports } from "../../types/document.js";
2
+ import { DisplayMode } from "../../managers/EditorModeManager.js";
2
3
  import { FlowBlock, HeaderFooterContent, ImageRun, ImageRunPosition, Measure, PageMargins } from "../../layout-engine/types.js";
3
4
  import { ToFlowBlocksOptions } from "./flowConversionShared.js";
4
5
  import "./toFlowBlocks.js";
@@ -40,11 +41,16 @@ declare function calculateHeaderFooterMarginPushBounds(blocks: FlowBlock[], meas
40
41
  */
41
42
  declare function calculateHeaderFooterBodyTopClearance(blocks: FlowBlock[], flowHeight: number, metrics: HeaderFooterMetrics): number | undefined;
42
43
  type ConvertHeaderFooterOptions = {
44
+ /** Review projection applied before header/footer measurement. Defaults to All Markup. */
45
+ markupView?: DisplayMode;
46
+ /** Whether comment highlights are painted. Defaults to true. */
47
+ showCommentHighlights?: boolean;
43
48
  styles?: document_d_exports.StyleDefinitions | null;
44
49
  numbering?: document_d_exports.NumberingDefinitions;
45
50
  theme?: document_d_exports.Theme | null;
46
51
  defaultSize?: number;
47
52
  fontAlternates?: ToFlowBlocksOptions["fontAlternates"];
53
+ embeddedFontFamilyMap?: ReadonlyMap<string, string>;
48
54
  measureBlocks: MeasureBlocksFn;
49
55
  /** Document-wide `w:defaultTabStop` in twips — forwarded to toFlowBlocks. */
50
56
  defaultTabStopTwips?: number;