@stll/folio-core 0.55.0 → 0.57.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.
- package/dist/ai-edits/apply.js +214 -52
- package/dist/ai-edits/batch-claims.d.ts +3 -1
- package/dist/ai-edits/batch-claims.js +25 -1
- package/dist/ai-edits/headless.js +2 -2
- package/dist/ai-edits/table-row-column-mutations.js +17 -3
- package/dist/ai-edits/types.d.ts +7 -1
- package/dist/ai-suggestions/apply.js +20 -1
- package/dist/compare/compare.js +1 -0
- package/dist/compare/inline-atoms.js +40 -16
- package/dist/compare/inline-provenance.js +12 -5
- package/dist/compare/reproducible-package.d.ts +0 -17
- package/dist/compare/reproducible-package.js +12 -18
- package/dist/compat/eigenpal.d.ts +2 -1
- package/dist/compat/eigenpal.js +2 -1
- package/dist/controller/canonicalClipboard.d.ts +23 -0
- package/dist/controller/canonicalClipboard.js +482 -0
- package/dist/controller/canonicalClipboardResources.d.ts +21 -0
- package/dist/controller/canonicalClipboardResources.js +382 -0
- package/dist/controller/canonicalComments.d.ts +41 -0
- package/dist/controller/canonicalComments.js +152 -0
- package/dist/controller/canonicalComposition.d.ts +24 -3
- package/dist/controller/canonicalComposition.js +208 -48
- package/dist/controller/canonicalInlineProjection.d.ts +118 -0
- package/dist/controller/canonicalInlineProjection.js +476 -0
- package/dist/controller/canonicalInput.d.ts +13 -4
- package/dist/controller/canonicalInput.js +62 -14
- package/dist/controller/canonicalInputTimer.d.ts +16 -0
- package/dist/controller/canonicalInputTimer.js +34 -0
- package/dist/controller/canonicalPublicOperations.d.ts +48 -0
- package/dist/controller/canonicalPublicOperations.js +648 -0
- package/dist/controller/canonicalSelection.d.ts +18 -0
- package/dist/controller/canonicalSelection.js +32 -0
- package/dist/controller/canonicalSession.d.ts +27 -6
- package/dist/controller/canonicalSession.js +298 -116
- package/dist/controller/canonicalStoryEditor.d.ts +7 -3
- package/dist/controller/canonicalStoryEditor.js +27 -2
- package/dist/controller/canonicalStructure.js +57 -4
- package/dist/controller/canonicalTocSelection.d.ts +11 -0
- package/dist/controller/canonicalTocSelection.js +43 -0
- package/dist/controller/folioEditor.d.ts +2 -9
- package/dist/controller/folioEditor.js +18 -4
- package/dist/controller/headerFooterEditorManager.d.ts +2 -1
- package/dist/controller/headerFooterEditorManager.js +26 -11
- package/dist/controller/hiddenEditorApi.d.ts +24 -3
- package/dist/controller/hiddenEditorApi.js +8 -0
- package/dist/controller/hiddenEditorManager.d.ts +5 -1
- package/dist/controller/hiddenEditorManager.js +378 -43
- package/dist/controller/noteEditorManager.d.ts +2 -1
- package/dist/controller/noteEditorManager.js +29 -13
- package/dist/document-operations.d.ts +8 -1
- package/dist/document-operations.js +6 -4
- package/dist/docx/blockPlainText.d.ts +1 -1
- package/dist/docx/blockPlainText.js +11 -3
- package/dist/docx/builtInStyles.js +13 -6
- package/dist/docx/canonicalResourceSave.d.ts +16 -0
- package/dist/docx/canonicalResourceSave.js +27 -0
- package/dist/docx/canonicalSave.d.ts +29 -0
- package/dist/docx/canonicalSave.js +101 -0
- package/dist/docx/canonicalStoryRepack.d.ts +1 -1
- package/dist/docx/canonicalStoryRepack.js +38 -5
- package/dist/docx/containerChildren.gen.d.ts +3 -1
- package/dist/docx/containerChildren.gen.js +33 -1
- package/dist/docx/documentParser.d.ts +1 -13
- package/dist/docx/documentParser.js +1 -47
- package/dist/docx/ensureParaIds.js +10 -4
- package/dist/docx/fieldParser.js +14 -2
- package/dist/docx/footnoteParser.d.ts +1 -11
- package/dist/docx/footnoteParser.js +1 -16
- package/dist/docx/headerFooterParser.d.ts +1 -9
- package/dist/docx/headerFooterParser.js +1 -12
- package/dist/docx/headerFooterVerbatim.d.ts +26 -1
- package/dist/docx/headerFooterVerbatim.js +81 -3
- package/dist/docx/hyperlinkParser.d.ts +1 -1
- package/dist/docx/hyperlinkParser.js +20 -1
- package/dist/docx/imageParser.d.ts +13 -1
- package/dist/docx/imageParser.js +20 -11
- package/dist/docx/inlineWrapperContent.d.ts +4 -4
- package/dist/docx/inlineWrapperContent.js +4 -4
- package/dist/docx/linkedSdtPreservation.d.ts +10 -0
- package/dist/docx/linkedSdtPreservation.js +37 -0
- package/dist/docx/metadataPrivacy.js +6 -1
- package/dist/docx/packageParts.js +9 -3
- package/dist/docx/paragraphParser.js +88 -67
- package/dist/docx/paragraphPropertySource.d.ts +22 -1
- package/dist/docx/paragraphPropertySource.js +109 -2
- package/dist/docx/parser.js +2 -1
- package/dist/docx/preservedRunContent.js +2 -1
- package/dist/docx/relsParser.js +26 -2
- package/dist/docx/removeHeaderFooterParts.js +17 -6
- package/dist/docx/rezip.d.ts +49 -5
- package/dist/docx/rezip.js +754 -235
- package/dist/docx/saveDiagnostics.d.ts +11 -0
- package/dist/docx/selectiveSave.d.ts +2 -1
- package/dist/docx/selectiveSave.js +42 -11
- package/dist/docx/selectiveXmlPatch.js +7 -5
- package/dist/docx/serializer/commentSerializer.d.ts +4 -1
- package/dist/docx/serializer/commentSerializer.js +7 -3
- package/dist/docx/serializer/documentSerializer.d.ts +9 -2
- package/dist/docx/serializer/documentSerializer.js +29 -10
- package/dist/docx/serializer/paragraphSerializer.js +207 -94
- package/dist/docx/server/applyDocxXmlPatchProposal.js +14 -9
- package/dist/docx/server/materializeYjsDocx.js +14 -6
- package/dist/docx/server/migrateYjsAttrSchema.js +17 -5
- package/dist/docx/storyBlockReplay.d.ts +21 -1
- package/dist/docx/storyBlockReplay.js +113 -9
- package/dist/docx/storyPlainText.d.ts +20 -0
- package/dist/docx/storyPlainText.js +23 -0
- package/dist/docx/structuralXmlPatch.js +10 -22
- package/dist/docx/styleParser.d.ts +5 -1
- package/dist/docx/styleParser.js +1 -1
- package/dist/docx/tableParser.d.ts +1 -8
- package/dist/docx/tableParser.js +1 -28
- package/dist/docx/textBoxParser.d.ts +1 -5
- package/dist/docx/textBoxParser.js +1 -20
- package/dist/docx/unzip.js +6 -1
- package/dist/i18n/messages/ar.gen.js +4 -0
- package/dist/i18n/messages/catalogs.gen.d.ts +68 -0
- package/dist/i18n/messages/catalogs.gen.js +68 -0
- package/dist/i18n/messages/cs.gen.js +4 -0
- package/dist/i18n/messages/de.gen.js +4 -0
- package/dist/i18n/messages/en.gen.js +4 -0
- package/dist/i18n/messages/es.gen.js +4 -0
- package/dist/i18n/messages/et.gen.js +4 -0
- package/dist/i18n/messages/fr.gen.js +4 -0
- package/dist/i18n/messages/he.gen.js +4 -0
- package/dist/i18n/messages/hi.gen.js +4 -0
- package/dist/i18n/messages/hu.gen.js +4 -0
- package/dist/i18n/messages/lt.gen.js +4 -0
- package/dist/i18n/messages/lv.gen.js +4 -0
- package/dist/i18n/messages/messages.gen.d.ts +4 -0
- package/dist/i18n/messages/pl.gen.js +4 -0
- package/dist/i18n/messages/pt-BR.gen.js +4 -0
- package/dist/i18n/messages/sk.gen.js +4 -0
- package/dist/i18n/messages/tr.gen.js +4 -0
- package/dist/i18n/messages/zh-CN.gen.js +4 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/internal/acceptedBlockProjection.d.ts +12 -0
- package/dist/internal/acceptedBlockProjection.js +45 -0
- package/dist/internal/revisionResolutionInline.js +25 -3
- package/dist/managers/DocumentLoaderManager.js +2 -1
- package/dist/markdown/escape.d.ts +3 -1
- package/dist/markdown/escape.js +9 -2
- package/dist/markdown/renderBlock.js +5 -120
- package/dist/markdown/renderParagraph.js +4 -2
- package/dist/markdown/renderRuns.d.ts +7 -1
- package/dist/markdown/renderRuns.js +33 -24
- package/dist/panel-layout.d.ts +11 -9
- package/dist/panel-layout.js +13 -9
- package/dist/prosemirror/addTrackedDeletionMark.d.ts +18 -0
- package/dist/prosemirror/addTrackedDeletionMark.js +87 -0
- package/dist/prosemirror/attrs/index.js +5 -0
- package/dist/prosemirror/canonicalCommands.d.ts +28 -4
- package/dist/prosemirror/canonicalCommands.js +11 -4
- package/dist/prosemirror/canonicalSelectionRange.d.ts +9 -0
- package/dist/prosemirror/canonicalSelectionRange.js +15 -0
- package/dist/prosemirror/clipboardIntent.d.ts +7 -0
- package/dist/prosemirror/clipboardIntent.js +9 -0
- package/dist/prosemirror/commands/comments.js +60 -35
- package/dist/prosemirror/commands/pageBreak.js +2 -2
- package/dist/prosemirror/commands/pastePlainText.js +2 -1
- package/dist/prosemirror/commands/propertyChangeScope.js +3 -6
- package/dist/prosemirror/commands/resolveParagraphProperties.js +22 -13
- package/dist/prosemirror/commentOps.js +15 -1
- package/dist/prosemirror/conversion/fromProseDoc.js +22 -3
- package/dist/prosemirror/conversion/hyphenTextCarriers.d.ts +8 -0
- package/dist/prosemirror/conversion/hyphenTextCarriers.js +8 -0
- package/dist/prosemirror/conversion/toProseDoc.d.ts +7 -1
- package/dist/prosemirror/conversion/toProseDoc.js +124 -22
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +61 -35
- package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +74 -25
- package/dist/prosemirror/extensions/marks/FootnoteRefExtension.js +11 -0
- package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +65 -29
- package/dist/prosemirror/extensions/marks/markUtils.js +11 -8
- package/dist/prosemirror/extensions/marks/noteReferenceDeletion.js +5 -2
- package/dist/prosemirror/fieldRepresentation.d.ts +8 -0
- package/dist/prosemirror/fieldRepresentation.js +18 -0
- package/dist/prosemirror/hyperlinkRemoval.d.ts +13 -1
- package/dist/prosemirror/hyperlinkRemoval.js +28 -9
- package/dist/prosemirror/insertOperations.js +2 -1
- package/dist/prosemirror/listNumbering.js +11 -5
- package/dist/prosemirror/noteReferenceOccurrenceId.d.ts +5 -0
- package/dist/prosemirror/noteReferenceOccurrenceId.js +5 -0
- package/dist/prosemirror/noteReferenceOccurrences.d.ts +21 -0
- package/dist/prosemirror/noteReferenceOccurrences.js +185 -0
- package/dist/prosemirror/noteReferenceReview.js +14 -1
- package/dist/prosemirror/paragraphPropertyCarry.d.ts +7 -1
- package/dist/prosemirror/paragraphPropertyCarry.js +8 -3
- package/dist/prosemirror/plugins/documentStyles.d.ts +4 -1
- package/dist/prosemirror/plugins/documentStyles.js +17 -10
- package/dist/prosemirror/plugins/suggestionMode.js +48 -48
- package/dist/prosemirror/preservedXmlReview.d.ts +6 -0
- package/dist/prosemirror/preservedXmlReview.js +35 -0
- package/dist/prosemirror/runFormattingFromMarks.js +2 -2
- package/dist/prosemirror/runFormattingReconciliation.js +5 -4
- package/dist/prosemirror/runPropertyChangeResolution.d.ts +8 -1
- package/dist/prosemirror/runPropertyChangeResolution.js +24 -2
- package/dist/prosemirror/runStyleFormatting.d.ts +3 -1
- package/dist/prosemirror/runStyleFormatting.js +3 -1
- package/dist/prosemirror/schema/marks.d.ts +1 -0
- package/dist/prosemirror/schema/nodes.d.ts +2 -0
- package/dist/prosemirror/styles/paragraphStyleCascade.js +4 -1
- package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +15 -15
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +69 -28
- package/dist/prosemirror/textInput.d.ts +5 -1
- package/dist/prosemirror/textInput.js +3 -3
- package/dist/prosemirror/trackedRevisionPath.d.ts +5 -1
- package/dist/prosemirror/trackedRevisionPath.js +39 -1
- package/dist/prosemirror/validation.js +3 -5
- package/dist/prosemirror/yjsDocumentMetadata.d.ts +9 -3
- package/dist/prosemirror/yjsDocumentMetadata.js +37 -8
- package/dist/types/canonicalCapabilities.d.ts +201 -0
- package/dist/types/canonicalCapabilities.js +198 -0
- package/dist/types/canonicalComments.d.ts +51 -0
- package/dist/types/canonicalComments.js +0 -0
- package/dist/types/canonicalSave.d.ts +11 -0
- package/dist/types/canonicalSave.js +0 -0
- package/dist/types/canonicalSections.d.ts +12 -0
- package/dist/types/canonicalSections.js +0 -0
- package/dist/types/docxSerialization.d.ts +14 -0
- package/dist/types/docxSerialization.js +7 -0
- package/dist/utils/headingCollector.js +45 -4
- package/dist/utils/outlineDepth.d.ts +9 -0
- package/dist/utils/outlineDepth.js +9 -0
- package/package.json +4 -4
package/dist/ai-edits/apply.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { paragraphNumberingReference, paragraphNumberingReferenceId } from "../docx/numberingReference.js";
|
|
2
2
|
import { formattingEquals } from "../docx/runConsolidator.js";
|
|
3
3
|
import { isStyleSourcedParagraphNumbering } from "../internal/paragraphFormattingSerialization.js";
|
|
4
|
+
import { addTrackedDeletionMark } from "../prosemirror/addTrackedDeletionMark.js";
|
|
4
5
|
import { deleteTextBoxesAnchoredAt, droppedTextBoxAnchorIds, endOfParagraphWithItsTextBoxes, gatherTextBoxesAfterParagraph, textBoxAnchorIdOf, textBoxAnchorIdsBetween } from "../prosemirror/anchoredTextBoxes.js";
|
|
5
6
|
import { expectParagraphAttrs, expectRunPropertyChangeMarkAttrs, expectTableRowAttrs } from "../prosemirror/attrs/index.js";
|
|
6
7
|
import { hasSerializableParagraphPropertyChange, paragraphPropertiesSnapshot } from "../prosemirror/commands/propertyChangeScope.js";
|
|
@@ -17,7 +18,7 @@ import { directParagraphAlignment } from "../prosemirror/paragraphAlignment.js";
|
|
|
17
18
|
import { styleResolvedParagraphFormatting } from "../prosemirror/paragraphFormattingProvenance.js";
|
|
18
19
|
import { directParagraphIndentation, paragraphIndentationAttrPatch, paragraphIndentationEqual, paragraphIndentationFromFormatting, withDirectParagraphIndentation } from "../prosemirror/paragraphIndentation.js";
|
|
19
20
|
import { joinAtParagraphMark } from "../prosemirror/paragraphMarkJoin.js";
|
|
20
|
-
import { carryParagraphProperties, paragraphLeftAfter, propertiesSetInBatch, recordReplacedParagraphProperties } from "../prosemirror/paragraphPropertyCarry.js";
|
|
21
|
+
import { carriedParagraphProperties, carryParagraphProperties, paragraphLeftAfter, propertiesSetInBatch, recordReplacedParagraphProperties } from "../prosemirror/paragraphPropertyCarry.js";
|
|
21
22
|
import { directParagraphSpacing, paragraphSpacingAttrPatch, paragraphSpacingEqual, paragraphSpacingFromFormatting, withDirectParagraphSpacing } from "../prosemirror/paragraphSpacing.js";
|
|
22
23
|
import { getDocumentNumbering, getDocumentNumberingInstanceIds } from "../prosemirror/plugins/documentNumbering.js";
|
|
23
24
|
import { getDocumentStyleDefinitions, getDocumentStyleResolver } from "../prosemirror/plugins/documentStyleState.js";
|
|
@@ -33,7 +34,8 @@ import { listAttrsFromNumbering, listLevelAttrPatch } from "../prosemirror/style
|
|
|
33
34
|
import { removeRowsWithoutCellsAfterBatch } from "../prosemirror/tableGridMutation.js";
|
|
34
35
|
import { isZeroWidthAnchor } from "../prosemirror/zeroWidthAnchors.js";
|
|
35
36
|
import { getFolioParaIdFromBlockId } from "../types/block-id.js";
|
|
36
|
-
import {
|
|
37
|
+
import { CANONICAL_GAP } from "../types/canonicalCapabilities.js";
|
|
38
|
+
import { BatchClaims, compareBatchTieOrder } from "./batch-claims.js";
|
|
37
39
|
import { stripBlockIdentityAttrs } from "./block-identity.js";
|
|
38
40
|
import { describeCharacterSplit } from "./character-boundaries.js";
|
|
39
41
|
import { buildCleanBlockText, resolveCleanTextRange } from "./clean-text.js";
|
|
@@ -436,6 +438,10 @@ const preserveRunFormattingAcrossTrackedStyleChange = ({ allocateRevisionInfo, n
|
|
|
436
438
|
revisionIds
|
|
437
439
|
};
|
|
438
440
|
};
|
|
441
|
+
const appendParagraphPropertyChange = (existing, change) => {
|
|
442
|
+
if (change.info.provenance !== "suggested" && hasSerializableParagraphPropertyChange(existing)) panic("A paragraph-property write must resolve its occupied revision slot first");
|
|
443
|
+
return [...existing ?? [], change];
|
|
444
|
+
};
|
|
439
445
|
/**
|
|
440
446
|
* Apply one paragraph-property patch to a live node. A tracked patch stores
|
|
441
447
|
* the complete previous pPr: a partial snapshot cannot distinguish a property
|
|
@@ -482,7 +488,7 @@ const applyBlockParagraphProperties = ({ tr, position, node, properties, styleRe
|
|
|
482
488
|
const nextAttrs = {
|
|
483
489
|
...node.attrs,
|
|
484
490
|
...patch,
|
|
485
|
-
...change ? { _propertyChanges:
|
|
491
|
+
...change ? { _propertyChanges: appendParagraphPropertyChange(existing, change) } : {}
|
|
486
492
|
};
|
|
487
493
|
const bridgeResult = preserveRunFormatting && revisionInfo ? preserveRunFormattingAcrossTrackedStyleChange({
|
|
488
494
|
allocateRevisionInfo: revisionInfo,
|
|
@@ -560,7 +566,7 @@ const applyReplaceBlockStyleId = ({ item, tr, styleResolver, revisionInfo }) =>
|
|
|
560
566
|
const nextAttrs = {
|
|
561
567
|
...block.attrs,
|
|
562
568
|
...patch,
|
|
563
|
-
...change ? { _propertyChanges:
|
|
569
|
+
...change ? { _propertyChanges: appendParagraphPropertyChange(existing, change) } : {}
|
|
564
570
|
};
|
|
565
571
|
const bridgeResult = preserveRunFormatting && revisionInfo ? preserveRunFormattingAcrossTrackedStyleChange({
|
|
566
572
|
allocateRevisionInfo: revisionInfo,
|
|
@@ -1280,6 +1286,11 @@ const isInsertedPPrMark = (value) => typeof value === "object" && value !== null
|
|
|
1280
1286
|
const isSuggestedParagraphInsert = (paragraph) => typeof paragraph.attrs["_suggestedInsert"] === "object" && paragraph.attrs["_suggestedInsert"] !== null;
|
|
1281
1287
|
/** A paragraph mark that is a pending deletion, or a relocation's source. */
|
|
1282
1288
|
const isDeletedPPrMark = (value) => typeof value === "object" && value !== null && "kind" in value && (value.kind === "del" || value.kind === "moveFrom");
|
|
1289
|
+
const pendingParagraphMarkPropertyRefusal = {
|
|
1290
|
+
reason: "pendingParagraphMarkDeletion",
|
|
1291
|
+
canonicalRefusal: { gap: CANONICAL_GAP.publicPendingParagraphMarkProperties },
|
|
1292
|
+
message: "Resolve the pending paragraph mark deletion before editing its properties, or provide mergedParagraphProperties on the merge operation for atomic intent."
|
|
1293
|
+
};
|
|
1283
1294
|
const hasRevisionMarker = (value) => typeof value === "object" && value !== null && "revisionId" in value;
|
|
1284
1295
|
const isDeletedCell = (cell) => {
|
|
1285
1296
|
const marker = cell.attrs["cellMarker"];
|
|
@@ -1501,6 +1512,10 @@ const crossesBatchDeletion = ({ doc, from, to, batchRevisionIds }) => {
|
|
|
1501
1512
|
}
|
|
1502
1513
|
return false;
|
|
1503
1514
|
};
|
|
1515
|
+
const canRetractFinalBreak = ({ predecessor, target }) => {
|
|
1516
|
+
if (target.type !== predecessor.type) return false;
|
|
1517
|
+
return !(JSON.stringify(paragraphPropertiesBeforePendingChanges(target)) !== JSON.stringify(paragraphPropertiesSnapshot(predecessor)) && hasSerializableParagraphPropertyChange(expectParagraphAttrs(predecessor)._propertyChanges));
|
|
1518
|
+
};
|
|
1504
1519
|
/** Pending retirements, read after the merge has mapped any inserted separator. */
|
|
1505
1520
|
const pendingRemovedFinalBreakPositions = (tr, deletions) => {
|
|
1506
1521
|
const positions = /* @__PURE__ */ new Set();
|
|
@@ -1512,6 +1527,92 @@ const pendingRemovedFinalBreakPositions = (tr, deletions) => {
|
|
|
1512
1527
|
}
|
|
1513
1528
|
return positions;
|
|
1514
1529
|
};
|
|
1530
|
+
/** An unoccupied final carrier takes admissible writes from the finished batch. */
|
|
1531
|
+
const finalParagraphCarry = ({ tr, at, target, predecessor, batchRevisionIds, styleResolver, numbering }) => {
|
|
1532
|
+
const { node: previous, position } = predecessor;
|
|
1533
|
+
const beforeBatch = hasSerializableParagraphPropertyChange(expectParagraphAttrs(target)._propertyChanges) ? resolveParagraphChangeAttrs({
|
|
1534
|
+
node: previous,
|
|
1535
|
+
mode: "reject",
|
|
1536
|
+
boundaryCovered: true,
|
|
1537
|
+
revisionSet: batchRevisionIds,
|
|
1538
|
+
styleResolver,
|
|
1539
|
+
numbering
|
|
1540
|
+
}) : null;
|
|
1541
|
+
return {
|
|
1542
|
+
source: beforeBatch ? previous.type.create(beforeBatch, previous.content, previous.marks) : previous,
|
|
1543
|
+
keep: crossesBatchDeletion({
|
|
1544
|
+
doc: tr.doc,
|
|
1545
|
+
from: position + previous.nodeSize,
|
|
1546
|
+
to: at,
|
|
1547
|
+
batchRevisionIds
|
|
1548
|
+
}) ? /* @__PURE__ */ new Set() : propertiesSetInBatch(target, batchRevisionIds)
|
|
1549
|
+
};
|
|
1550
|
+
};
|
|
1551
|
+
/** Deferred retirement still owns a slot before a later explicit formatting merge. */
|
|
1552
|
+
const hasDeferredParagraphPropertyWrite = ({ tr, deletions, targets, mergedPropertyTargets, batchRevisionIds, styleResolver, numbering }) => {
|
|
1553
|
+
for (const deletion of deletions) {
|
|
1554
|
+
const at = tr.mapping.slice(deletion.mappedFrom).map(deletion.position);
|
|
1555
|
+
const target = tr.doc.nodeAt(at);
|
|
1556
|
+
if (!target) continue;
|
|
1557
|
+
const predecessor = finalParagraphPredecessor(tr.doc, at);
|
|
1558
|
+
if (!predecessor) continue;
|
|
1559
|
+
const mark = predecessor.node.attrs["pPrMark"];
|
|
1560
|
+
if (mark == null && mergedPropertyTargets.some(({ position, mappedFrom }) => {
|
|
1561
|
+
const mapped = tr.mapping.slice(mappedFrom).mapResult(position);
|
|
1562
|
+
return !mapped.deleted && mapped.pos === at;
|
|
1563
|
+
})) continue;
|
|
1564
|
+
const writeTarget = mark == null ? target : tr.doc.nodeAt(predecessor.position + predecessor.node.nodeSize);
|
|
1565
|
+
if (!writeTarget || !targets.includes(writeTarget)) continue;
|
|
1566
|
+
if (mark != null && !(isInsertedPPrMark(mark) && canRetractFinalBreak({
|
|
1567
|
+
predecessor: predecessor.node,
|
|
1568
|
+
target: writeTarget
|
|
1569
|
+
}))) continue;
|
|
1570
|
+
const transfer = mark == null ? finalParagraphCarry({
|
|
1571
|
+
tr,
|
|
1572
|
+
at,
|
|
1573
|
+
target,
|
|
1574
|
+
predecessor,
|
|
1575
|
+
batchRevisionIds,
|
|
1576
|
+
styleResolver,
|
|
1577
|
+
numbering
|
|
1578
|
+
}) : {
|
|
1579
|
+
source: predecessor.node,
|
|
1580
|
+
keep: propertiesSetInBatch(writeTarget, batchRevisionIds)
|
|
1581
|
+
};
|
|
1582
|
+
if (JSON.stringify(paragraphPropertiesSnapshot(writeTarget)) !== JSON.stringify(carriedParagraphProperties({
|
|
1583
|
+
...transfer,
|
|
1584
|
+
target: writeTarget
|
|
1585
|
+
}))) return true;
|
|
1586
|
+
}
|
|
1587
|
+
return false;
|
|
1588
|
+
};
|
|
1589
|
+
/** The paragraph a merge leaves owns its properties, even across pending deleted breaks. */
|
|
1590
|
+
const paragraphPropertyRevisionTargets = ({ item, tr, deletedFinalParagraphs }) => {
|
|
1591
|
+
const position = tr.mapping.map(item.blockFrom, item.operation.type === "replaceBlock" ? -1 : 1);
|
|
1592
|
+
const source = tr.doc.nodeAt(position) ?? item.blockNode;
|
|
1593
|
+
const targets = source.type.name === "paragraph" ? [source] : [];
|
|
1594
|
+
if (item.operation.type !== "mergeBlockWithNext") return targets;
|
|
1595
|
+
const removedBreakPositions = pendingRemovedFinalBreakPositions(tr, deletedFinalParagraphs);
|
|
1596
|
+
for (const deletion of deletedFinalParagraphs) {
|
|
1597
|
+
const at = tr.mapping.slice(deletion.mappedFrom).map(deletion.position);
|
|
1598
|
+
const predecessor = finalParagraphPredecessor(tr.doc, at);
|
|
1599
|
+
if (!predecessor || !isInsertedPPrMark(predecessor.node.attrs["pPrMark"])) continue;
|
|
1600
|
+
const target = tr.doc.nodeAt(predecessor.position + predecessor.node.nodeSize);
|
|
1601
|
+
if (!target) continue;
|
|
1602
|
+
if (canRetractFinalBreak({
|
|
1603
|
+
predecessor: predecessor.node,
|
|
1604
|
+
target
|
|
1605
|
+
})) removedBreakPositions.add(predecessor.position);
|
|
1606
|
+
}
|
|
1607
|
+
const survivorPosition = paragraphLeftAfter({
|
|
1608
|
+
doc: tr.doc,
|
|
1609
|
+
paragraphPos: position,
|
|
1610
|
+
removedBreakPositions
|
|
1611
|
+
});
|
|
1612
|
+
const survivor = survivorPosition === null ? null : tr.doc.nodeAt(survivorPosition);
|
|
1613
|
+
if (survivor?.type.name === "paragraph") targets.push(survivor);
|
|
1614
|
+
return targets;
|
|
1615
|
+
};
|
|
1515
1616
|
/**
|
|
1516
1617
|
* Finish the tracked deletion of every paragraph a container ends with.
|
|
1517
1618
|
*
|
|
@@ -1562,21 +1663,21 @@ const withRetiredFinalParagraphs = ({ tr, deletions, mergedPropertyTargets, appl
|
|
|
1562
1663
|
...revisionExtras
|
|
1563
1664
|
}
|
|
1564
1665
|
});
|
|
1565
|
-
const beforeBatch = resolveParagraphChangeAttrs({
|
|
1566
|
-
node: previous,
|
|
1567
|
-
mode: "reject",
|
|
1568
|
-
boundaryCovered: true,
|
|
1569
|
-
revisionSet: batchRevisionIds,
|
|
1570
|
-
styleResolver,
|
|
1571
|
-
numbering
|
|
1572
|
-
});
|
|
1573
1666
|
if (!mergedPropertyTargets.some(({ position: target, mappedFrom }) => {
|
|
1574
1667
|
const mapped = tr.mapping.slice(mappedFrom).mapResult(target);
|
|
1575
1668
|
return !mapped.deleted && mapped.pos === at;
|
|
1576
1669
|
})) carryParagraphProperties({
|
|
1577
1670
|
tr,
|
|
1578
1671
|
position: at,
|
|
1579
|
-
|
|
1672
|
+
...finalParagraphCarry({
|
|
1673
|
+
tr,
|
|
1674
|
+
at,
|
|
1675
|
+
target: emptied,
|
|
1676
|
+
predecessor,
|
|
1677
|
+
batchRevisionIds,
|
|
1678
|
+
styleResolver,
|
|
1679
|
+
numbering
|
|
1680
|
+
}),
|
|
1580
1681
|
styleResolver,
|
|
1581
1682
|
numbering,
|
|
1582
1683
|
revision: {
|
|
@@ -1584,13 +1685,7 @@ const withRetiredFinalParagraphs = ({ tr, deletions, mergedPropertyTargets, appl
|
|
|
1584
1685
|
author,
|
|
1585
1686
|
date,
|
|
1586
1687
|
...revisionExtras
|
|
1587
|
-
}
|
|
1588
|
-
keep: crossesBatchDeletion({
|
|
1589
|
-
doc: tr.doc,
|
|
1590
|
-
from: position + previous.nodeSize,
|
|
1591
|
-
to: at,
|
|
1592
|
-
batchRevisionIds
|
|
1593
|
-
}) ? /* @__PURE__ */ new Set() : propertiesSetInBatch(emptied, batchRevisionIds)
|
|
1688
|
+
}
|
|
1594
1689
|
});
|
|
1595
1690
|
resolvedOperationIds.add(operationId);
|
|
1596
1691
|
addedRevisions.push({
|
|
@@ -1601,11 +1696,10 @@ const withRetiredFinalParagraphs = ({ tr, deletions, mergedPropertyTargets, appl
|
|
|
1601
1696
|
}
|
|
1602
1697
|
if (isInsertedPPrMark(mark)) {
|
|
1603
1698
|
const following = tr.doc.nodeAt(position + previous.nodeSize);
|
|
1604
|
-
if (following
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
if (formattingChanges && hasSerializableParagraphPropertyChange(existing)) continue;
|
|
1699
|
+
if (!following || !canRetractFinalBreak({
|
|
1700
|
+
predecessor: previous,
|
|
1701
|
+
target: following
|
|
1702
|
+
})) continue;
|
|
1609
1703
|
joinAtParagraphMark({
|
|
1610
1704
|
tr,
|
|
1611
1705
|
paragraphPos: position,
|
|
@@ -2148,6 +2242,7 @@ const applyFolioAIEditOperationsInternal = ({ view, snapshot, operations: reques
|
|
|
2148
2242
|
skipped.push({
|
|
2149
2243
|
id: operation.id,
|
|
2150
2244
|
reason: resolution.reason,
|
|
2245
|
+
...resolution.canonicalRefusal !== void 0 && { canonicalRefusal: resolution.canonicalRefusal },
|
|
2151
2246
|
...resolution.message !== void 0 && { message: resolution.message }
|
|
2152
2247
|
});
|
|
2153
2248
|
continue;
|
|
@@ -2323,7 +2418,7 @@ const applyFolioAIEditOperationsInternal = ({ view, snapshot, operations: reques
|
|
|
2323
2418
|
if (leftCellShape.tablePosition !== rightCellShape.tablePosition) return rightCellShape.tablePosition - leftCellShape.tablePosition;
|
|
2324
2419
|
if (leftCellShape.rectangle.bottom !== rightCellShape.rectangle.bottom) return rightCellShape.rectangle.bottom - leftCellShape.rectangle.bottom;
|
|
2325
2420
|
if (leftCellShape.rectangle.right !== rightCellShape.rectangle.right) return rightCellShape.rectangle.right - leftCellShape.rectangle.right;
|
|
2326
|
-
return
|
|
2421
|
+
return compareBatchTieOrder(left.originalIndex, right.originalIndex);
|
|
2327
2422
|
}
|
|
2328
2423
|
const leftColumn = left.tableColumnInsertion ?? left.tableColumnDeletion;
|
|
2329
2424
|
const rightColumn = right.tableColumnInsertion ?? right.tableColumnDeletion;
|
|
@@ -2334,19 +2429,32 @@ const applyFolioAIEditOperationsInternal = ({ view, snapshot, operations: reques
|
|
|
2334
2429
|
if (leftColumn.columnIndex !== rightColumn.columnIndex) return rightColumn.columnIndex - leftColumn.columnIndex;
|
|
2335
2430
|
const leftIsInsertion = left.tableColumnInsertion !== void 0;
|
|
2336
2431
|
if (leftIsInsertion !== (right.tableColumnInsertion !== void 0)) return leftIsInsertion ? -1 : 1;
|
|
2337
|
-
return
|
|
2432
|
+
return compareBatchTieOrder(left.originalIndex, right.originalIndex);
|
|
2338
2433
|
}
|
|
2339
2434
|
if (left.from !== right.from) return right.from - left.from;
|
|
2340
|
-
return
|
|
2435
|
+
return compareBatchTieOrder(left.originalIndex, right.originalIndex);
|
|
2341
2436
|
});
|
|
2342
2437
|
for (let executionIndex = 0; executionIndex < executionOrder.length; executionIndex++) {
|
|
2343
2438
|
const item = executionOrder[executionIndex];
|
|
2344
2439
|
if (!item) panic("The operation execution index exceeded the resolved plan", { executionIndex });
|
|
2345
2440
|
continueSharedRevisionIds();
|
|
2346
2441
|
if (mode === "tracked-changes" && writesParagraphPropertyChange(item)) {
|
|
2347
|
-
const
|
|
2348
|
-
const
|
|
2349
|
-
|
|
2442
|
+
const appliedIds = new Set(applied.map(({ id }) => id));
|
|
2443
|
+
const pendingDeletions = deletedFinalParagraphs.filter(({ operationId }) => appliedIds.has(operationId));
|
|
2444
|
+
const targets = paragraphPropertyRevisionTargets({
|
|
2445
|
+
item,
|
|
2446
|
+
tr,
|
|
2447
|
+
deletedFinalParagraphs: pendingDeletions
|
|
2448
|
+
});
|
|
2449
|
+
if (targets.some((target) => hasSerializableParagraphPropertyChange(expectParagraphAttrs(target)._propertyChanges)) || item.operation.type === "mergeBlockWithNext" && hasDeferredParagraphPropertyWrite({
|
|
2450
|
+
tr,
|
|
2451
|
+
deletions: pendingDeletions,
|
|
2452
|
+
targets,
|
|
2453
|
+
mergedPropertyTargets,
|
|
2454
|
+
batchRevisionIds: new Set(applied.flatMap(({ revisionIds }) => revisionIds ?? [])),
|
|
2455
|
+
styleResolver,
|
|
2456
|
+
numbering
|
|
2457
|
+
})) {
|
|
2350
2458
|
skipped.push({
|
|
2351
2459
|
id: item.operation.id,
|
|
2352
2460
|
reason: "pendingParagraphPropertyChange"
|
|
@@ -2580,6 +2688,13 @@ const applyFolioAIEditOperationsInternal = ({ view, snapshot, operations: reques
|
|
|
2580
2688
|
case "replaceBlock": {
|
|
2581
2689
|
if (!isResolvedReplaceBlockOperation(item)) panic("Resolved replaceBlock operation lost its impact discriminator");
|
|
2582
2690
|
const { changesStyle, changesText } = REPLACE_BLOCK_IMPACT[item.replaceBlockImpact];
|
|
2691
|
+
if (changesStyle && isDeletedPPrMark(tr.doc.nodeAt(tr.mapping.map(item.blockFrom, -1))?.attrs["pPrMark"])) {
|
|
2692
|
+
skipped.push({
|
|
2693
|
+
id: item.operation.id,
|
|
2694
|
+
...pendingParagraphMarkPropertyRefusal
|
|
2695
|
+
});
|
|
2696
|
+
continue;
|
|
2697
|
+
}
|
|
2583
2698
|
const revisionIdDelete = operationRevisionSeed;
|
|
2584
2699
|
const revisionIdInsert = changesText ? operationRevisionSeed + 1 : operationRevisionSeed;
|
|
2585
2700
|
const revisionIdBackgroundSeed = changesText ? operationRevisionSeed + 2 : operationRevisionSeed;
|
|
@@ -3072,9 +3187,21 @@ const applyFolioAIEditOperationsInternal = ({ view, snapshot, operations: reques
|
|
|
3072
3187
|
...isPairedMove(item.operation.moveId) && { moveKind: "moveFrom" },
|
|
3073
3188
|
...trackedRevisionExtras
|
|
3074
3189
|
});
|
|
3075
|
-
|
|
3190
|
+
addTrackedDeletionMark({
|
|
3191
|
+
insertionPolicy: "preserve-pending",
|
|
3192
|
+
tr,
|
|
3193
|
+
from: item.from,
|
|
3194
|
+
to: item.to,
|
|
3195
|
+
mark: deletionMark
|
|
3196
|
+
});
|
|
3076
3197
|
const atomRanges = undeletedContentAtomRanges(tr, item.blockFrom);
|
|
3077
|
-
for (const { from, to } of atomRanges)
|
|
3198
|
+
for (const { from, to } of atomRanges) addTrackedDeletionMark({
|
|
3199
|
+
insertionPolicy: "preserve-pending",
|
|
3200
|
+
tr,
|
|
3201
|
+
from,
|
|
3202
|
+
to,
|
|
3203
|
+
mark: deletionMark
|
|
3204
|
+
});
|
|
3078
3205
|
for (const anchorId of textBoxAnchorIdsBetween(tr.doc, tr.mapping.map(item.blockFrom), tr.mapping.map(item.blockTo))) deletedTextBoxAnchorIds.add(anchorId);
|
|
3079
3206
|
encloseWholeControls({
|
|
3080
3207
|
tr,
|
|
@@ -3312,6 +3439,13 @@ const applyFolioAIEditOperationsInternal = ({ view, snapshot, operations: reques
|
|
|
3312
3439
|
continue;
|
|
3313
3440
|
}
|
|
3314
3441
|
const blockPosition = mapped.pos;
|
|
3442
|
+
if (isDeletedPPrMark(liveBlock.attrs["pPrMark"])) {
|
|
3443
|
+
skipped.push({
|
|
3444
|
+
id: item.operation.id,
|
|
3445
|
+
...pendingParagraphMarkPropertyRefusal
|
|
3446
|
+
});
|
|
3447
|
+
continue;
|
|
3448
|
+
}
|
|
3315
3449
|
const appliedProperties = applyBlockParagraphProperties({
|
|
3316
3450
|
tr,
|
|
3317
3451
|
position: blockPosition,
|
|
@@ -3360,12 +3494,18 @@ const applyFolioAIEditOperationsInternal = ({ view, snapshot, operations: reques
|
|
|
3360
3494
|
appliedRevisionIds = [revisionIdMark];
|
|
3361
3495
|
if (item.to > item.from && deletionType) {
|
|
3362
3496
|
const revisionIdSeparator = operationRevisionSeed++;
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3497
|
+
addTrackedDeletionMark({
|
|
3498
|
+
insertionPolicy: "preserve-pending",
|
|
3499
|
+
tr,
|
|
3500
|
+
from: item.from,
|
|
3501
|
+
to: item.to,
|
|
3502
|
+
mark: deletionType.create({
|
|
3503
|
+
revisionId: revisionIdSeparator,
|
|
3504
|
+
author,
|
|
3505
|
+
date,
|
|
3506
|
+
...trackedRevisionExtras
|
|
3507
|
+
})
|
|
3508
|
+
});
|
|
3369
3509
|
appliedRevisionIds.push(revisionIdSeparator);
|
|
3370
3510
|
}
|
|
3371
3511
|
tr = tr.split(item.from);
|
|
@@ -3861,7 +4001,13 @@ const applyTextReplacement = ({ tr, item, mode, author, date, revisionIdDelete,
|
|
|
3861
4001
|
if (commentMark) nextTr = nextTr.addMark(inserted.start, inserted.end, commentMark);
|
|
3862
4002
|
}
|
|
3863
4003
|
if (item.to > item.from && deletionType) {
|
|
3864
|
-
|
|
4004
|
+
addTrackedDeletionMark({
|
|
4005
|
+
insertionPolicy: "preserve-pending",
|
|
4006
|
+
tr: nextTr,
|
|
4007
|
+
from: item.from,
|
|
4008
|
+
to: item.to,
|
|
4009
|
+
mark: deletionType.create(delAttrs)
|
|
4010
|
+
});
|
|
3865
4011
|
if (commentMark && replacement.length === 0) nextTr = nextTr.addMark(item.from, item.to, commentMark);
|
|
3866
4012
|
}
|
|
3867
4013
|
return nextTr;
|
|
@@ -4353,7 +4499,13 @@ const applyMinimalTrackedReplacement = ({ tr, item, noteReferences, replacement,
|
|
|
4353
4499
|
removedFrom = first.from;
|
|
4354
4500
|
marks = addCarriedMarks(inheritedReplacementMarks(doc, styleSource.from, styleSource.to), surveyReplacedAnnotations(doc, first.from, last.to).carried);
|
|
4355
4501
|
for (const piece of change.pieces) {
|
|
4356
|
-
|
|
4502
|
+
addTrackedDeletionMark({
|
|
4503
|
+
insertionPolicy: "preserve-pending",
|
|
4504
|
+
tr: nextTr,
|
|
4505
|
+
from: piece.from,
|
|
4506
|
+
to: piece.to,
|
|
4507
|
+
mark: deletion
|
|
4508
|
+
});
|
|
4357
4509
|
if (commentMark) nextTr = nextTr.addMark(piece.from, piece.to, commentMark);
|
|
4358
4510
|
}
|
|
4359
4511
|
}
|
|
@@ -4889,17 +5041,23 @@ const resolveOperationTarget = ({ snapshot, operation, liveBlocks, liveBlocksByP
|
|
|
4889
5041
|
}
|
|
4890
5042
|
};
|
|
4891
5043
|
}
|
|
4892
|
-
if (operation.type === "setBlockParagraphProperties")
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
5044
|
+
if (operation.type === "setBlockParagraphProperties") {
|
|
5045
|
+
if (isDeletedPPrMark(blockNode.attrs["pPrMark"])) return {
|
|
5046
|
+
type: "skip",
|
|
5047
|
+
...pendingParagraphMarkPropertyRefusal
|
|
5048
|
+
};
|
|
5049
|
+
return {
|
|
5050
|
+
type: "resolved",
|
|
5051
|
+
operation: {
|
|
5052
|
+
operation,
|
|
5053
|
+
from: blockFrom,
|
|
5054
|
+
to: blockTo,
|
|
5055
|
+
blockFrom,
|
|
5056
|
+
blockTo,
|
|
5057
|
+
blockNode
|
|
5058
|
+
}
|
|
5059
|
+
};
|
|
5060
|
+
}
|
|
4903
5061
|
if (operation.type === "splitBlock") {
|
|
4904
5062
|
const separator = operation.separator ?? "";
|
|
4905
5063
|
const startOffset = operation.offset;
|
|
@@ -4965,6 +5123,10 @@ const resolveOperationTarget = ({ snapshot, operation, liveBlocks, liveBlocksByP
|
|
|
4965
5123
|
if (operation.type === "deleteBlock" || operation.type === "replaceBlock") {
|
|
4966
5124
|
const replaceChangesText = operation.type === "replaceBlock" && operation.text !== currentText;
|
|
4967
5125
|
const replaceChangesStyle = operation.type === "replaceBlock" && operation.styleId !== void 0 && operation.styleId !== (expectParagraphAttrs(blockNode).styleId ?? null);
|
|
5126
|
+
if (replaceChangesStyle && isDeletedPPrMark(blockNode.attrs["pPrMark"])) return {
|
|
5127
|
+
type: "skip",
|
|
5128
|
+
...pendingParagraphMarkPropertyRefusal
|
|
5129
|
+
};
|
|
4968
5130
|
if (replaceChangesText && cleanBlock.structuralBoundaries.some((boundary) => boundary.type !== "field" && boundary.type !== "noteReference")) return {
|
|
4969
5131
|
type: "skip",
|
|
4970
5132
|
reason: "unsupportedBlock"
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
* Positions are the ones the batch resolved against. A block is keyed by the
|
|
22
22
|
* position before its node.
|
|
23
23
|
*/
|
|
24
|
+
/** Equal snapshot coordinates execute in reverse input order. */
|
|
25
|
+
declare const compareBatchTieOrder: (leftIndex: number, rightIndex: number) => number;
|
|
24
26
|
type PositionRange = {
|
|
25
27
|
from: number;
|
|
26
28
|
to: number;
|
|
@@ -142,4 +144,4 @@ declare class BatchClaims {
|
|
|
142
144
|
add(operationId: string, claim: BatchClaim): void;
|
|
143
145
|
}
|
|
144
146
|
//#endregion
|
|
145
|
-
export { BatchClaim, BatchClaims };
|
|
147
|
+
export { BatchClaim, BatchClaims, compareBatchTieOrder };
|
|
@@ -1,4 +1,28 @@
|
|
|
1
1
|
//#region src/ai-edits/batch-claims.ts
|
|
2
|
+
/**
|
|
3
|
+
* Which operations of one batch may not share their targets.
|
|
4
|
+
*
|
|
5
|
+
* A batch resolves every operation against the document as it was read and
|
|
6
|
+
* applies them from the end of the document backwards, so an operation never
|
|
7
|
+
* moves the positions an earlier-placed one resolved to. That holds only while
|
|
8
|
+
* the operations' targets are disjoint. Two operations on the same stretch of
|
|
9
|
+
* text, or an operation inside a paragraph another one deletes, rewrites,
|
|
10
|
+
* splits or merges away, are applied against coordinates the first one has
|
|
11
|
+
* already invalidated — and the second then edits whatever now sits there,
|
|
12
|
+
* which can be a paragraph neither operation named.
|
|
13
|
+
*
|
|
14
|
+
* Each operation therefore states what it claims before anything is applied,
|
|
15
|
+
* and the later of two operations whose claims conflict is refused
|
|
16
|
+
* (`overlappingOperation`). The caller re-reads the document after the batch
|
|
17
|
+
* and sends the refused operation again against the result. What remains
|
|
18
|
+
* applies exactly as the same operations applied one at a time, from the end
|
|
19
|
+
* of the document backwards, would.
|
|
20
|
+
*
|
|
21
|
+
* Positions are the ones the batch resolved against. A block is keyed by the
|
|
22
|
+
* position before its node.
|
|
23
|
+
*/
|
|
24
|
+
/** Equal snapshot coordinates execute in reverse input order. */
|
|
25
|
+
const compareBatchTieOrder = (leftIndex, rightIndex) => rightIndex - leftIndex;
|
|
2
26
|
const blockRolesOf = (claim) => {
|
|
3
27
|
switch (claim.type) {
|
|
4
28
|
case "text":
|
|
@@ -272,4 +296,4 @@ var BatchClaims = class {
|
|
|
272
296
|
}
|
|
273
297
|
};
|
|
274
298
|
//#endregion
|
|
275
|
-
export { BatchClaims };
|
|
299
|
+
export { BatchClaims, compareBatchTieOrder };
|
|
@@ -5,8 +5,7 @@ import { importReferencedStyleDefinitions } from "../compare/style-resources.js"
|
|
|
5
5
|
import { applyFolioDocumentOperations } from "../document-operations.js";
|
|
6
6
|
import { applyReplyThreadMarkers } from "../docx/commentReplyMarkers.js";
|
|
7
7
|
import { rebindDrawingImageRelationship } from "../docx/drawingRelationships.js";
|
|
8
|
-
import {
|
|
9
|
-
import { getHeaderFooterText } from "../docx/headerFooterParser.js";
|
|
8
|
+
import { isSeparatorEndnote, isSeparatorFootnote } from "../docx/footnoteParser.js";
|
|
10
9
|
import { createNumberingIdAllocator } from "../docx/numberingIds.js";
|
|
11
10
|
import { getCachedNumberingMap } from "../docx/numberingParser.js";
|
|
12
11
|
import { recreateProseNodeWithParagraphPropertySource, transferProseParagraphPropertySource } from "../docx/paragraphPropertySource.js";
|
|
@@ -15,6 +14,7 @@ import { createReply } from "../docx/replyToComment.js";
|
|
|
15
14
|
import { repackDocx } from "../docx/rezip.js";
|
|
16
15
|
import { sectionReferenceHistory } from "../docx/sectionReferenceHistory.js";
|
|
17
16
|
import { attemptSelectiveSave } from "../docx/selectiveSave.js";
|
|
17
|
+
import { getEndnoteText, getFootnoteText, getHeaderFooterText } from "../docx/storyPlainText.js";
|
|
18
18
|
import { pluginsForHeadlessRevisionResolution } from "../internal/headlessRevisionResolutionGuard.js";
|
|
19
19
|
import { withTrackedSectionEndpointRemoval } from "../internal/sectionEndpointResolution.js";
|
|
20
20
|
import { captureSectionReferenceInventory, resolvedSectionReferenceLosses, withSectionReferenceResolution } from "../internal/sectionReferenceResolution.js";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { addTrackedDeletionMark } from "../prosemirror/addTrackedDeletionMark.js";
|
|
1
2
|
import { markStructuralChange } from "../prosemirror/extensions/features/ParagraphChangeTrackerExtension.js";
|
|
2
3
|
import { markRowsEmptiedInBatch, reconcileTableGridAfterColumnInsertion, reconcileTableGridAfterColumnRemoval, removeRowsWithoutCells, removeTableRow } from "../prosemirror/tableGridMutation.js";
|
|
3
4
|
import { stripBlockIdentityAttrs } from "./block-identity.js";
|
|
@@ -130,7 +131,7 @@ const markTableRowContent = ({ tr, rowPosition, kind, revision }) => {
|
|
|
130
131
|
if (!node.isInline) return true;
|
|
131
132
|
if (node.marks.some(isTrackedChangeMark)) {
|
|
132
133
|
wholeRowMarkable = false;
|
|
133
|
-
if (kind === "insertion"
|
|
134
|
+
if (kind === "insertion") return false;
|
|
134
135
|
}
|
|
135
136
|
const from = contentFrom + offset;
|
|
136
137
|
markable.push({
|
|
@@ -140,10 +141,23 @@ const markTableRowContent = ({ tr, rowPosition, kind, revision }) => {
|
|
|
140
141
|
return false;
|
|
141
142
|
});
|
|
142
143
|
if (wholeRowMarkable) {
|
|
143
|
-
|
|
144
|
+
if (kind === "deletion") addTrackedDeletionMark({
|
|
145
|
+
insertionPolicy: "preserve-pending",
|
|
146
|
+
tr,
|
|
147
|
+
from: contentFrom,
|
|
148
|
+
to: rowPosition + row.nodeSize - 1,
|
|
149
|
+
mark
|
|
150
|
+
});
|
|
151
|
+
else tr.addMark(contentFrom, rowPosition + row.nodeSize - 1, mark);
|
|
144
152
|
return;
|
|
145
153
|
}
|
|
146
|
-
for (const range of markable)
|
|
154
|
+
for (const range of markable) if (kind === "deletion") addTrackedDeletionMark({
|
|
155
|
+
insertionPolicy: "preserve-pending",
|
|
156
|
+
tr,
|
|
157
|
+
...range,
|
|
158
|
+
mark
|
|
159
|
+
});
|
|
160
|
+
else tr.addMark(range.from, range.to, mark);
|
|
147
161
|
};
|
|
148
162
|
const isTrackedChangeMark = (mark) => mark.type.name === "insertion" || mark.type.name === "deletion";
|
|
149
163
|
const isRowSpanningCell = (node) => {
|
package/dist/ai-edits/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
import { CanonicalGap } from "../types/canonicalCapabilities.js";
|
|
2
3
|
import { FolioContentBlock, FolioContentInlineBooleanProperty, FolioContentInlineFormatting, FolioContentInlineFormattingPatch, FolioContentListReference, FolioContentParagraphIndentation, FolioContentParagraphKind, FolioContentParagraphSpacing, FolioContentRun, FolioContentSnapshot, FolioContentTableLocation } from "../compare/content-types.js";
|
|
3
4
|
import { ListKind } from "../docx/listNumberingInstances.js";
|
|
4
5
|
//#region src/ai-edits/types.d.ts
|
|
@@ -656,7 +657,9 @@ type FolioAIEditSkipReason = "missingBlock" | "changedBlock" | "ambiguousFind" |
|
|
|
656
657
|
* deletion is accepted. Reject that deletion first, or insert a new block
|
|
657
658
|
* next to it.
|
|
658
659
|
*/
|
|
659
|
-
"pendingDeletion"
|
|
660
|
+
"pendingDeletion" |
|
|
661
|
+
/** Resolve the removed paragraph mark before editing its properties separately. */
|
|
662
|
+
"pendingParagraphMarkDeletion";
|
|
660
663
|
type FolioAIEditAppliedOperation = {
|
|
661
664
|
id: string;
|
|
662
665
|
commentId?: number;
|
|
@@ -689,6 +692,9 @@ type FolioAIEditAppliedOperation = {
|
|
|
689
692
|
type FolioAIEditSkippedOperation = {
|
|
690
693
|
id: string;
|
|
691
694
|
reason: FolioAIEditSkipReason;
|
|
695
|
+
canonicalRefusal?: {
|
|
696
|
+
gap: CanonicalGap;
|
|
697
|
+
};
|
|
692
698
|
/**
|
|
693
699
|
* What exactly was wrong when the reason alone does not say: the values a
|
|
694
700
|
* `payloadDoesNotFit` skip could not place, the earlier operation an
|
|
@@ -1,6 +1,19 @@
|
|
|
1
|
+
import { addTrackedDeletionMark } from "../prosemirror/addTrackedDeletionMark.js";
|
|
1
2
|
import { mintRevisionId, seedRevisionIdsFromDoc } from "../prosemirror/plugins/revisionIds.js";
|
|
2
3
|
import { resolveSuggestionAnchor } from "./conflict.js";
|
|
3
4
|
//#region src/ai-suggestions/apply.ts
|
|
5
|
+
/**
|
|
6
|
+
* Apply AI suggestions to the document.
|
|
7
|
+
*
|
|
8
|
+
* Two modes:
|
|
9
|
+
* - "direct": replace text in place.
|
|
10
|
+
* - "tracked-changes": insertion + deletion marks, attributed to the
|
|
11
|
+
* configured author. Reuses the editor's existing tracked-change
|
|
12
|
+
* schema and resolution commands.
|
|
13
|
+
*
|
|
14
|
+
* Apply is always preceded by anchor resolution; stale suggestions are
|
|
15
|
+
* skipped and reported back to the caller.
|
|
16
|
+
*/
|
|
4
17
|
function applySuggestions(options) {
|
|
5
18
|
const { view, suggestions, mode, author } = options;
|
|
6
19
|
const applied = [];
|
|
@@ -51,7 +64,13 @@ function applySuggestions(options) {
|
|
|
51
64
|
tr.insertText(suggestion.suggestedText, to, to);
|
|
52
65
|
tr.addMark(to, to + suggestion.suggestedText.length, insertionType.create(attrs));
|
|
53
66
|
}
|
|
54
|
-
if (to > from)
|
|
67
|
+
if (to > from) addTrackedDeletionMark({
|
|
68
|
+
insertionPolicy: "preserve-pending",
|
|
69
|
+
tr,
|
|
70
|
+
from,
|
|
71
|
+
to,
|
|
72
|
+
mark: deletionType.create(attrs)
|
|
73
|
+
});
|
|
55
74
|
applied.push(suggestion.id);
|
|
56
75
|
}
|
|
57
76
|
}
|
package/dist/compare/compare.js
CHANGED
|
@@ -486,6 +486,7 @@ const COMPARE_SKIP_DISPOSITION = {
|
|
|
486
486
|
staleRange: "fatal",
|
|
487
487
|
emptyOperation: "unwritable",
|
|
488
488
|
pendingParagraphPropertyChange: "unwritable",
|
|
489
|
+
pendingParagraphMarkDeletion: "unwritable",
|
|
489
490
|
pendingRunPropertyChange: "unwritable",
|
|
490
491
|
noopOperation: "unwritable",
|
|
491
492
|
documentVersionMismatch: "fatal",
|