@stll/folio-core 0.36.0 → 0.37.1
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.
- package/README.md +59 -1
- package/dist/ai-edits/apply.js +689 -367
- package/dist/ai-edits/block-identity.d.ts +4 -1
- package/dist/ai-edits/block-identity.js +4 -1
- package/dist/ai-edits/blockRange.js +14 -14
- package/dist/ai-edits/clean-text.d.ts +40 -1
- package/dist/ai-edits/clean-text.js +52 -2
- package/dist/ai-edits/headless.d.ts +3 -1
- package/dist/ai-edits/headless.js +133 -71
- package/dist/ai-edits/index.d.ts +3 -3
- package/dist/ai-edits/index.js +2 -2
- package/dist/ai-edits/read.js +38 -20
- package/dist/ai-edits/snapshot.d.ts +14 -6
- package/dist/ai-edits/snapshot.js +99 -19
- package/dist/ai-edits/table-cell-mutations.js +1 -1
- package/dist/ai-edits/table-row-column-mutations.js +7 -0
- package/dist/ai-edits/table-template.d.ts +11 -1
- package/dist/ai-edits/table-template.js +49 -17
- package/dist/ai-edits/types.d.ts +60 -57
- package/dist/ai-suggestions/conflict.js +1 -4
- package/dist/ai-suggestions/text-positions.d.ts +8 -0
- package/dist/ai-suggestions/text-positions.js +27 -5
- package/dist/compare/__fixtures__/body-sequence.js +3 -4
- package/dist/compare/column-alignment.d.ts +13 -13
- package/dist/compare/column-alignment.js +78 -39
- package/dist/compare/compare.d.ts +4 -3
- package/dist/compare/compare.js +41 -5
- package/dist/compare/content-alignment.d.ts +95 -0
- package/dist/compare/content-alignment.js +1450 -0
- package/dist/compare/content-types.d.ts +100 -0
- package/dist/compare/content-types.js +0 -0
- package/dist/compare/content.d.ts +209 -0
- package/dist/compare/content.js +885 -0
- package/dist/compare/formatting.d.ts +5 -5
- package/dist/compare/formatting.js +6 -4
- package/dist/compare/plan.d.ts +6 -1
- package/dist/compare/plan.js +201 -569
- package/dist/compare/scenario.d.ts +2 -2
- package/dist/compare/types.d.ts +3 -3
- package/dist/compare/verification.d.ts +2 -2
- package/dist/compare/verification.js +25 -8
- package/dist/compat/eigenpal.d.ts +5 -3
- package/dist/compat/eigenpal.js +3 -2
- package/dist/controller/headerFooterEditorManager.js +14 -6
- package/dist/controller/hiddenEditorManager.d.ts +7 -2
- package/dist/controller/hiddenEditorManager.js +15 -6
- package/dist/controller/layoutPipeline.js +5 -3
- package/dist/controller/noteEditorManager.js +12 -7
- package/dist/display-list/build/headerFooterPrimitives.js +1 -0
- package/dist/display-list/build/storyPrimitives.d.ts +5 -2
- package/dist/display-list/build/storyPrimitives.js +60 -3
- package/dist/display-list/build/tablePrimitives.js +30 -0
- package/dist/display-list/primitives.d.ts +1 -1
- package/dist/document-operations.d.ts +8 -6
- package/dist/document-operations.js +121 -26
- package/dist/docx/blockContentParser.js +6 -27
- package/dist/docx/ensureParaIds.js +9 -4
- package/dist/docx/numberingParser.d.ts +3 -1
- package/dist/docx/numberingParser.js +4 -1
- package/dist/docx/paragraphParser.js +7 -6
- package/dist/docx/paragraphTraversal.js +30 -34
- package/dist/docx/rezip.d.ts +0 -8
- package/dist/docx/rezip.js +41 -16
- package/dist/docx/runParser.js +4 -2
- package/dist/docx/serializer/paragraphSerializer.js +2 -0
- package/dist/docx/serializer/runSerializer.js +5 -3
- package/dist/docx/serializer/trackedChangeAttributes.d.ts +3 -1
- package/dist/docx/serializer/trackedChangeAttributes.js +11 -1
- package/dist/docx/server/build.d.ts +1 -1
- package/dist/headless-layout.js +5 -4
- package/dist/index.d.ts +5 -3
- package/dist/index.js +3 -2
- package/dist/internal/headlessRevisionResolution.d.ts +23 -0
- package/dist/internal/headlessRevisionResolution.js +176 -0
- package/dist/internal/headlessRevisionResolutionGuard.d.ts +12 -0
- package/dist/internal/headlessRevisionResolutionGuard.js +28 -0
- package/dist/internal/pageBreakRunDescendantIndex.d.ts +9 -0
- package/dist/internal/pageBreakRunDescendantIndex.js +27 -0
- package/dist/internal/pageBreakRunPartition.d.ts +26 -0
- package/dist/internal/pageBreakRunPartition.js +35 -0
- package/dist/internal/pageBreakRunSourceDescendantIndex.d.ts +15 -0
- package/dist/internal/pageBreakRunSourceDescendantIndex.js +126 -0
- package/dist/internal/sectionEndpointResolution.d.ts +32 -0
- package/dist/internal/sectionEndpointResolution.js +38 -0
- package/dist/layout-bridge/convert/footnoteLayout.js +1 -0
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +16 -4
- package/dist/layout-bridge/convert/headerFooterLayout.js +48 -5
- package/dist/layout-bridge/convert/toFlowBlocks.d.ts +4 -0
- package/dist/layout-bridge/convert/toFlowBlocks.js +379 -75
- package/dist/layout-bridge/dom/clickToPositionDom.d.ts +8 -1
- package/dist/layout-bridge/dom/clickToPositionDom.js +114 -40
- package/dist/layout-bridge/dom/textStreamDom.d.ts +24 -0
- package/dist/layout-bridge/dom/textStreamDom.js +75 -0
- package/dist/layout-bridge/headerFooterLayout.js +16 -30
- package/dist/layout-engine/index.js +12 -3
- package/dist/layout-engine/measure/tableFragmentBorderGeometry.d.ts +17 -0
- package/dist/layout-engine/measure/tableFragmentBorderGeometry.js +24 -0
- package/dist/layout-engine/renderedBreakReconciliation.js +1 -1
- package/dist/layout-engine/types.d.ts +7 -0
- package/dist/layout-painter/imageLayout.d.ts +1 -1
- package/dist/layout-painter/renderTable.js +20 -0
- package/dist/model.d.ts +1 -1
- package/dist/paged-layout/rangeProjection.js +6 -9
- package/dist/paged-layout/transactionDirtyRange.d.ts +3 -1
- package/dist/paged-layout/transactionDirtyRange.js +23 -1
- package/dist/prosemirror/attrs/index.d.ts +7 -3
- package/dist/prosemirror/attrs/index.js +113 -7
- package/dist/prosemirror/bookmarkBoundaryIntegrity.d.ts +9 -0
- package/dist/prosemirror/bookmarkBoundaryIntegrity.js +22 -0
- package/dist/prosemirror/commands/comments.d.ts +10 -1
- package/dist/prosemirror/commands/comments.js +167 -59
- package/dist/prosemirror/commands/formatPainter.d.ts +45 -10
- package/dist/prosemirror/commands/formatPainter.js +319 -63
- package/dist/prosemirror/commands/index.d.ts +2 -2
- package/dist/prosemirror/commands/pageBreak.d.ts +5 -2
- package/dist/prosemirror/commands/pageBreak.js +18 -36
- package/dist/prosemirror/commands/propertyChangeScope.d.ts +7 -5
- package/dist/prosemirror/commands/propertyChangeScope.js +27 -18
- package/dist/prosemirror/conversion/fromProseDoc.d.ts +7 -2
- package/dist/prosemirror/conversion/fromProseDoc.js +809 -209
- package/dist/prosemirror/conversion/runShadingMark.js +2 -2
- package/dist/prosemirror/conversion/toProseDoc.d.ts +26 -1
- package/dist/prosemirror/conversion/toProseDoc.js +416 -283
- package/dist/prosemirror/extensions/StarterKit.js +4 -0
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +12 -8
- package/dist/prosemirror/extensions/features/ListExtension.js +95 -123
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +1 -1
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +27 -1
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +134 -30
- package/dist/prosemirror/extensions/features/pasteCleanup.js +9 -15
- package/dist/prosemirror/extensions/marks/BoldExtension.js +4 -3
- package/dist/prosemirror/extensions/marks/CharacterStyleExtension.d.ts +4 -7
- package/dist/prosemirror/extensions/marks/CharacterStyleExtension.js +5 -11
- package/dist/prosemirror/extensions/marks/FontSizeExtension.js +3 -3
- package/dist/prosemirror/extensions/marks/ItalicExtension.js +4 -3
- package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.d.ts +13 -0
- package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.js +39 -0
- package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.d.ts +7 -1
- package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.js +67 -21
- package/dist/prosemirror/extensions/marks/markUtils.d.ts +8 -1
- package/dist/prosemirror/extensions/marks/markUtils.js +88 -2
- package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.js +44 -3
- package/dist/prosemirror/extensions/nodes/FieldExtension.js +1 -1
- package/dist/prosemirror/extensions/nodes/HardBreakExtension.js +15 -4
- package/dist/prosemirror/extensions/nodes/PageBreakExtension.d.ts +6 -0
- package/dist/prosemirror/extensions/nodes/PageBreakExtension.js +6 -0
- package/dist/prosemirror/extensions/nodes/PageBreakRunExtension.d.ts +6 -0
- package/dist/prosemirror/extensions/nodes/PageBreakRunExtension.js +36 -0
- package/dist/prosemirror/findReplaceSelection.js +8 -3
- package/dist/prosemirror/index.d.ts +3 -3
- package/dist/prosemirror/listMarker.d.ts +26 -1
- package/dist/prosemirror/listMarker.js +108 -14
- package/dist/prosemirror/pageBreakRunProjection.d.ts +28 -0
- package/dist/prosemirror/pageBreakRunProjection.js +47 -0
- package/dist/prosemirror/paraText.js +6 -0
- package/dist/prosemirror/paragraphSpacing.d.ts +29 -0
- package/dist/prosemirror/paragraphSpacing.js +125 -0
- package/dist/prosemirror/plugins/documentNumbering.d.ts +8 -0
- package/dist/prosemirror/plugins/documentNumbering.js +18 -0
- package/dist/prosemirror/plugins/pmTextScan.d.ts +3 -2
- package/dist/prosemirror/plugins/pmTextScan.js +14 -4
- package/dist/prosemirror/plugins/suggestionMode.js +8 -10
- package/dist/prosemirror/rebaseParagraphRunFormatting.d.ts +16 -0
- package/dist/prosemirror/rebaseParagraphRunFormatting.js +61 -0
- package/dist/prosemirror/runFormattingInlineCarriers.d.ts +64 -0
- package/dist/prosemirror/runFormattingInlineCarriers.js +121 -0
- package/dist/prosemirror/runFormattingProvenance.d.ts +12 -0
- package/dist/prosemirror/runFormattingProvenance.js +48 -0
- package/dist/prosemirror/runFormattingReconciliation.d.ts +25 -0
- package/dist/prosemirror/runFormattingReconciliation.js +54 -0
- package/dist/prosemirror/runPropertyChangeResolution.d.ts +18 -0
- package/dist/prosemirror/runPropertyChangeResolution.js +18 -0
- package/dist/prosemirror/runStyleFormatting.d.ts +50 -0
- package/dist/prosemirror/runStyleFormatting.js +105 -0
- package/dist/prosemirror/schema/index.d.ts +3 -3
- package/dist/prosemirror/schema/marks.d.ts +82 -9
- package/dist/prosemirror/schema/marks.js +73 -1
- package/dist/prosemirror/schema/nodes.d.ts +18 -5
- package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +14 -2
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +44 -23
- package/dist/prosemirror/styles/styleResolver.d.ts +10 -13
- package/dist/prosemirror/styles/styleResolver.js +3 -3
- package/dist/prosemirror/styles/styleToggleCascade.d.ts +8 -1
- package/dist/prosemirror/styles/styleToggleCascade.js +24 -1
- package/dist/prosemirror/tableGridMutation.d.ts +20 -0
- package/dist/prosemirror/tableGridMutation.js +30 -0
- package/dist/prosemirror/trackedRunInlineAtoms.d.ts +31 -0
- package/dist/prosemirror/trackedRunInlineAtoms.js +39 -0
- package/dist/prosemirror/utils/visualLineNavigation.js +27 -31
- package/dist/prosemirror/validation.js +23 -4
- package/dist/render-dom/HeaderFooterSelectionOverlay.js +20 -20
- package/dist/render-dom/RenderedDomContext.js +17 -34
- package/dist/server.d.ts +4 -4
- package/dist/server.js +2 -2
- package/dist/style-engine/styleEngine.d.ts +1 -1
- package/dist/utils/clipboard.js +1 -1
- package/dist/utils/findReplace.js +38 -21
- package/dist/version-comparison.d.ts +38 -44
- package/dist/version-comparison.js +270 -401
- package/package.json +3 -2
package/dist/docx/rezip.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { consumeTrackedSectionEndpointRemoval } from "../internal/sectionEndpointResolution.js";
|
|
1
2
|
import { isAllowedExternalWatermarkImageUrl } from "../watermark/index.js";
|
|
2
3
|
import { normalizeAppVersionInExtendedProperties } from "./appVersionNormalization.js";
|
|
3
4
|
import { withoutOrphanCommentRanges } from "./commentRangeIntegrity.js";
|
|
@@ -115,11 +116,34 @@ const extractHeaderFooterReferences = (xml) => {
|
|
|
115
116
|
const hasParsedHeaderFooterPart = (doc, ref) => {
|
|
116
117
|
return (ref.element === "headerReference" ? doc.package.headers : doc.package.footers)?.has(ref.rId) ?? false;
|
|
117
118
|
};
|
|
118
|
-
|
|
119
|
+
const headerFooterReferenceKey = ({ element, type, rId }) => `${element}:${type}:${rId}`;
|
|
120
|
+
const incrementReferenceCount = (counts, key) => {
|
|
121
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
122
|
+
};
|
|
123
|
+
const consumeReferenceCount = (counts, key) => {
|
|
124
|
+
const count = counts.get(key) ?? 0;
|
|
125
|
+
if (count === 0) return false;
|
|
126
|
+
counts.set(key, count - 1);
|
|
127
|
+
return true;
|
|
128
|
+
};
|
|
129
|
+
function assertDocumentPackageFidelity(originalDocumentXml, serializedDocumentXml, doc, sectionEndpointRemoval) {
|
|
119
130
|
const originalSectionCount = countDocumentSections(originalDocumentXml);
|
|
120
|
-
|
|
121
|
-
const
|
|
122
|
-
|
|
131
|
+
const serializedSectionCount = countDocumentSections(serializedDocumentXml);
|
|
132
|
+
const trackedRemovedSectionCount = sectionEndpointRemoval ? sectionEndpointRemoval.sourceParagraphEndpointCount - sectionEndpointRemoval.expectedParagraphEndpointCount : 0;
|
|
133
|
+
const exactTrackedSectionRemoval = trackedRemovedSectionCount > 0 && originalSectionCount - trackedRemovedSectionCount === serializedSectionCount && serializedSectionCount < originalSectionCount;
|
|
134
|
+
if (serializedSectionCount < originalSectionCount && !exactTrackedSectionRemoval) throw new DocxPackageFidelityError("Full DOCX repack would drop section properties. Use selective patching instead.");
|
|
135
|
+
const serializedReferenceCounts = /* @__PURE__ */ new Map();
|
|
136
|
+
for (const reference of extractHeaderFooterReferences(serializedDocumentXml)) incrementReferenceCount(serializedReferenceCounts, headerFooterReferenceKey(reference));
|
|
137
|
+
const removedReferenceCounts = /* @__PURE__ */ new Map();
|
|
138
|
+
if (exactTrackedSectionRemoval && sectionEndpointRemoval) for (const { part, type, relationshipId } of sectionEndpointRemoval.removedReferences) incrementReferenceCount(removedReferenceCounts, `${part}Reference:${type}:${relationshipId}`);
|
|
139
|
+
const missingRefs = [];
|
|
140
|
+
for (const reference of extractHeaderFooterReferences(originalDocumentXml)) {
|
|
141
|
+
if (!hasParsedHeaderFooterPart(doc, reference)) continue;
|
|
142
|
+
const key = headerFooterReferenceKey(reference);
|
|
143
|
+
if (consumeReferenceCount(serializedReferenceCounts, key) || consumeReferenceCount(removedReferenceCounts, key)) continue;
|
|
144
|
+
missingRefs.push(reference);
|
|
145
|
+
}
|
|
146
|
+
if (missingRefs.length > 0) throw new DocxPackageFidelityError("Full DOCX repack would drop header/footer references. Use selective patching instead.");
|
|
123
147
|
}
|
|
124
148
|
async function serializeCommentsToZip(doc, zip, compressionLevel) {
|
|
125
149
|
const comments = doc.package.document.comments ?? [];
|
|
@@ -488,7 +512,7 @@ const cloneDocxZip = (source) => {
|
|
|
488
512
|
clone.files = { ...source.files };
|
|
489
513
|
return clone;
|
|
490
514
|
};
|
|
491
|
-
const finishRepack = async ({ document, originalZip, outputZip, originalDocumentXml, originalCorePropertiesXml, compressionLevel, updateModifiedDate, modifiedBy, changedNoteParaIds }) => {
|
|
515
|
+
const finishRepack = async ({ document, originalZip, outputZip, originalDocumentXml, originalCorePropertiesXml, compressionLevel, updateModifiedDate, modifiedBy, changedNoteParaIds, sectionEndpointRemoval }) => {
|
|
492
516
|
await materializeNewHeaderFooterParts(document, outputZip, compressionLevel);
|
|
493
517
|
const parts = collectDocxParts(document, outputZip);
|
|
494
518
|
await processNewImages(parts, outputZip, compressionLevel);
|
|
@@ -496,7 +520,7 @@ const finishRepack = async ({ document, originalZip, outputZip, originalDocument
|
|
|
496
520
|
assertValidFolioDocumentModel(document, "Cannot repack invalid DOCX document model");
|
|
497
521
|
applyReplyThreadMarkers(document);
|
|
498
522
|
const documentXml = serializeDocument(document, originalDocumentXml === void 0 ? void 0 : readRootNamespaceBindings(originalDocumentXml));
|
|
499
|
-
if (originalDocumentXml) assertDocumentPackageFidelity(originalDocumentXml, documentXml, document);
|
|
523
|
+
if (originalDocumentXml) assertDocumentPackageFidelity(originalDocumentXml, documentXml, document, sectionEndpointRemoval);
|
|
500
524
|
outputZip.file("word/document.xml", documentXml, {
|
|
501
525
|
compression: "DEFLATE",
|
|
502
526
|
compressionOptions: { level: compressionLevel }
|
|
@@ -526,15 +550,7 @@ const finishRepack = async ({ document, originalZip, outputZip, originalDocument
|
|
|
526
550
|
}
|
|
527
551
|
return generateDocxZip(outputZip, compressionLevel);
|
|
528
552
|
};
|
|
529
|
-
|
|
530
|
-
* Repack a Document into a valid DOCX file
|
|
531
|
-
*
|
|
532
|
-
* @param doc - Document with modified content
|
|
533
|
-
* @param options - Optional repack options
|
|
534
|
-
* @returns Promise resolving to DOCX as ArrayBuffer
|
|
535
|
-
* @throws {Error} if document has no original buffer for round-trip
|
|
536
|
-
*/
|
|
537
|
-
async function repackDocx(doc, options = {}) {
|
|
553
|
+
async function repackDocxWithSectionEndpointRemoval({ document: doc, options, sectionEndpointRemoval }) {
|
|
538
554
|
if (!doc.originalBuffer) panic("Cannot repack document: no original buffer for round-trip. Use createDocx() for new documents.");
|
|
539
555
|
const { compressionLevel = 6, updateModifiedDate = true, modifiedBy, changedNoteParaIds } = options;
|
|
540
556
|
const exportDocument = withoutOrphanCommentRanges(doc);
|
|
@@ -551,7 +567,16 @@ async function repackDocx(doc, options = {}) {
|
|
|
551
567
|
compressionLevel,
|
|
552
568
|
updateModifiedDate,
|
|
553
569
|
...modifiedBy !== void 0 ? { modifiedBy } : {},
|
|
554
|
-
...changedNoteParaIds !== void 0 ? { changedNoteParaIds } : {}
|
|
570
|
+
...changedNoteParaIds !== void 0 ? { changedNoteParaIds } : {},
|
|
571
|
+
...sectionEndpointRemoval !== void 0 ? { sectionEndpointRemoval } : {}
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
function repackDocx(doc, options = {}) {
|
|
575
|
+
const sectionEndpointRemoval = consumeTrackedSectionEndpointRemoval(doc);
|
|
576
|
+
return repackDocxWithSectionEndpointRemoval({
|
|
577
|
+
document: doc,
|
|
578
|
+
options,
|
|
579
|
+
...sectionEndpointRemoval ? { sectionEndpointRemoval } : {}
|
|
555
580
|
});
|
|
556
581
|
}
|
|
557
582
|
/**
|
package/dist/docx/runParser.js
CHANGED
|
@@ -41,9 +41,11 @@ function parseShadingProperties(shd) {
|
|
|
41
41
|
if (!shd) return;
|
|
42
42
|
const props = {};
|
|
43
43
|
const color = getAttribute(shd, "w", "color");
|
|
44
|
-
if (color
|
|
44
|
+
if (color === "auto") props.color = { auto: true };
|
|
45
|
+
else if (color && isValidHexColor(color)) props.color = { rgb: color };
|
|
45
46
|
const fill = getAttribute(shd, "w", "fill");
|
|
46
|
-
if (fill
|
|
47
|
+
if (fill === "auto") props.fill = { auto: true };
|
|
48
|
+
else if (fill && isValidHexColor(fill)) props.fill = { rgb: fill };
|
|
47
49
|
const validatedThemeFill = narrowEnum(getAttribute(shd, "w", "themeFill"), ThemeColorSlotSchema);
|
|
48
50
|
if (validatedThemeFill) {
|
|
49
51
|
if (!props.fill) props.fill = {};
|
|
@@ -398,6 +398,8 @@ const withParagraphMarkChange = (sourceXml, mark) => {
|
|
|
398
398
|
return captureVerbatimXml(cloneElement(root, { elements }));
|
|
399
399
|
};
|
|
400
400
|
const serializeParagraphFormattingWithOptions = (formatting, { propertyChanges, paragraphMarkChange, propertySource, sectionProperties } = {}) => {
|
|
401
|
+
const serializablePropertyChangeCount = propertyChanges?.length ?? 0;
|
|
402
|
+
if (serializablePropertyChangeCount > 1) panic("A paragraph cannot serialize more than one w:pPrChange", { count: serializablePropertyChangeCount });
|
|
401
403
|
const paragraphMarkXml = paragraphMarkChange ? serializeParagraphMarkChange(paragraphMarkChange) : "";
|
|
402
404
|
const sectionPropertiesXml = serializeSectionProperties(sectionProperties);
|
|
403
405
|
const propertyChangesXml = (propertyChanges ?? []).map((change) => serializeParagraphPropertyChange(change));
|
|
@@ -5,7 +5,7 @@ import { THEME_COLOR_TO_DRAWING_SCHEME } from "../drawingUtils.js";
|
|
|
5
5
|
import { requiresXmlSpacePreserve } from "../textWhitespace.js";
|
|
6
6
|
import { serializeParagraph } from "./paragraphSerializer.js";
|
|
7
7
|
import { serializeTable } from "./tableSerializer.js";
|
|
8
|
-
import { serializeTrackedChangeAttributes } from "./trackedChangeAttributes.js";
|
|
8
|
+
import { getSingularRunPropertyChange, serializeTrackedChangeAttributes } from "./trackedChangeAttributes.js";
|
|
9
9
|
import { escapeXml, intAttr } from "./xmlUtils.js";
|
|
10
10
|
import { panic } from "better-result";
|
|
11
11
|
//#region src/docx/serializer/runSerializer.ts
|
|
@@ -145,7 +145,7 @@ function serializeTextFormatting(formatting) {
|
|
|
145
145
|
}
|
|
146
146
|
parts.push(`<w:u ${uAttrs.join(" ")}/>`);
|
|
147
147
|
}
|
|
148
|
-
if (formatting.effect
|
|
148
|
+
if (formatting.effect) parts.push(`<w:effect w:val="${formatting.effect}"/>`);
|
|
149
149
|
const shadingXml = serializeShading(formatting.shading) || customHighlightShadingXml;
|
|
150
150
|
if (shadingXml) parts.push(shadingXml);
|
|
151
151
|
if (formatting.vertAlign) parts.push(`<w:vertAlign w:val="${formatting.vertAlign}"/>`);
|
|
@@ -174,7 +174,9 @@ function serializeRunPropertyChange(change) {
|
|
|
174
174
|
}
|
|
175
175
|
function serializeRunProperties(formatting, propertyChanges) {
|
|
176
176
|
const currentRPrXml = serializeTextFormatting(formatting);
|
|
177
|
-
const
|
|
177
|
+
const currentInner = currentRPrXml ? extractRPrInner(currentRPrXml) : "";
|
|
178
|
+
const propertyChange = getSingularRunPropertyChange(propertyChanges);
|
|
179
|
+
const combined = `${currentInner}${propertyChange ? serializeRunPropertyChange(propertyChange) : ""}`;
|
|
178
180
|
if (!combined) return "";
|
|
179
181
|
return `<w:rPr>${combined}</w:rPr>`;
|
|
180
182
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { document_d_exports } from "../../types/document.js";
|
|
2
2
|
//#region src/docx/serializer/trackedChangeAttributes.d.ts
|
|
3
3
|
type SerializableTrackedChangeInfo = document_d_exports.TrackedChangeInfo | document_d_exports.PropertyChangeInfo;
|
|
4
|
+
/** Enforces the singular `w:rPrChange` child in a run-property container. */
|
|
5
|
+
declare const getSingularRunPropertyChange: (propertyChanges: readonly document_d_exports.RunPropertyChange[] | undefined) => document_d_exports.RunPropertyChange | undefined;
|
|
4
6
|
/** Normalized, unescaped attributes in schema order for an XML element or string serializer. */
|
|
5
7
|
declare const trackedChangeAttributeEntries: (info: SerializableTrackedChangeInfo) => readonly (readonly [string, string])[];
|
|
6
8
|
declare const trackedChangeAttributeRecord: (info: SerializableTrackedChangeInfo) => Record<string, string>;
|
|
7
9
|
declare const serializeTrackedChangeAttributes: (info: SerializableTrackedChangeInfo) => string;
|
|
8
10
|
//#endregion
|
|
9
|
-
export { serializeTrackedChangeAttributes, trackedChangeAttributeEntries, trackedChangeAttributeRecord };
|
|
11
|
+
export { getSingularRunPropertyChange, serializeTrackedChangeAttributes, trackedChangeAttributeEntries, trackedChangeAttributeRecord };
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
import { DATE_UTC_ATTRIBUTE } from "../trackedChangeInfo.js";
|
|
2
2
|
import { escapeXml } from "./xmlUtils.js";
|
|
3
|
+
import { panic } from "better-result";
|
|
3
4
|
import { normalizeRevisionId } from "@stll/docx-core/model";
|
|
4
5
|
//#region src/docx/serializer/trackedChangeAttributes.ts
|
|
6
|
+
/** Enforces the singular `w:rPrChange` child in a run-property container. */
|
|
7
|
+
const getSingularRunPropertyChange = (propertyChanges) => {
|
|
8
|
+
const propertyChangeCount = propertyChanges?.length ?? 0;
|
|
9
|
+
if (propertyChangeCount > 1) panic("A run-property container cannot serialize more than one w:rPrChange", {
|
|
10
|
+
elementName: "w:rPrChange",
|
|
11
|
+
propertyChangeCount
|
|
12
|
+
});
|
|
13
|
+
return propertyChanges?.at(0);
|
|
14
|
+
};
|
|
5
15
|
/** Normalized, unescaped attributes in schema order for an XML element or string serializer. */
|
|
6
16
|
const trackedChangeAttributeEntries = (info) => {
|
|
7
17
|
const author = typeof info.author === "string" ? info.author.trim() : "";
|
|
@@ -18,4 +28,4 @@ const trackedChangeAttributeEntries = (info) => {
|
|
|
18
28
|
const trackedChangeAttributeRecord = (info) => Object.fromEntries(trackedChangeAttributeEntries(info));
|
|
19
29
|
const serializeTrackedChangeAttributes = (info) => trackedChangeAttributeEntries(info).map(([name, value]) => `${name}="${escapeXml(value)}"`).join(" ");
|
|
20
30
|
//#endregion
|
|
21
|
-
export { serializeTrackedChangeAttributes, trackedChangeAttributeEntries, trackedChangeAttributeRecord };
|
|
31
|
+
export { getSingularRunPropertyChange, serializeTrackedChangeAttributes, trackedChangeAttributeEntries, trackedChangeAttributeRecord };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ShadingProperties } from "../../types/colors.js";
|
|
2
2
|
import { document_d_exports } from "../../types/document.js";
|
|
3
|
-
import { Hyperlink, Paragraph, ParagraphContent, Run, Table } from "../../types/content.js";
|
|
4
3
|
import { ParagraphFormatting, TextFormatting } from "../../types/formatting.js";
|
|
4
|
+
import { Hyperlink, Paragraph, ParagraphContent, Run, Table } from "../../types/content.js";
|
|
5
5
|
//#region src/docx/server/build.d.ts
|
|
6
6
|
declare const HEADING_LEVELS: readonly [1, 2, 3, 4, 5, 6];
|
|
7
7
|
type HeadingLevel = (typeof HEADING_LEVELS)[number];
|
package/dist/headless-layout.js
CHANGED
|
@@ -88,7 +88,8 @@ const buildFlowOptions = (document, pageContentHeight) => {
|
|
|
88
88
|
const settings = document.package.settings;
|
|
89
89
|
const options = {
|
|
90
90
|
pageContentHeight,
|
|
91
|
-
fontAlternates: buildFontAlternates(document.package.fontTable)
|
|
91
|
+
fontAlternates: buildFontAlternates(document.package.fontTable),
|
|
92
|
+
...document.package.styles ? { styles: document.package.styles } : {}
|
|
92
93
|
};
|
|
93
94
|
const theme = document.package.theme;
|
|
94
95
|
if (theme) options.theme = theme;
|
|
@@ -118,8 +119,8 @@ const buildBlockLookup = (blocks, measures) => new Map(blocks.flatMap((block, in
|
|
|
118
119
|
measure
|
|
119
120
|
}]];
|
|
120
121
|
}));
|
|
121
|
-
const buildStoryOptions = (
|
|
122
|
-
...
|
|
122
|
+
const buildStoryOptions = (flowOptions) => ({
|
|
123
|
+
...flowOptions.styles === void 0 ? {} : { styles: flowOptions.styles },
|
|
123
124
|
...flowOptions.theme === void 0 ? {} : { theme: flowOptions.theme },
|
|
124
125
|
...flowOptions.fontAlternates === void 0 ? {} : { fontAlternates: flowOptions.fontAlternates },
|
|
125
126
|
...flowOptions.defaultTabStopTwips === void 0 ? {} : { defaultTabStopTwips: flowOptions.defaultTabStopTwips },
|
|
@@ -240,7 +241,7 @@ const layoutDocxHeadless = async (input, options = {}) => {
|
|
|
240
241
|
const contentWidth = pageSize.w - margins.left - margins.right;
|
|
241
242
|
const pageContentHeight = pageSize.h - margins.top - margins.bottom;
|
|
242
243
|
const flowOptions = buildFlowOptions(document, pageContentHeight);
|
|
243
|
-
const storyOptions = buildStoryOptions(
|
|
244
|
+
const storyOptions = buildStoryOptions(flowOptions);
|
|
244
245
|
const laidOut = Result.try(() => {
|
|
245
246
|
const authored = toFlowBlocks(projected.value, flowOptions);
|
|
246
247
|
const footnotes = document.package.footnotes ?? [];
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { document_d_exports } from "./types/document.js";
|
|
2
|
-
import {
|
|
2
|
+
import { FolioContentBlock, FolioContentContainerPathEntry, FolioContentIdStability, FolioContentInlineBooleanProperty, FolioContentInlineFormatting, FolioContentInlineFormattingPatch, FolioContentLineSpacingRule, FolioContentParagraphAlignment, FolioContentParagraphSpacing, FolioContentRun, FolioContentSnapshot, FolioContentTableLocation } from "./compare/content-types.js";
|
|
3
|
+
import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIBlockStructuralBoundary, FolioAIBlockTableLocation, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditNormalization, FolioAIEditNormalizationCode, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAIInlineBooleanProperty, FolioAIInlineFormatting, FolioAIInlineFormattingPatch, FolioAIParagraphSpacing, FolioAISignatureParty } from "./ai-edits/types.js";
|
|
3
4
|
import { WORD_DIFF_GRANULARITIES, WordDiffGranularity, WordDiffNormalization, WordDiffOptions, WordDiffSegment, diffWordSegments } from "./ai-edits/word-diff.js";
|
|
4
5
|
import { FolioAIEditApplyOutcome, FolioRevisionStamp, FolioWordDiffOptions, applyFolioAIEditOperations } from "./ai-edits/apply.js";
|
|
5
|
-
import { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationResultBase, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "./document-operations.js";
|
|
6
|
+
import { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationResultBase, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "./document-operations.js";
|
|
6
7
|
import { createFolioAIEditSnapshot, hashFolioAIBlockText, isFolioAIContentBlock, normalizeFolioAIBlockText } from "./ai-edits/snapshot.js";
|
|
7
8
|
import { DeriveBlockIdInput, FolioBlockId, currentFolioBlockId, deriveBlockId, getFolioParaIdFromBlockId, isFolioBlockId, isSequentialFolioBlockId } from "./types/block-id.js";
|
|
8
9
|
import "./ai-edits/index.js";
|
|
@@ -10,6 +11,7 @@ import { AIBarStatus, AIChatMode, AICitation, AICitationSource, AIGenerateInput,
|
|
|
10
11
|
import { ApplyResult, applySuggestions } from "./ai-suggestions/apply.js";
|
|
11
12
|
import { ResolvedAnchor, isSuggestionStale, resolveSuggestionAnchor } from "./ai-suggestions/conflict.js";
|
|
12
13
|
import { PositionalText, buildPositionalText } from "./ai-suggestions/text-positions.js";
|
|
14
|
+
import { CompareContentOptions, FOLIO_CONTENT_COMPARISON_LIMITS, FolioContentBlockProperty, FolioContentComparison, FolioContentComparisonError, FolioContentComparisonEvent, FolioContentComparisonLimit, FolioContentComparisonLimitError, FolioContentFormatRange, FolioContentFormattingChange, FolioContentParagraphFormattingPatch, FolioContentStructuralChange, FolioContentTextSegment, InvalidFolioContentComparisonError, compareContent } from "./compare/content.js";
|
|
13
15
|
import { COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareVerification, CompareVerificationCause, CompareVerificationFailure, CompareVerificationInvariant, FinalParagraphMarkRevision } from "./compare/verification.js";
|
|
14
16
|
import { COMPARE_UNSUPPORTED_REASONS, CompareChange, CompareChangeLocation, CompareDocxApplyError, CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, CompareFormatRange, CompareResult, CompareUnsupportedPart, CompareUnsupportedReason, InvalidCompareDocxOptionsError } from "./compare/types.js";
|
|
15
17
|
import { MAX_COMPARE_OPERATIONS, compareDocx } from "./compare/compare.js";
|
|
@@ -38,4 +40,4 @@ import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled
|
|
|
38
40
|
import { DOCX_CONFORMANCE_CLASSES } from "@stll/docx-core/model";
|
|
39
41
|
type Document = document_d_exports.Document;
|
|
40
42
|
type DocxConformanceClass = document_d_exports.DocxConformanceClass;
|
|
41
|
-
export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type BlockRect, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, type CompareChange, type CompareChangeLocation, CompareDocxApplyError, type CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, type CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, type CompareFormatRange, type CompareResult, type CompareUnsupportedPart, type CompareUnsupportedReason, type CompareVerification, type CompareVerificationCause, type CompareVerificationFailure, type CompareVerificationInvariant, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, type FinalParagraphMarkRevision, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIBlockTableLocation, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyOutcome, type FolioAIEditApplyResult, type FolioAIEditNormalization, type FolioAIEditNormalizationCode, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAISignatureParty, type FolioBlockId, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationResultBase, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type FolioRevisionStamp, type FolioWordDiffOptions, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidCompareDocxOptionsError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, type WordDiffGranularity, type WordDiffNormalization, type WordDiffOptions, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
|
43
|
+
export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type BlockRect, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, type CompareChange, type CompareChangeLocation, type CompareContentOptions, CompareDocxApplyError, type CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, type CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, type CompareFormatRange, type CompareResult, type CompareUnsupportedPart, type CompareUnsupportedReason, type CompareVerification, type CompareVerificationCause, type CompareVerificationFailure, type CompareVerificationInvariant, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_CONTENT_COMPARISON_LIMITS, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, type FinalParagraphMarkRevision, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIBlockStructuralBoundary, type FolioAIBlockTableLocation, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyOutcome, type FolioAIEditApplyResult, type FolioAIEditNormalization, type FolioAIEditNormalizationCode, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAIInlineBooleanProperty, type FolioAIInlineFormatting, type FolioAIInlineFormattingPatch, type FolioAIParagraphSpacing, type FolioAISignatureParty, type FolioBlockId, type FolioContentBlock, type FolioContentBlockProperty, type FolioContentComparison, type FolioContentComparisonError, type FolioContentComparisonEvent, type FolioContentComparisonLimit, FolioContentComparisonLimitError, type FolioContentContainerPathEntry, type FolioContentFormatRange, type FolioContentFormattingChange, type FolioContentIdStability, type FolioContentInlineBooleanProperty, type FolioContentInlineFormatting, type FolioContentInlineFormattingPatch, type FolioContentLineSpacingRule, type FolioContentParagraphAlignment, type FolioContentParagraphFormattingPatch, type FolioContentParagraphSpacing, type FolioContentRun, type FolioContentSnapshot, type FolioContentStructuralChange, type FolioContentTableLocation, type FolioContentTextSegment, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationResultBase, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type FolioRevisionStamp, type FolioWordDiffOptions, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidCompareDocxOptionsError, InvalidFolioContentComparisonError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, type WordDiffGranularity, type WordDiffNormalization, type WordDiffOptions, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareContent, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
package/dist/index.js
CHANGED
|
@@ -6,9 +6,10 @@ import { isSuggestionStale, resolveSuggestionAnchor } from "./ai-suggestions/con
|
|
|
6
6
|
import { buildPositionalText } from "./ai-suggestions/text-positions.js";
|
|
7
7
|
import { DEFAULT_AI_SUGGESTION_PRESETS } from "./ai-suggestions/types.js";
|
|
8
8
|
import { MAX_COMPARE_OPERATIONS, compareDocx } from "./compare/compare.js";
|
|
9
|
+
import { FOLIO_CONTENT_COMPARISON_LIMITS, FolioContentComparisonLimitError, InvalidFolioContentComparisonError, compareContent } from "./compare/content.js";
|
|
9
10
|
import { COMPARE_UNSUPPORTED_REASONS, CompareDocxApplyError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, InvalidCompareDocxOptionsError } from "./compare/types.js";
|
|
10
11
|
import { COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS } from "./compare/verification.js";
|
|
11
|
-
import { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "./document-operations.js";
|
|
12
|
+
import { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "./document-operations.js";
|
|
12
13
|
import { inspectDocxCompatibility } from "./docx/compatibility.js";
|
|
13
14
|
import { createDocx } from "./docx/rezip.js";
|
|
14
15
|
import { buildEmbeddedFontFamilyMap, extractEmbeddedFonts, getEmbeddedFontFaces, scopeEmbeddedFontFamily } from "./fonts/embeddedFonts.js";
|
|
@@ -31,4 +32,4 @@ import { createEmptyDocument } from "./utils/createDocument.js";
|
|
|
31
32
|
import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled } from "./utils/fontResolver.js";
|
|
32
33
|
import { mergeDocumentContent } from "./utils/mergeDocumentContent.js";
|
|
33
34
|
import { DOCX_CONFORMANCE_CLASSES } from "@stll/docx-core/model";
|
|
34
|
-
export { COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareDocxApplyError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, InvalidCompareDocxOptionsError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, STELLA_STYLE_SET_NAME, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
|
35
|
+
export { COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareDocxApplyError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, FOLIO_CONTENT_COMPARISON_LIMITS, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, FolioContentComparisonLimitError, InvalidCompareDocxOptionsError, InvalidFolioContentComparisonError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, STELLA_STYLE_SET_NAME, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareContent, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { RunStyleResolver } from "../prosemirror/runStyleFormatting.js";
|
|
2
|
+
import { Transaction } from "prosemirror-state";
|
|
3
|
+
import { MarkType } from "prosemirror-model";
|
|
4
|
+
//#region src/internal/headlessRevisionResolution.d.ts
|
|
5
|
+
type HeadlessRevisionResolutionMode = "accept" | "reject";
|
|
6
|
+
type HeadlessRange = {
|
|
7
|
+
from: number;
|
|
8
|
+
to: number;
|
|
9
|
+
};
|
|
10
|
+
type HeadlessInlineChangeTracking = {
|
|
11
|
+
ranges: readonly HeadlessRange[];
|
|
12
|
+
mappingFrom: number;
|
|
13
|
+
};
|
|
14
|
+
type AppendHeadlessInlineResolutionOptions = {
|
|
15
|
+
tr: Transaction;
|
|
16
|
+
mode: HeadlessRevisionResolutionMode;
|
|
17
|
+
keepType: MarkType | undefined;
|
|
18
|
+
removeType: MarkType | undefined;
|
|
19
|
+
styleResolver: RunStyleResolver | null;
|
|
20
|
+
};
|
|
21
|
+
declare const appendHeadlessInlineResolution: ({ tr, mode, keepType, removeType, styleResolver }: AppendHeadlessInlineResolutionOptions) => HeadlessInlineChangeTracking | null;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { HeadlessInlineChangeTracking, HeadlessRevisionResolutionMode, appendHeadlessInlineResolution };
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { recreateProseNodeWithParagraphPropertySource } from "../docx/paragraphPropertySource.js";
|
|
2
|
+
import { expectRunPropertyChangeMarkAttrs } from "../prosemirror/attrs/index.js";
|
|
3
|
+
import { RUN_FORMATTING_MARK_NAMES } from "../prosemirror/runFormattingMarkNames.js";
|
|
4
|
+
import { reconstructRejectedRunFormattingMarks } from "../prosemirror/runPropertyChangeResolution.js";
|
|
5
|
+
import { paragraphRunStyleContext } from "../prosemirror/runStyleFormatting.js";
|
|
6
|
+
import { panic } from "better-result";
|
|
7
|
+
import { Fragment, Slice } from "prosemirror-model";
|
|
8
|
+
import { ReplaceStep, StepMap } from "prosemirror-transform";
|
|
9
|
+
//#region src/internal/headlessRevisionResolution.ts
|
|
10
|
+
const EMPTY_PARAGRAPH_RUN_STYLE_CONTEXT = {
|
|
11
|
+
baseParagraphFormatting: void 0,
|
|
12
|
+
paragraphFormatting: void 0,
|
|
13
|
+
paragraphMarkFormatting: void 0,
|
|
14
|
+
paragraphMarkPrecedesStyle: false
|
|
15
|
+
};
|
|
16
|
+
const resolveParagraphRunStyleScope = (scope, styleResolver) => {
|
|
17
|
+
if (!scope) return EMPTY_PARAGRAPH_RUN_STYLE_CONTEXT;
|
|
18
|
+
scope.resolved ??= paragraphRunStyleContext(scope.paragraph, styleResolver);
|
|
19
|
+
return scope.resolved;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* A synchronous headless replacement with the granular position map of the
|
|
23
|
+
* inline deletions it applies. It must never enter history or collaboration;
|
|
24
|
+
* map and serialization fail loudly if that invariant is broken.
|
|
25
|
+
*/
|
|
26
|
+
var HeadlessInlineResolutionStep = class HeadlessInlineResolutionStep extends ReplaceStep {
|
|
27
|
+
positionMap;
|
|
28
|
+
constructor(from, to, slice, positionMap) {
|
|
29
|
+
super(from, to, slice);
|
|
30
|
+
this.positionMap = positionMap;
|
|
31
|
+
}
|
|
32
|
+
getMap() {
|
|
33
|
+
return this.positionMap;
|
|
34
|
+
}
|
|
35
|
+
invert(doc) {
|
|
36
|
+
return new HeadlessInlineResolutionStep(this.from, this.from + this.slice.size, doc.slice(this.from, this.to), this.positionMap.invert());
|
|
37
|
+
}
|
|
38
|
+
map(_mapping) {
|
|
39
|
+
return panic("A headless revision-resolution step cannot be mapped");
|
|
40
|
+
}
|
|
41
|
+
toJSON() {
|
|
42
|
+
return panic("A headless revision-resolution step cannot be serialized");
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
const marksEqual = (left, right) => left.length === right.length && left.every((mark, index) => {
|
|
46
|
+
const candidate = right[index];
|
|
47
|
+
return candidate !== void 0 && mark.eq(candidate);
|
|
48
|
+
});
|
|
49
|
+
const rebuildNode = (source, attrs, content, marks = source.marks) => recreateProseNodeWithParagraphPropertySource(source, {
|
|
50
|
+
attrs,
|
|
51
|
+
content,
|
|
52
|
+
marks
|
|
53
|
+
});
|
|
54
|
+
const resolveInlineNode = ({ node, context, paragraphScope }) => {
|
|
55
|
+
let marks = node.marks;
|
|
56
|
+
const runPropertyChangeMark = marks.find((mark) => mark.type.name === "runPropertyChange");
|
|
57
|
+
if (runPropertyChangeMark) {
|
|
58
|
+
const { changes } = expectRunPropertyChangeMarkAttrs(runPropertyChangeMark);
|
|
59
|
+
if (changes.length > 0) {
|
|
60
|
+
marks = marks.filter((mark) => mark !== runPropertyChangeMark);
|
|
61
|
+
if (context.mode === "reject") {
|
|
62
|
+
marks = marks.filter((mark) => !RUN_FORMATTING_MARK_NAMES.has(mark.type.name));
|
|
63
|
+
const previousFormatting = changes.at(0)?.previousFormatting;
|
|
64
|
+
for (const previousMark of reconstructRejectedRunFormattingMarks({
|
|
65
|
+
node,
|
|
66
|
+
paragraphContext: resolveParagraphRunStyleScope(paragraphScope, context.styleResolver),
|
|
67
|
+
previousFormatting,
|
|
68
|
+
styleResolver: context.styleResolver
|
|
69
|
+
})) marks = previousMark.addToSet(marks);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (context.removeType && node.marks.some((mark) => mark.type === context.removeType)) return null;
|
|
74
|
+
if (context.keepType) marks = marks.filter((mark) => mark.type !== context.keepType);
|
|
75
|
+
return marksEqual(marks, node.marks) ? node : node.mark(marks);
|
|
76
|
+
};
|
|
77
|
+
const resolveInlineContent = ({ node, position, context, inheritedParagraphScope }) => {
|
|
78
|
+
const paragraphScope = node.type.name === "paragraph" && context.mode === "reject" ? { paragraph: node } : inheritedParagraphScope;
|
|
79
|
+
const replacementRangeStart = context.replacementRanges.length;
|
|
80
|
+
let resolvedNode = node;
|
|
81
|
+
if (node.isInline) {
|
|
82
|
+
const resolved = resolveInlineNode({
|
|
83
|
+
node,
|
|
84
|
+
context,
|
|
85
|
+
paragraphScope
|
|
86
|
+
});
|
|
87
|
+
if (resolved === null) {
|
|
88
|
+
context.replacementRanges.push({
|
|
89
|
+
from: position,
|
|
90
|
+
to: position + node.nodeSize,
|
|
91
|
+
newSize: 0
|
|
92
|
+
});
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
resolvedNode = resolved;
|
|
96
|
+
if (resolvedNode.isLeaf) return resolvedNode;
|
|
97
|
+
}
|
|
98
|
+
const children = [];
|
|
99
|
+
const contentStart = resolvedNode.type.name === "doc" ? 0 : position + 1;
|
|
100
|
+
let contentChanged = false;
|
|
101
|
+
resolvedNode.forEach((child, offset) => {
|
|
102
|
+
const resolved = resolveInlineContent({
|
|
103
|
+
node: child,
|
|
104
|
+
position: contentStart + offset,
|
|
105
|
+
context,
|
|
106
|
+
...paragraphScope !== void 0 ? { inheritedParagraphScope: paragraphScope } : {}
|
|
107
|
+
});
|
|
108
|
+
if (resolved) {
|
|
109
|
+
children.push(resolved);
|
|
110
|
+
contentChanged ||= resolved !== child;
|
|
111
|
+
} else contentChanged = true;
|
|
112
|
+
});
|
|
113
|
+
if (!contentChanged) return resolvedNode;
|
|
114
|
+
let resolvedContent = Fragment.fromArray(children);
|
|
115
|
+
if (!resolvedNode.type.validContent(resolvedContent)) {
|
|
116
|
+
const fitted = resolvedNode.type.createAndFill(resolvedNode.attrs, resolvedContent, resolvedNode.marks);
|
|
117
|
+
if (!fitted || !resolvedNode.type.validContent(fitted.content)) {
|
|
118
|
+
if (!resolvedNode.isInline) return panic(`Headless inline resolution invalidated ${resolvedNode.type.name} content`);
|
|
119
|
+
context.replacementRanges.splice(replacementRangeStart, context.replacementRanges.length - replacementRangeStart, {
|
|
120
|
+
from: position,
|
|
121
|
+
to: position + node.nodeSize,
|
|
122
|
+
newSize: 0
|
|
123
|
+
});
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
context.replacementRanges.splice(replacementRangeStart, context.replacementRanges.length - replacementRangeStart, {
|
|
127
|
+
from: contentStart,
|
|
128
|
+
to: contentStart + node.content.size,
|
|
129
|
+
newSize: fitted.content.size
|
|
130
|
+
});
|
|
131
|
+
resolvedContent = fitted.content;
|
|
132
|
+
}
|
|
133
|
+
if (resolvedNode.type.name === "paragraph") context.changedParagraphRanges.push({
|
|
134
|
+
from: position,
|
|
135
|
+
to: position + resolvedNode.nodeSize
|
|
136
|
+
});
|
|
137
|
+
return rebuildNode(node, resolvedNode.attrs, resolvedContent, resolvedNode.marks);
|
|
138
|
+
};
|
|
139
|
+
const coalesceReplacementRanges = (replacementRanges) => {
|
|
140
|
+
const coalesced = [];
|
|
141
|
+
for (const range of replacementRanges) {
|
|
142
|
+
const previous = coalesced.at(-1);
|
|
143
|
+
if (previous && previous.newSize === 0 && range.newSize === 0 && range.from <= previous.to) previous.to = Math.max(previous.to, range.to);
|
|
144
|
+
else coalesced.push({ ...range });
|
|
145
|
+
}
|
|
146
|
+
return coalesced;
|
|
147
|
+
};
|
|
148
|
+
const appendHeadlessInlineResolution = ({ tr, mode, keepType, removeType, styleResolver }) => {
|
|
149
|
+
const context = {
|
|
150
|
+
mode,
|
|
151
|
+
keepType,
|
|
152
|
+
removeType,
|
|
153
|
+
replacementRanges: [],
|
|
154
|
+
changedParagraphRanges: [],
|
|
155
|
+
styleResolver
|
|
156
|
+
};
|
|
157
|
+
const resolved = resolveInlineContent({
|
|
158
|
+
node: tr.doc,
|
|
159
|
+
position: -1,
|
|
160
|
+
context
|
|
161
|
+
});
|
|
162
|
+
if (!resolved || resolved.eq(tr.doc)) return null;
|
|
163
|
+
const positionMap = new StepMap(coalesceReplacementRanges(context.replacementRanges).flatMap(({ from, to, newSize }) => [
|
|
164
|
+
from,
|
|
165
|
+
to - from,
|
|
166
|
+
newSize
|
|
167
|
+
]));
|
|
168
|
+
const mappingFrom = tr.steps.length;
|
|
169
|
+
tr.step(new HeadlessInlineResolutionStep(0, tr.doc.content.size, new Slice(resolved.content, 0, 0), positionMap));
|
|
170
|
+
return {
|
|
171
|
+
ranges: context.changedParagraphRanges,
|
|
172
|
+
mappingFrom
|
|
173
|
+
};
|
|
174
|
+
};
|
|
175
|
+
//#endregion
|
|
176
|
+
export { appendHeadlessInlineResolution };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { EditorState, Plugin } from "prosemirror-state";
|
|
2
|
+
//#region src/internal/headlessRevisionResolutionGuard.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Whether a state can consume an unmapped replacement before it returns.
|
|
5
|
+
* Only the internal headless plugin set opts in; history and collaboration
|
|
6
|
+
* plugins always keep the state on the legacy editor-command path.
|
|
7
|
+
*/
|
|
8
|
+
declare const stateAllowsHeadlessRevisionResolution: (state: EditorState) => boolean;
|
|
9
|
+
/** Build the private plugin set for synchronous headless review states. */
|
|
10
|
+
declare const pluginsForHeadlessRevisionResolution: (plugins: readonly Plugin[]) => readonly Plugin[];
|
|
11
|
+
//#endregion
|
|
12
|
+
export { pluginsForHeadlessRevisionResolution, stateAllowsHeadlessRevisionResolution };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Plugin, PluginKey } from "prosemirror-state";
|
|
2
|
+
//#region src/internal/headlessRevisionResolutionGuard.ts
|
|
3
|
+
const UNSAFE_PLUGIN_KEY_PREFIXES = [
|
|
4
|
+
"collab$",
|
|
5
|
+
"history$",
|
|
6
|
+
"y-sync$",
|
|
7
|
+
"y-undo$"
|
|
8
|
+
];
|
|
9
|
+
const headlessRevisionResolutionKey = new PluginKey("folioHeadlessRevisionResolution");
|
|
10
|
+
const headlessRevisionResolutionPlugin = new Plugin({ key: headlessRevisionResolutionKey });
|
|
11
|
+
const pluginRuntimeKey = (plugin) => {
|
|
12
|
+
const key = Reflect.get(plugin, "key");
|
|
13
|
+
return typeof key === "string" ? key : null;
|
|
14
|
+
};
|
|
15
|
+
const retainsOrTransportsSteps = (plugin) => {
|
|
16
|
+
const key = pluginRuntimeKey(plugin);
|
|
17
|
+
return key !== null && UNSAFE_PLUGIN_KEY_PREFIXES.some((prefix) => key.startsWith(prefix));
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Whether a state can consume an unmapped replacement before it returns.
|
|
21
|
+
* Only the internal headless plugin set opts in; history and collaboration
|
|
22
|
+
* plugins always keep the state on the legacy editor-command path.
|
|
23
|
+
*/
|
|
24
|
+
const stateAllowsHeadlessRevisionResolution = (state) => headlessRevisionResolutionKey.get(state) === headlessRevisionResolutionPlugin && !state.plugins.some(retainsOrTransportsSteps);
|
|
25
|
+
/** Build the private plugin set for synchronous headless review states. */
|
|
26
|
+
const pluginsForHeadlessRevisionResolution = (plugins) => [...plugins.filter((plugin) => !retainsOrTransportsSteps(plugin)), headlessRevisionResolutionPlugin];
|
|
27
|
+
//#endregion
|
|
28
|
+
export { pluginsForHeadlessRevisionResolution, stateAllowsHeadlessRevisionResolution };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Node } from "prosemirror-model";
|
|
2
|
+
//#region src/internal/pageBreakRunDescendantIndex.d.ts
|
|
3
|
+
type PageBreakRunDescendantIndex = {
|
|
4
|
+
firstPageBreakRunPosition: (node: Node) => number | undefined;
|
|
5
|
+
};
|
|
6
|
+
/** Build one identity-scoped index for a single layout conversion. */
|
|
7
|
+
declare const buildPageBreakRunDescendantIndex: (doc: Node) => PageBreakRunDescendantIndex;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { PageBreakRunDescendantIndex, buildPageBreakRunDescendantIndex };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//#region src/internal/pageBreakRunDescendantIndex.ts
|
|
2
|
+
const indexesPageBreakDescendants = (node) => {
|
|
3
|
+
switch (node.type.name) {
|
|
4
|
+
case "paragraph":
|
|
5
|
+
case "tableCell":
|
|
6
|
+
case "tableHeader":
|
|
7
|
+
case "textBox": return true;
|
|
8
|
+
default: return false;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
/** Build one identity-scoped index for a single layout conversion. */
|
|
12
|
+
const buildPageBreakRunDescendantIndex = (doc) => {
|
|
13
|
+
const positions = /* @__PURE__ */ new WeakMap();
|
|
14
|
+
const visitNode = (node, startPos) => {
|
|
15
|
+
let firstPosition = node.type.name === "pageBreakRun" ? startPos : void 0;
|
|
16
|
+
node.forEach((child, offset) => {
|
|
17
|
+
const descendantPosition = visitNode(child, startPos + 1 + offset);
|
|
18
|
+
firstPosition ??= descendantPosition;
|
|
19
|
+
});
|
|
20
|
+
if (firstPosition !== void 0 && indexesPageBreakDescendants(node)) positions.set(node, firstPosition);
|
|
21
|
+
return firstPosition;
|
|
22
|
+
};
|
|
23
|
+
visitNode(doc, -1);
|
|
24
|
+
return { firstPageBreakRunPosition: (node) => positions.get(node) };
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { buildPageBreakRunDescendantIndex };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/internal/pageBreakRunPartition.d.ts
|
|
2
|
+
type PositionedRun = {
|
|
3
|
+
pmStart?: number;
|
|
4
|
+
pmEnd?: number;
|
|
5
|
+
};
|
|
6
|
+
type PositionedPageBreak = {
|
|
7
|
+
pmStart: number;
|
|
8
|
+
pmEnd: number;
|
|
9
|
+
};
|
|
10
|
+
type PageBreakRunPartition<TRun, TPageBreak> = {
|
|
11
|
+
before: TRun[];
|
|
12
|
+
pageBreak: TPageBreak;
|
|
13
|
+
};
|
|
14
|
+
type PageBreakRunPartitionResult<TRun, TPageBreak> = {
|
|
15
|
+
type: "partitioned";
|
|
16
|
+
partitions: PageBreakRunPartition<TRun, TPageBreak>[];
|
|
17
|
+
remaining: TRun[];
|
|
18
|
+
} | {
|
|
19
|
+
type: "overlap";
|
|
20
|
+
pageBreak: TPageBreak;
|
|
21
|
+
run: TRun;
|
|
22
|
+
};
|
|
23
|
+
/** Partition ordered runs with one monotonic cursor; each run is consumed once and peeked once. */
|
|
24
|
+
declare const partitionRunsAtPageBreaks: <TRun extends PositionedRun, TPageBreak extends PositionedPageBreak>(runs: readonly TRun[], pageBreaks: readonly TPageBreak[]) => PageBreakRunPartitionResult<TRun, TPageBreak>;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { PageBreakRunPartition, PageBreakRunPartitionResult, partitionRunsAtPageBreaks };
|