@stll/folio-core 0.53.0 → 0.54.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/dist/ai-edits/apply.js +415 -166
- package/dist/ai-edits/batch-claims.d.ts +21 -6
- package/dist/ai-edits/batch-claims.js +47 -16
- package/dist/ai-edits/headless.d.ts +20 -0
- package/dist/ai-edits/headless.js +140 -11
- package/dist/ai-edits/pending-suggestions.js +1 -1
- package/dist/ai-edits/read.d.ts +5 -3
- package/dist/ai-edits/read.js +97 -47
- package/dist/ai-edits/revisionStretches.d.ts +17 -0
- package/dist/ai-edits/revisionStretches.js +80 -0
- package/dist/ai-edits/snapshot.js +3 -2
- package/dist/ai-edits/table-cell-mutations.d.ts +3 -1
- package/dist/ai-edits/table-cell-mutations.js +2 -1
- package/dist/ai-edits/table-row-column-mutations.d.ts +6 -1
- package/dist/ai-edits/table-row-column-mutations.js +27 -10
- package/dist/compare/content-alignment.d.ts +5 -1
- package/dist/compare/content-alignment.js +39 -32
- package/dist/compare/inline-provenance.js +1 -1
- package/dist/controller/layoutPipeline.js +3 -2
- package/dist/docx/archiveInflation.d.ts +127 -0
- package/dist/docx/archiveInflation.js +181 -0
- package/dist/docx/metadataPrivacy.js +24 -1
- package/dist/docx/noteReferenceMark.d.ts +15 -0
- package/dist/docx/noteReferenceMark.js +48 -0
- package/dist/docx/paragraphParser.js +5 -3
- package/dist/docx/paragraphPropertySource.d.ts +1 -1
- package/dist/docx/paragraphPropertySource.js +4 -2
- package/dist/docx/parser.js +2 -2
- package/dist/docx/rezip.js +4 -2
- package/dist/docx/selectiveXmlPatch.d.ts +3 -1
- package/dist/docx/selectiveXmlPatch.js +81 -3
- package/dist/docx/server/boundedArchive.d.ts +8 -13
- package/dist/docx/server/boundedArchive.js +70 -59
- package/dist/docx/server/extractDocxText.d.ts +8 -2
- package/dist/docx/server/extractDocxText.js +2 -2
- package/dist/docx/server/validateDocxConformance.d.ts +1 -1
- package/dist/docx/server/validateDocxConformance.js +1 -0
- package/dist/docx/unzip.d.ts +19 -2
- package/dist/docx/unzip.js +135 -24
- package/dist/docx/verticalMergeProjection.d.ts +17 -0
- package/dist/docx/verticalMergeProjection.js +120 -0
- package/dist/fonts/embeddedFonts.js +1 -1
- package/dist/i18n/messages/catalogs.gen.d.ts +34 -34
- package/dist/i18n/messages/catalogs.gen.js +34 -34
- package/dist/i18n/messages/messages.gen.d.ts +2 -2
- package/dist/internal/wholeStoryRevisionResolution.js +95 -25
- package/dist/layout-engine/measure/measureParagraph.js +2 -2
- package/dist/layout-engine/measure/paragraphMeasureShared.d.ts +12 -1
- package/dist/layout-engine/measure/paragraphMeasureShared.js +14 -1
- package/dist/markdown/escape.d.ts +2 -2
- package/dist/markdown/escape.js +4 -5
- package/dist/markdown/renderBlock.js +91 -25
- package/dist/markdown/renderRuns.d.ts +10 -1
- package/dist/markdown/renderRuns.js +320 -59
- package/dist/prosemirror/clearRunColor.d.ts +6 -0
- package/dist/prosemirror/clearRunColor.js +46 -0
- package/dist/prosemirror/commands/comments.js +62 -22
- package/dist/prosemirror/commands/formatPainter.js +1 -1
- package/dist/prosemirror/commands/hyperlink.js +2 -1
- package/dist/prosemirror/commands/propertyChangeScope.d.ts +3 -2
- package/dist/prosemirror/commands/propertyChangeScope.js +28 -4
- package/dist/prosemirror/commands/resolveAllTableChanges.js +40 -41
- package/dist/prosemirror/commands/resolveParagraphProperties.js +33 -8
- package/dist/prosemirror/commands/tableCellMergeResolution.d.ts +7 -1
- package/dist/prosemirror/commands/tableCellMergeResolution.js +39 -20
- package/dist/prosemirror/commands/tableMergeFoldDecisions.d.ts +61 -0
- package/dist/prosemirror/commands/tableMergeFoldDecisions.js +79 -0
- package/dist/prosemirror/containerFinalParagraph.d.ts +11 -5
- package/dist/prosemirror/containerFinalParagraph.js +7 -6
- package/dist/prosemirror/conversion/fromProseDoc.d.ts +2 -13
- package/dist/prosemirror/conversion/fromProseDoc.js +12 -590
- package/dist/prosemirror/conversion/toProseDoc.d.ts +1 -13
- package/dist/prosemirror/conversion/toProseDoc.js +28 -262
- package/dist/prosemirror/documentSchema.d.ts +8 -0
- package/dist/prosemirror/documentSchema.js +18 -0
- package/dist/prosemirror/extensions/StarterKit.js +2 -0
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +104 -63
- package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +1 -1
- package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.js +24 -3
- package/dist/prosemirror/extensions/features/JoinedRunStyleExtension.d.ts +20 -0
- package/dist/prosemirror/extensions/features/JoinedRunStyleExtension.js +43 -0
- package/dist/prosemirror/extensions/features/ListExtension.js +10 -9
- package/dist/prosemirror/extensions/features/pastedHeadingStyles.js +1 -1
- package/dist/prosemirror/extensions/features/pastedHtmlLists.js +2 -4
- package/dist/prosemirror/extensions/marks/FootnoteRefExtension.js +14 -8
- package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +8 -4
- package/dist/prosemirror/extensions/marks/StrikeExtension.js +2 -2
- package/dist/prosemirror/extensions/marks/SubscriptExtension.js +2 -2
- package/dist/prosemirror/extensions/marks/SuperscriptExtension.js +2 -2
- package/dist/prosemirror/extensions/marks/TextColorExtension.js +4 -3
- package/dist/prosemirror/extensions/marks/markUtils.d.ts +8 -6
- package/dist/prosemirror/extensions/marks/markUtils.js +17 -8
- package/dist/prosemirror/extensions/marks/noteReferenceDeletion.d.ts +3 -1
- package/dist/prosemirror/extensions/marks/noteReferenceDeletion.js +12 -1
- package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +2 -2
- package/dist/prosemirror/extensions/nodes/HardBreakExtension.js +5 -3
- package/dist/prosemirror/extensions/nodes/TableExtension.js +104 -210
- package/dist/prosemirror/extensions/types.d.ts +7 -0
- package/dist/prosemirror/hyperlinkRemoval.d.ts +9 -0
- package/dist/prosemirror/hyperlinkRemoval.js +129 -0
- package/dist/prosemirror/index.d.ts +2 -1
- package/dist/prosemirror/index.js +2 -1
- package/dist/prosemirror/listNumbering.d.ts +3 -21
- package/dist/prosemirror/listNumbering.js +24 -39
- package/dist/prosemirror/listRendering.d.ts +29 -0
- package/dist/prosemirror/listRendering.js +26 -0
- package/dist/prosemirror/markupViewNotes.d.ts +8 -0
- package/dist/prosemirror/markupViewNotes.js +49 -0
- package/dist/prosemirror/markupViewProjection.d.ts +3 -1
- package/dist/prosemirror/markupViewProjection.js +7 -2
- package/dist/prosemirror/noteReferenceReview.d.ts +77 -0
- package/dist/prosemirror/noteReferenceReview.js +332 -0
- package/dist/prosemirror/paragraphIndentation.js +5 -2
- package/dist/prosemirror/paragraphMarkJoin.d.ts +6 -4
- package/dist/prosemirror/paragraphMarkJoin.js +21 -19
- package/dist/prosemirror/paragraphPropertyCarry.d.ts +64 -0
- package/dist/prosemirror/paragraphPropertyCarry.js +155 -0
- package/dist/prosemirror/plugins/documentStyleState.d.ts +26 -0
- package/dist/prosemirror/plugins/documentStyleState.js +32 -0
- package/dist/prosemirror/plugins/documentStyles.d.ts +2 -21
- package/dist/prosemirror/plugins/documentStyles.js +66 -29
- package/dist/prosemirror/plugins/index.d.ts +2 -1
- package/dist/prosemirror/plugins/index.js +2 -1
- package/dist/prosemirror/plugins/paragraphStyleResolution.d.ts +15 -0
- package/dist/prosemirror/plugins/paragraphStyleResolution.js +230 -0
- package/dist/prosemirror/plugins/suggestionMode.d.ts +12 -2
- package/dist/prosemirror/plugins/suggestionMode.js +387 -28
- package/dist/prosemirror/plugins/templateDirectives.d.ts +6 -0
- package/dist/prosemirror/plugins/templateDirectives.js +21 -7
- package/dist/prosemirror/plugins/templatePreviewValues.js +14 -21
- package/dist/prosemirror/rebaseParagraphRunFormatting.d.ts +22 -2
- package/dist/prosemirror/rebaseParagraphRunFormatting.js +39 -13
- package/dist/prosemirror/rebaseParagraphRuns.d.ts +36 -0
- package/dist/prosemirror/rebaseParagraphRuns.js +99 -0
- package/dist/prosemirror/runFormattingFromMarks.d.ts +18 -0
- package/dist/prosemirror/runFormattingFromMarks.js +567 -0
- package/dist/prosemirror/runFormattingReconciliation.js +10 -9
- package/dist/prosemirror/schema/nodes.d.ts +2 -0
- package/dist/prosemirror/styles/paragraphStyleCascade.d.ts +59 -0
- package/dist/prosemirror/styles/paragraphStyleCascade.js +145 -0
- package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +21 -2
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +38 -1
- package/dist/prosemirror/styles/tableStyleRegions.d.ts +31 -0
- package/dist/prosemirror/styles/tableStyleRegions.js +55 -0
- package/dist/prosemirror/tableCellPaste.d.ts +74 -0
- package/dist/prosemirror/tableCellPaste.js +525 -0
- package/dist/prosemirror/tableGridMutation.d.ts +53 -14
- package/dist/prosemirror/tableGridMutation.js +166 -18
- package/dist/prosemirror/tableRunIn.d.ts +51 -0
- package/dist/prosemirror/tableRunIn.js +165 -0
- package/dist/prosemirror/textInput.js +11 -2
- package/dist/prosemirror/trackedRevisionPath.d.ts +17 -0
- package/dist/prosemirror/trackedRevisionPath.js +32 -0
- package/dist/server.d.ts +2 -2
- package/package.json +6 -6
|
@@ -7,21 +7,23 @@ import { expectFieldAttrs, expectParagraphAttrs, expectRunPropertyChangeMarkAttr
|
|
|
7
7
|
import { addedBreakCarrierBefore, finalParagraphsOf, paragraphEndsItsContainer } from "../containerFinalParagraph.js";
|
|
8
8
|
import { enclosingRevisionIds, resolutionRemovesControl, withoutResolvedEnclosures } from "../contentControlRevisions.js";
|
|
9
9
|
import { resolveEmptyFieldResultRuns } from "../emptyFieldResultRuns.js";
|
|
10
|
+
import { JOINED_RUNS_RESTYLED_META } from "../extensions/features/JoinedRunStyleExtension.js";
|
|
10
11
|
import { markChangedParagraphRanges, markStructuralChange, markTrackedSectionEndpointRemoval } from "../extensions/features/ParagraphChangeTrackerExtension.js";
|
|
11
12
|
import "../extensions/nodes/SdtExtension.js";
|
|
12
13
|
import { resolveStateStory } from "../markupViewProjection.js";
|
|
13
14
|
import { joinAtParagraphMark } from "../paragraphMarkJoin.js";
|
|
14
15
|
import { getDocumentNumbering } from "../plugins/documentNumbering.js";
|
|
15
|
-
import { getDocumentStyleResolver } from "../plugins/
|
|
16
|
-
import { setParagraphAttrsWithRebasedRunFormatting } from "../rebaseParagraphRunFormatting.js";
|
|
16
|
+
import { getDocumentStyleResolver } from "../plugins/documentStyleState.js";
|
|
17
|
+
import { rebaseParagraphRuns, setParagraphAttrsWithRebasedRunFormatting } from "../rebaseParagraphRunFormatting.js";
|
|
17
18
|
import { rejoinRunsAt } from "../rejoinRunCarriers.js";
|
|
18
19
|
import { getFolioNodeRevisionCarriers, nodePropertyRevisionSites } from "../revisionCarriers.js";
|
|
19
20
|
import { RUN_FORMATTING_MARK_NAMES } from "../runFormattingMarkNames.js";
|
|
20
21
|
import { reconstructRejectedRunFormattingMarks } from "../runPropertyChangeResolution.js";
|
|
21
|
-
import { paragraphRunStyleContextAt } from "../runStyleFormatting.js";
|
|
22
|
+
import { paragraphRunStyleContext, paragraphRunStyleContextAt } from "../runStyleFormatting.js";
|
|
22
23
|
import { getTableCellMergeChange } from "../tableCellMergeRevision.js";
|
|
23
24
|
import { isTableCellRetainedInReviewView } from "../tableCellRevisionVisibility.js";
|
|
24
|
-
import { reconcileTableGridAfterColumnRemoval,
|
|
25
|
+
import { markRowEmptiedInBatch, reconcileTableGridAfterColumnRemoval, removeRowsWithoutCellsAfterBatch, removeTableRow } from "../tableGridMutation.js";
|
|
26
|
+
import { runInCellPending, runParagraphIntoTable } from "../tableRunIn.js";
|
|
25
27
|
import { holdsNoContent } from "../zeroWidthAnchors.js";
|
|
26
28
|
import { inlineBookmarksForParagraphJoin } from "./paragraphBookmarkJoin.js";
|
|
27
29
|
import { hasSerializableParagraphPropertyChange, paragraphPropertiesSnapshot } from "./propertyChangeScope.js";
|
|
@@ -106,6 +108,7 @@ function resolveChange(from, to, mode, revisionIds) {
|
|
|
106
108
|
const matchesRevision = (mark) => revisionSet === null || typeof mark.attrs["revisionId"] === "number" && revisionSet.has(mark.attrs["revisionId"]);
|
|
107
109
|
if (dispatch) {
|
|
108
110
|
const tr = state.tr;
|
|
111
|
+
tr.setMeta(JOINED_RUNS_RESTYLED_META, true);
|
|
109
112
|
const deleteRanges = [];
|
|
110
113
|
/** Where resolved inline content began and ended, in `state.doc`. */
|
|
111
114
|
const resolvedBoundaries = [];
|
|
@@ -278,13 +281,18 @@ function resolveChange(from, to, mode, revisionIds) {
|
|
|
278
281
|
tableCellStructuralOps.sort((left, right) => right.cellPos - left.cellPos);
|
|
279
282
|
let resolvedTableCellStructure = false;
|
|
280
283
|
let failedTableCellMergeResolution = false;
|
|
281
|
-
const emptiedTables =
|
|
284
|
+
const emptiedTables = { pending: false };
|
|
282
285
|
for (const op of tableCellStructuralOps) {
|
|
283
286
|
const mappedPos = tr.mapping.map(op.cellPos);
|
|
284
287
|
const cell = tr.doc.nodeAt(mappedPos);
|
|
285
288
|
if (!cell || cell.type.name !== "tableCell" && cell.type.name !== "tableHeader") continue;
|
|
286
289
|
if (op.type === "merge") {
|
|
287
|
-
const resolved = op.source === "collapsed" ? resolveCollapsedTableCellMerge(tr, mappedPos, op.mode, op.revisionSet) : resolveVisibleTableCellMerge(
|
|
290
|
+
const resolved = op.source === "collapsed" ? resolveCollapsedTableCellMerge(tr, mappedPos, op.mode, op.revisionSet) : resolveVisibleTableCellMerge({
|
|
291
|
+
tr,
|
|
292
|
+
cellPos: mappedPos,
|
|
293
|
+
mode: op.mode,
|
|
294
|
+
revisionSet: op.revisionSet
|
|
295
|
+
});
|
|
288
296
|
if (!resolved) {
|
|
289
297
|
failedTableCellMergeResolution = true;
|
|
290
298
|
break;
|
|
@@ -301,9 +309,15 @@ function resolveChange(from, to, mode, revisionIds) {
|
|
|
301
309
|
resolvedTableCellStructure = true;
|
|
302
310
|
}
|
|
303
311
|
if (failedTableCellMergeResolution) return false;
|
|
304
|
-
|
|
312
|
+
removeRowsWithoutCellsAfterBatch(tr, emptiedTables);
|
|
305
313
|
if (resolvedTableCellStructure) markStructuralChange(tr);
|
|
306
314
|
pPrMarkOps.sort((a, b) => b.paragraphPos - a.paragraphPos);
|
|
315
|
+
const pendingTables = [];
|
|
316
|
+
state.doc.descendants((node, position) => {
|
|
317
|
+
if (node.type.spec["tableRole"] === "table" && runInCellPending(node)) pendingTables.push(position);
|
|
318
|
+
return !node.isTextblock;
|
|
319
|
+
});
|
|
320
|
+
const joinSeams = [];
|
|
307
321
|
for (const op of pPrMarkOps) {
|
|
308
322
|
const mappedPos = tr.mapping.map(op.paragraphPos);
|
|
309
323
|
const paragraph = tr.doc.nodeAt(mappedPos);
|
|
@@ -323,7 +337,18 @@ function resolveChange(from, to, mode, revisionIds) {
|
|
|
323
337
|
nextPos += boundary.nodeSize;
|
|
324
338
|
}
|
|
325
339
|
const nextNode = nextPos < tr.doc.content.size ? tr.doc.nodeAt(nextPos) : null;
|
|
326
|
-
|
|
340
|
+
const joinable = nextNode?.type.name === paragraph.type.name;
|
|
341
|
+
const ranIn = nextNode?.type.spec["tableRole"] === "table" && boundaries.length === 0 && !pendingTables.some((position) => tr.mapping.map(position) === nextPos) ? runParagraphIntoTable({
|
|
342
|
+
tr,
|
|
343
|
+
paragraphPos: mappedPos,
|
|
344
|
+
styleResolver
|
|
345
|
+
}) : null;
|
|
346
|
+
if (ranIn) {
|
|
347
|
+
tr.setMeta(JOINED_RUNS_RESTYLED_META, true);
|
|
348
|
+
markParagraphPropertySourceTransfers(tr, [ranIn.transfer]);
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
if (!joinable) {
|
|
327
352
|
const resolved = tr.doc.resolve(mappedPos);
|
|
328
353
|
const endsItsContainer = paragraphEndsItsContainer(resolved, paragraph.type.name);
|
|
329
354
|
const canGo = op.markWasAdded || !endsItsContainer;
|
|
@@ -340,12 +365,6 @@ function resolveChange(from, to, mode, revisionIds) {
|
|
|
340
365
|
}
|
|
341
366
|
try {
|
|
342
367
|
if (boundaries.length > 0) {
|
|
343
|
-
const emptyFirstParagraph = holdsNoContent(paragraph);
|
|
344
|
-
const joinedAttrs = {
|
|
345
|
-
...(emptyFirstParagraph ? nextNode : paragraph).attrs,
|
|
346
|
-
pPrMark: nextNode.attrs["pPrMark"],
|
|
347
|
-
_sectionProperties: nextNode.attrs["_sectionProperties"]
|
|
348
|
-
};
|
|
349
368
|
const leftToken = getProseParagraphPropertySourceToken(paragraph);
|
|
350
369
|
const rightToken = getProseParagraphPropertySourceToken(nextNode);
|
|
351
370
|
const inlineBookmarks = inlineBookmarksForParagraphJoin({
|
|
@@ -355,16 +374,31 @@ function resolveChange(from, to, mode, revisionIds) {
|
|
|
355
374
|
});
|
|
356
375
|
if (!inlineBookmarks) continue;
|
|
357
376
|
tr.replaceWith(joinPos - 1, nextPos + 1, inlineBookmarks);
|
|
358
|
-
tr.setNodeMarkup(mappedPos, void 0,
|
|
359
|
-
|
|
377
|
+
tr.setNodeMarkup(mappedPos, void 0, nextNode.attrs);
|
|
378
|
+
markParagraphPropertySourceTransfers(tr, [{
|
|
360
379
|
displacedToken: typeof leftToken === "string" ? leftToken : null,
|
|
361
380
|
selectedToken: typeof rightToken === "string" ? rightToken : null
|
|
362
381
|
}]);
|
|
382
|
+
if (styleResolver && paragraph.content.size > 0) rebaseParagraphRuns({
|
|
383
|
+
previousContext: paragraphRunStyleContext(paragraph, styleResolver),
|
|
384
|
+
paragraphPosition: mappedPos,
|
|
385
|
+
range: {
|
|
386
|
+
from: 0,
|
|
387
|
+
to: paragraph.content.size
|
|
388
|
+
},
|
|
389
|
+
styleResolver,
|
|
390
|
+
tr
|
|
391
|
+
});
|
|
363
392
|
} else joinAtParagraphMark({
|
|
364
393
|
tr,
|
|
365
394
|
paragraphPos: mappedPos,
|
|
366
395
|
paragraph,
|
|
367
|
-
next: nextNode
|
|
396
|
+
next: nextNode,
|
|
397
|
+
styleResolver
|
|
398
|
+
});
|
|
399
|
+
joinSeams.push({
|
|
400
|
+
position: mappedPos + 1 + paragraph.content.size,
|
|
401
|
+
step: tr.steps.length
|
|
368
402
|
});
|
|
369
403
|
if (ownsSectionEndpoint(paragraph)) {
|
|
370
404
|
removedSectionEndpointCount++;
|
|
@@ -378,9 +412,10 @@ function resolveChange(from, to, mode, revisionIds) {
|
|
|
378
412
|
removedReferences: removedSectionReferences
|
|
379
413
|
});
|
|
380
414
|
if (!terminalTableDeletionIsPending(tr)) resolveTerminalTableReviewCarrier(tr, mode);
|
|
415
|
+
const seams = new Set(joinSeams.map(({ position, step }) => tr.mapping.slice(step).map(position)));
|
|
381
416
|
rejoinRunsAt({
|
|
382
417
|
tr,
|
|
383
|
-
boundaries: resolvedBoundaries.map((position) => tr.mapping.map(position)),
|
|
418
|
+
boundaries: resolvedBoundaries.map((position) => tr.mapping.map(position)).filter((position) => !seams.has(position)),
|
|
384
419
|
styleResolver
|
|
385
420
|
});
|
|
386
421
|
if (tr.steps.length > 0) dispatch(tr);
|
|
@@ -559,6 +594,7 @@ function isTableCellRevisionAttr(value) {
|
|
|
559
594
|
const info = value.info;
|
|
560
595
|
return typeof info === "object" && info !== null && "revisionId" in info && typeof info.revisionId === "number";
|
|
561
596
|
}
|
|
597
|
+
/** Record rows for a final sweep after every cell revision has resolved. */
|
|
562
598
|
function deleteTableCellAt(tr, cellPos, emptied) {
|
|
563
599
|
const cell = tr.doc.nodeAt(cellPos);
|
|
564
600
|
if (!cell || cell.type.name !== "tableCell" && cell.type.name !== "tableHeader") return;
|
|
@@ -573,9 +609,10 @@ function deleteTableCellAt(tr, cellPos, emptied) {
|
|
|
573
609
|
const removedColumn = TableMap.get(table).findCell(cellOffset).left;
|
|
574
610
|
const spansDown = Number(cell.attrs["rowspan"]) > 1;
|
|
575
611
|
if (row.childCount > 1 || spansDown) {
|
|
576
|
-
if (row.childCount === 1)
|
|
577
|
-
|
|
578
|
-
|
|
612
|
+
if (row.childCount === 1) markRowEmptiedInBatch({
|
|
613
|
+
tr,
|
|
614
|
+
rowPosition: resolved.start() - 1,
|
|
615
|
+
emptied
|
|
579
616
|
});
|
|
580
617
|
tr.delete(cellPos, cellPos + cell.nodeSize);
|
|
581
618
|
reconcileTableGridAfterColumnRemoval({
|
|
@@ -1336,7 +1373,10 @@ const shiftAddedParagraphBreakBefore = ({ tr, paragraphPosition, mark, fallbackA
|
|
|
1336
1373
|
const paragraph = tr.doc.nodeAt(paragraphPosition);
|
|
1337
1374
|
if (!paragraph || paragraph.type.name !== "paragraph") return false;
|
|
1338
1375
|
const resolved = tr.doc.resolve(paragraphPosition);
|
|
1339
|
-
const carrier = addedBreakCarrierBefore(
|
|
1376
|
+
const carrier = addedBreakCarrierBefore({
|
|
1377
|
+
at: resolved,
|
|
1378
|
+
paragraphTypeName: paragraph.type.name
|
|
1379
|
+
});
|
|
1340
1380
|
if (!carrier) return false;
|
|
1341
1381
|
const path = [{
|
|
1342
1382
|
node: paragraph,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { mergeTextFormatting } from "../../utils/textFormattingMerge.js";
|
|
2
2
|
import { expectCharacterStyleMarkAttrs } from "../attrs/index.js";
|
|
3
|
-
import { getDocumentStyleResolver } from "../plugins/
|
|
3
|
+
import { getDocumentStyleResolver } from "../plugins/documentStyleState.js";
|
|
4
4
|
import { readAuthoredRunFormatting, reconcileRunFormattingMarks } from "../runFormattingReconciliation.js";
|
|
5
5
|
import { paragraphFormattingForRun, paragraphRunStyleContext, paragraphRunStyleContextAt, resolveEffectiveRunStyleFormatting } from "../runStyleFormatting.js";
|
|
6
6
|
//#region src/prosemirror/commands/formatPainter.ts
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { normalizeUserUrl } from "../../utils/urlSecurity.js";
|
|
2
2
|
import { expectHyperlinkMarkAttrs } from "../attrs/index.js";
|
|
3
|
+
import { removeHyperlinkInRange } from "../hyperlinkRemoval.js";
|
|
3
4
|
//#region src/prosemirror/commands/hyperlink.ts
|
|
4
5
|
const hyperlinkHref = (mark) => expectHyperlinkMarkAttrs(mark).href;
|
|
5
6
|
/**
|
|
@@ -87,7 +88,7 @@ const removeHyperlinkAtCursor = (view, { popupHref }) => {
|
|
|
87
88
|
const ranges = collectHyperlinkRanges($from.parent, $from.start(), hlType, hyperlinkHref(linkMark));
|
|
88
89
|
const targetRange = rangeAtCursor(ranges, $from.pos);
|
|
89
90
|
if (!targetRange) return false;
|
|
90
|
-
const tr = view.state.tr
|
|
91
|
+
const tr = removeHyperlinkInRange(view.state, view.state.tr, targetRange.start, targetRange.end);
|
|
91
92
|
view.dispatch(tr.scrollIntoView());
|
|
92
93
|
return true;
|
|
93
94
|
};
|
|
@@ -48,8 +48,9 @@ declare const PPR_CHANGE_SCOPED_ATTR_KEYS: readonly ["styleId", "numPr", "alignm
|
|
|
48
48
|
declare const paragraphPropertiesSnapshot: (node: Node) => ParagraphPropertySnapshot;
|
|
49
49
|
/**
|
|
50
50
|
* Build the attr patch that rejecting one pPrChange applies to a paragraph:
|
|
51
|
-
* every in-scope key set to the stored previous value, or
|
|
52
|
-
* when the stored old pPr does not carry it
|
|
51
|
+
* every in-scope key set to the stored previous value, or to what the style
|
|
52
|
+
* (`inheritedFormatting`) supplies when the stored old pPr does not carry it,
|
|
53
|
+
* `null` when neither does. Keys the record captured beyond
|
|
53
54
|
* the scoped set (editor-created list suggestions snapshot list-rendering
|
|
54
55
|
* bookkeeping attrs) merge through 1:1 so their pre-change values restore too.
|
|
55
56
|
*/
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import { isStyleSourcedParagraphNumbering } from "../../internal/paragraphFormattingSerialization.js";
|
|
1
2
|
import { expectParagraphAttrs } from "../attrs/index.js";
|
|
2
3
|
import { readParagraphNumberingAttr } from "../numberingAttr.js";
|
|
3
4
|
import { directParagraphAlignment } from "../paragraphAlignment.js";
|
|
4
5
|
import { directionFromBidi } from "../paragraphDirection.js";
|
|
6
|
+
import { PARAGRAPH_FORMATTING_WRITE_BACK, STYLE_RESOLVED_PARAGRAPH_FIELDS } from "../paragraphFormattingProvenance.js";
|
|
5
7
|
import { directParagraphSpacing, paragraphSpacingAttrPatch, paragraphSpacingFromFormatting } from "../paragraphSpacing.js";
|
|
8
|
+
import { sameFormattingValue } from "../runFormattingFromMarks.js";
|
|
6
9
|
//#region src/prosemirror/commands/propertyChangeScope.ts
|
|
7
10
|
/** Editor-only suggestions are rebased away before save; every other entry emits `w:pPrChange`. */
|
|
8
11
|
const hasSerializableParagraphPropertyChange = (changes) => changes?.some(({ info }) => info.provenance !== "suggested") === true;
|
|
@@ -106,12 +109,29 @@ const PPR_SPACING_ATTR_KEYS = /* @__PURE__ */ new Set([
|
|
|
106
109
|
"spacingExplicit",
|
|
107
110
|
"_autospacingBase"
|
|
108
111
|
]);
|
|
112
|
+
/**
|
|
113
|
+
* Whether the attr holds only what the paragraph's style resolves to: the
|
|
114
|
+
* paragraph does not state it (its source `w:pPr` has no such field) and the
|
|
115
|
+
* value is the style's. The same test a save applies before writing it.
|
|
116
|
+
*/
|
|
117
|
+
const styleSuppliedParagraphValue = (attrs, key) => {
|
|
118
|
+
if (!STYLE_RESOLVED_ATTR_FIELDS.has(key)) return false;
|
|
119
|
+
const field = key;
|
|
120
|
+
const inherited = attrs._resolvedFormatting?.[field];
|
|
121
|
+
return attrs._originalFormatting?.[field] === void 0 && inherited !== void 0 && inherited !== null && sameFormattingValue(Reflect.get(attrs, key), inherited);
|
|
122
|
+
};
|
|
123
|
+
/** Fields whose attr carries the style-resolved value under the field's own name. */
|
|
124
|
+
const STYLE_RESOLVED_ATTR_FIELDS = new Set(STYLE_RESOLVED_PARAGRAPH_FIELDS.filter((field) => PARAGRAPH_FORMATTING_WRITE_BACK[field].attr === field));
|
|
109
125
|
/** The in-scope paragraph properties as they stand, for a `w:pPrChange` record. */
|
|
110
126
|
const paragraphPropertiesSnapshot = (node) => {
|
|
111
127
|
const attrs = expectParagraphAttrs(node);
|
|
112
128
|
const snapshot = {};
|
|
113
129
|
for (const key of PPR_CHANGE_SCOPED_ATTR_KEYS) {
|
|
114
|
-
if (key === "alignment" || PPR_SPACING_ATTR_KEYS.has(key)) continue;
|
|
130
|
+
if (key === "alignment" || PPR_SPACING_ATTR_KEYS.has(key) || key === "numPr" && isStyleSourcedParagraphNumbering(attrs.numPr, attrs.numPrFromStyle)) continue;
|
|
131
|
+
if (styleSuppliedParagraphValue(attrs, key)) continue;
|
|
132
|
+
if (key === "hangingIndent" && styleSuppliedParagraphValue(attrs, "indentFirstLine")) continue;
|
|
133
|
+
if (styleSuppliedParagraphValue(attrs, key)) continue;
|
|
134
|
+
if (key === "hangingIndent" && styleSuppliedParagraphValue(attrs, "indentFirstLine")) continue;
|
|
115
135
|
const value = attrs[key];
|
|
116
136
|
if (key === "hangingIndent" && value === false && attrs._originalFormatting?.hangingIndent === void 0) continue;
|
|
117
137
|
if (value !== null && value !== void 0) snapshot[key] = value;
|
|
@@ -177,15 +197,19 @@ const PPR_CHANGE_SCOPED_FORMATTING_KEYS = [
|
|
|
177
197
|
];
|
|
178
198
|
/**
|
|
179
199
|
* Build the attr patch that rejecting one pPrChange applies to a paragraph:
|
|
180
|
-
* every in-scope key set to the stored previous value, or
|
|
181
|
-
* when the stored old pPr does not carry it
|
|
200
|
+
* every in-scope key set to the stored previous value, or to what the style
|
|
201
|
+
* (`inheritedFormatting`) supplies when the stored old pPr does not carry it,
|
|
202
|
+
* `null` when neither does. Keys the record captured beyond
|
|
182
203
|
* the scoped set (editor-created list suggestions snapshot list-rendering
|
|
183
204
|
* bookkeeping attrs) merge through 1:1 so their pre-change values restore too.
|
|
184
205
|
*/
|
|
185
206
|
function paragraphRejectAttrPatch(previousFormatting, inheritedFormatting) {
|
|
186
207
|
const prev = previousFormatting ?? {};
|
|
187
208
|
const patch = {};
|
|
188
|
-
for (const key of PPR_CHANGE_SCOPED_ATTR_KEYS)
|
|
209
|
+
for (const key of PPR_CHANGE_SCOPED_ATTR_KEYS) if (Object.hasOwn(prev, key)) patch[key] = prev[key] ?? null;
|
|
210
|
+
else if (STYLE_RESOLVED_ATTR_FIELDS.has(key)) patch[key] = Reflect.get(inheritedFormatting ?? {}, key) ?? null;
|
|
211
|
+
else patch[key] = null;
|
|
212
|
+
if (!Object.hasOwn(prev, "indentFirstLine") && !Object.hasOwn(prev, "hangingIndent")) patch["hangingIndent"] = inheritedFormatting?.hangingIndent ?? null;
|
|
189
213
|
if (!Object.hasOwn(prev, "alignment")) patch["alignment"] = inheritedFormatting?.alignment ?? null;
|
|
190
214
|
patch["alignmentFromStyle"] = inheritedFormatting?.alignment;
|
|
191
215
|
const directSpacing = paragraphSpacingFromFormatting(prev);
|
|
@@ -6,6 +6,7 @@ import { getTableCellMergeChange } from "../tableCellMergeRevision.js";
|
|
|
6
6
|
import { isTableCellRetainedInReviewView } from "../tableCellRevisionVisibility.js";
|
|
7
7
|
import { resolveAllNodePropertyChangeAttrs } from "./resolveNodePropertyChangeAttrs.js";
|
|
8
8
|
import { createRestoredTableCell, hasMatchingCollapsedTableCellMerge, tableCellContinuationCells, tableCellContinuationFromNode, tableCellContinuationPayload } from "./tableCellMergeResolution.js";
|
|
9
|
+
import { resolvedTableMergeOriginAttrs, resolvedVisibleTableCellMergeAttrs, tableMergeFoldDecisions } from "./tableMergeFoldDecisions.js";
|
|
9
10
|
import { panic } from "better-result";
|
|
10
11
|
import { TableMap } from "prosemirror-tables";
|
|
11
12
|
import { StepMap } from "prosemirror-transform";
|
|
@@ -131,10 +132,12 @@ const cellRevisionMarker = (cell) => {
|
|
|
131
132
|
const marker = cell.attrs["cellMarker"];
|
|
132
133
|
if (typeof marker !== "object" || marker === null || !("kind" in marker) || marker.kind !== "ins" && marker.kind !== "del" && marker.kind !== "merge" || !("info" in marker) || typeof marker.info !== "object" || marker.info === null || !("revisionId" in marker.info) || typeof marker.info.revisionId !== "number") return null;
|
|
133
134
|
const verticalMergeOriginal = "verticalMergeOriginal" in marker && isTableCellMergeRevisionValue(marker.verticalMergeOriginal) ? marker.verticalMergeOriginal : void 0;
|
|
135
|
+
const verticalMerge = "verticalMerge" in marker && isTableCellMergeRevisionValue(marker.verticalMerge) ? marker.verticalMerge : void 0;
|
|
134
136
|
return {
|
|
135
137
|
kind: marker.kind,
|
|
136
138
|
info: { revisionId: marker.info.revisionId },
|
|
137
|
-
...verticalMergeOriginal ? { verticalMergeOriginal } : {}
|
|
139
|
+
...verticalMergeOriginal ? { verticalMergeOriginal } : {},
|
|
140
|
+
...verticalMerge ? { verticalMerge } : {}
|
|
138
141
|
};
|
|
139
142
|
};
|
|
140
143
|
/**
|
|
@@ -356,6 +359,12 @@ const compactColumnWidths = (widths, removals) => {
|
|
|
356
359
|
/** Resolve all cell edits in reverse order against one grid and mutable slots. */
|
|
357
360
|
const resolvePureTableMerges = ({ table, mode, rowMetadata, tablePropertyTouched, sourceTable }) => {
|
|
358
361
|
const map = TableMap.get(table);
|
|
362
|
+
const mergeDecisions = tableMergeFoldDecisions({
|
|
363
|
+
table,
|
|
364
|
+
mode,
|
|
365
|
+
revisionSet: null
|
|
366
|
+
});
|
|
367
|
+
if (mergeDecisions.invalid.size > 0) return failedTableResolution(table);
|
|
359
368
|
const cellRectangle = indexedTableCells(map);
|
|
360
369
|
const rows = Array.from({ length: table.childCount }, (_, index) => table.child(index));
|
|
361
370
|
const rowCells = rows.map(() => /* @__PURE__ */ new Map());
|
|
@@ -381,7 +390,7 @@ const resolvePureTableMerges = ({ table, mode, rowMetadata, tablePropertyTouched
|
|
|
381
390
|
for (let coveredRow = rectangle.top; coveredRow < rectangle.bottom; coveredRow++) rowOccupancy[coveredRow] = elementAt(rowOccupancy, coveredRow) + (rectangle.right - rectangle.left);
|
|
382
391
|
const initial = elementAt(elementAt(rowMetadata, rowIndex).cells, cellIndex);
|
|
383
392
|
const entry = {
|
|
384
|
-
node,
|
|
393
|
+
node: mergeDecisions.origins.has(cellOffset) ? node.type.create(resolvedTableMergeOriginAttrs(node), node.content, node.marks) : node,
|
|
385
394
|
position: cellOffset,
|
|
386
395
|
left,
|
|
387
396
|
row: rowIndex,
|
|
@@ -435,46 +444,36 @@ const resolvePureTableMerges = ({ table, mode, rowMetadata, tablePropertyTouched
|
|
|
435
444
|
count: previousWidth - currentWidth
|
|
436
445
|
});
|
|
437
446
|
}
|
|
438
|
-
} else if (marker?.kind === "merge")
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
447
|
+
} else if (marker?.kind === "merge") {
|
|
448
|
+
const joinsAbove = mergeDecisions.folds.get(entry.position);
|
|
449
|
+
if (joinsAbove === void 0) return panic("Merge resolution lost its cell");
|
|
450
|
+
if (mode === "reject" && isTableCellMergeRevisionContinuation(marker.verticalMergeOriginal) && cellRectangle(entry.position).top === 0) return failedTableResolution(table);
|
|
451
|
+
if (!joinsAbove) entry.node = entry.node.type.create(resolvedVisibleTableCellMergeAttrs({
|
|
452
|
+
cell: entry.node,
|
|
453
|
+
mode,
|
|
454
|
+
origin: mergeDecisions.origins.has(entry.position)
|
|
455
|
+
}), entry.node.content, entry.node.marks);
|
|
456
|
+
else {
|
|
457
|
+
const rectangle = cellRectangle(entry.position);
|
|
458
|
+
if (rectangle.top === 0) return failedTableResolution(table);
|
|
459
|
+
const abovePosition = map.map[(rectangle.top - 1) * map.width + rectangle.left];
|
|
460
|
+
if (abovePosition === void 0) return failedTableResolution(table);
|
|
461
|
+
const aboveRectangle = cellRectangle(abovePosition);
|
|
462
|
+
const above = byPosition.get(abovePosition);
|
|
463
|
+
if (!above || !elementAt(rowCells, above.row).has(above.left) || aboveRectangle.left !== rectangle.left || aboveRectangle.right !== rectangle.right || aboveRectangle.bottom !== rectangle.top) return failedTableResolution(table);
|
|
464
|
+
const aboveRowspan = above.node.attrs["rowspan"];
|
|
465
|
+
const cellRowspan = entry.node.attrs["rowspan"];
|
|
466
|
+
if (typeof aboveRowspan !== "number" || typeof cellRowspan !== "number" || aboveRowspan < 1 || cellRowspan < 1) return failedTableResolution(table);
|
|
467
|
+
above.continuation ??= continuationSequence(tableCellContinuationCells(above.node, aboveRowspan));
|
|
468
|
+
appendContinuation(above.continuation, tableCellContinuationFromNode(entry.node));
|
|
469
|
+
const nested = entry.continuation ?? continuationSequence(tableCellContinuationPayload(entry.node)?.cells ?? []);
|
|
470
|
+
appendContinuationSequence(above.continuation, nested);
|
|
471
|
+
above.node = above.node.type.create({
|
|
472
|
+
...above.node.attrs,
|
|
473
|
+
rowspan: aboveRowspan + cellRowspan
|
|
474
|
+
}, above.node.content, above.node.marks);
|
|
475
|
+
elementAt(rowCells, entry.row).delete(entry.left);
|
|
452
476
|
}
|
|
453
|
-
entry.node = entry.node.type.create({
|
|
454
|
-
...entry.node.attrs,
|
|
455
|
-
cellMarker: null,
|
|
456
|
-
_originalFormatting: formatting
|
|
457
|
-
}, entry.node.content, entry.node.marks);
|
|
458
|
-
} else {
|
|
459
|
-
const rectangle = cellRectangle(entry.position);
|
|
460
|
-
if (rectangle.top === 0) return failedTableResolution(table);
|
|
461
|
-
const abovePosition = map.map[(rectangle.top - 1) * map.width + rectangle.left];
|
|
462
|
-
if (abovePosition === void 0) return failedTableResolution(table);
|
|
463
|
-
const aboveRectangle = cellRectangle(abovePosition);
|
|
464
|
-
const above = byPosition.get(abovePosition);
|
|
465
|
-
if (!above || !elementAt(rowCells, above.row).has(above.left) || aboveRectangle.left !== rectangle.left || aboveRectangle.right !== rectangle.right || aboveRectangle.bottom !== rectangle.top) return failedTableResolution(table);
|
|
466
|
-
const aboveRowspan = above.node.attrs["rowspan"];
|
|
467
|
-
const cellRowspan = entry.node.attrs["rowspan"];
|
|
468
|
-
if (typeof aboveRowspan !== "number" || typeof cellRowspan !== "number" || aboveRowspan < 1 || cellRowspan < 1) return failedTableResolution(table);
|
|
469
|
-
above.continuation ??= continuationSequence(tableCellContinuationCells(above.node, aboveRowspan));
|
|
470
|
-
appendContinuation(above.continuation, tableCellContinuationFromNode(entry.node));
|
|
471
|
-
const nested = entry.continuation ?? continuationSequence(tableCellContinuationPayload(entry.node)?.cells ?? []);
|
|
472
|
-
appendContinuationSequence(above.continuation, nested);
|
|
473
|
-
above.node = above.node.type.create({
|
|
474
|
-
...above.node.attrs,
|
|
475
|
-
rowspan: aboveRowspan + cellRowspan
|
|
476
|
-
}, above.node.content, above.node.marks);
|
|
477
|
-
elementAt(rowCells, entry.row).delete(entry.left);
|
|
478
477
|
}
|
|
479
478
|
if (!elementAt(rowCells, entry.row).has(entry.left)) continue;
|
|
480
479
|
if (!tableCellContinuationPayload(entry.node)?.cells.some((cell) => getTableCellMergeChange(cell) !== null)) continue;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import { resolveParagraphNumbering } from "../../docx/numberingReference.js";
|
|
1
2
|
import { expectParagraphAttrs } from "../attrs/index.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
3
|
+
import { rejectedListRenderingPatch } from "../listRendering.js";
|
|
4
|
+
import { paragraphNumberingAttr } from "../numberingAttr.js";
|
|
5
|
+
import { styleResolvedParagraphFormatting } from "../paragraphFormattingProvenance.js";
|
|
6
|
+
import { resolveParagraphDefaultTextFormatting } from "../styles/paragraphStyleCascade.js";
|
|
4
7
|
import { paragraphRejectAttrPatch, paragraphRejectOriginalFormatting, removeParagraphPropertyChanges, sectionRejectProperties } from "./propertyChangeScope.js";
|
|
5
8
|
//#region src/prosemirror/commands/resolveParagraphProperties.ts
|
|
6
9
|
/** Resolve paragraph and section property records before resolving their inline content. */
|
|
@@ -20,15 +23,37 @@ const resolveParagraphChangeAttrs = ({ node, boundaryCovered, mode, revisionSet,
|
|
|
20
23
|
_propertyChanges: remaining.length > 0 ? remaining : null
|
|
21
24
|
};
|
|
22
25
|
if (rejection?.type === "restore-previous") {
|
|
23
|
-
const
|
|
26
|
+
const currentAttrs = expectParagraphAttrs(node);
|
|
27
|
+
const inheritedAlignment = currentAttrs.alignmentFromStyle;
|
|
28
|
+
const restoredStyleId = rejection.previousFormatting?.styleId ?? void 0;
|
|
29
|
+
const sameStyle = restoredStyleId === (currentAttrs.styleId ?? void 0);
|
|
24
30
|
let previousFormattingFromStyle;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
let resolvedFromStyle = sameStyle ? currentAttrs._resolvedFormatting : void 0;
|
|
32
|
+
if (styleResolver) {
|
|
33
|
+
previousFormattingFromStyle = styleResolver.resolveParagraphStyle(restoredStyleId).paragraphFormatting;
|
|
34
|
+
if (!sameStyle) {
|
|
35
|
+
resolvedFromStyle = styleResolvedParagraphFormatting(previousFormattingFromStyle);
|
|
36
|
+
nextAttrs["_resolvedFormatting"] = resolvedFromStyle;
|
|
37
|
+
}
|
|
38
|
+
} else if (inheritedAlignment !== void 0) previousFormattingFromStyle = { alignment: inheritedAlignment };
|
|
39
|
+
const inheritedFormatting = previousFormattingFromStyle === void 0 && resolvedFromStyle === void 0 ? void 0 : {
|
|
40
|
+
...previousFormattingFromStyle,
|
|
41
|
+
...resolvedFromStyle
|
|
42
|
+
};
|
|
43
|
+
let styleNumbering = previousFormattingFromStyle?.numPr;
|
|
44
|
+
if (!styleResolver && sameStyle) styleNumbering = currentAttrs.numPrFromStyle ?? void 0;
|
|
45
|
+
const inheritedNumbering = styleNumbering == null ? null : paragraphNumberingAttr(resolveParagraphNumbering(styleNumbering));
|
|
46
|
+
const recordedNumbering = rejection.previousFormatting?.numPr;
|
|
47
|
+
const restoredNumbering = recordedNumbering ?? inheritedNumbering;
|
|
48
|
+
Object.assign(nextAttrs, paragraphRejectAttrPatch(rejection.previousFormatting, inheritedFormatting), rejectedListRenderingPatch({
|
|
28
49
|
current: expectParagraphAttrs(node),
|
|
29
50
|
previousFormatting: rejection.previousFormatting,
|
|
30
|
-
numbering
|
|
31
|
-
|
|
51
|
+
numbering,
|
|
52
|
+
restoredNumbering
|
|
53
|
+
}), {
|
|
54
|
+
numPr: restoredNumbering,
|
|
55
|
+
numPrFromStyle: recordedNumbering == null ? inheritedNumbering : null
|
|
56
|
+
});
|
|
32
57
|
const restoredFormatting = paragraphRejectOriginalFormatting(rejection.previousFormatting, node.attrs["_originalFormatting"]);
|
|
33
58
|
nextAttrs["_originalFormatting"] = restoredFormatting;
|
|
34
59
|
if (styleResolver) nextAttrs["defaultTextFormatting"] = resolveParagraphDefaultTextFormatting(rejection.previousFormatting?.styleId, restoredFormatting ?? void 0, styleResolver) ?? null;
|
|
@@ -5,7 +5,13 @@ import { Transaction } from "prosemirror-state";
|
|
|
5
5
|
//#region src/prosemirror/commands/tableCellMergeResolution.d.ts
|
|
6
6
|
declare const tableCellContinuationPayload: (node: Node) => DecodedTableCellParagraphSourcePayload | null;
|
|
7
7
|
declare const hasMatchingCollapsedTableCellMerge: (node: Node, revisionSet: Set<number> | null) => boolean;
|
|
8
|
-
|
|
8
|
+
type ResolveVisibleTableCellMergeOptions = {
|
|
9
|
+
tr: Transaction;
|
|
10
|
+
cellPos: number;
|
|
11
|
+
mode: "accept" | "reject";
|
|
12
|
+
revisionSet: ReadonlySet<number> | null;
|
|
13
|
+
};
|
|
14
|
+
declare const resolveVisibleTableCellMerge: ({ tr, cellPos, mode, revisionSet }: ResolveVisibleTableCellMergeOptions) => boolean;
|
|
9
15
|
declare const tableCellContinuationCells: (cell: Node, rowspan: number) => document_d_exports.TableCell[];
|
|
10
16
|
declare const tableCellContinuationFromNode: (cell: Node) => document_d_exports.TableCell;
|
|
11
17
|
declare const resolveCollapsedTableCellMerge: (tr: Transaction, cellPos: number, mode: "accept" | "reject", revisionSet: Set<number> | null) => boolean;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { decodeTableCellParagraphSourcePayload, restoreTableCellsWithParagraphPropertySources, transportTableCellsWithParagraphPropertySources } from "../../docx/paragraphPropertySource.js";
|
|
2
|
+
import { isTableCellMergeRevisionContinuation } from "../../docx/tableParser.js";
|
|
2
3
|
import { standaloneTableCellFromProseMirror } from "../conversion/fromProseDoc.js";
|
|
3
4
|
import { standaloneTableCellToProseMirror } from "../conversion/toProseDoc.js";
|
|
4
5
|
import { getTableCellMergeChange } from "../tableCellMergeRevision.js";
|
|
5
|
-
import {
|
|
6
|
+
import { removeRowsWithoutCellsInRange } from "../tableGridMutation.js";
|
|
7
|
+
import { resolvedTableMergeOriginAttrs, resolvedVisibleTableCellMergeAttrs, tableMergeFoldDecisions } from "./tableMergeFoldDecisions.js";
|
|
8
|
+
import { Result, panic } from "better-result";
|
|
6
9
|
import { TableMap } from "prosemirror-tables";
|
|
7
10
|
//#region src/prosemirror/commands/tableCellMergeResolution.ts
|
|
8
11
|
const tableCellContinuationPayload = (node) => {
|
|
@@ -35,26 +38,35 @@ const tableCellContext = (doc, cellPos) => {
|
|
|
35
38
|
}
|
|
36
39
|
return null;
|
|
37
40
|
};
|
|
38
|
-
const resolveVisibleTableCellMerge = (tr, cellPos, mode) => {
|
|
41
|
+
const resolveVisibleTableCellMerge = ({ tr, cellPos, mode, revisionSet }) => {
|
|
39
42
|
const cell = tr.doc.nodeAt(cellPos);
|
|
40
43
|
const marker = cell?.attrs["cellMarker"];
|
|
41
44
|
if (!cell || !isTableCellMergeRevisionAttr(marker)) return false;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
nextOriginalFormatting = { ...originalFormatting };
|
|
51
|
-
delete nextOriginalFormatting.vMerge;
|
|
52
|
-
}
|
|
53
|
-
tr.setNodeMarkup(cellPos, void 0, {
|
|
54
|
-
...cell.attrs,
|
|
55
|
-
cellMarker: null,
|
|
56
|
-
_originalFormatting: nextOriginalFormatting
|
|
45
|
+
const context = tableCellContext(tr.doc, cellPos);
|
|
46
|
+
if (!context) return false;
|
|
47
|
+
const rectangle = TableMap.get(context.table).findCell(context.relativeCellPos);
|
|
48
|
+
if (mode === "reject" && isTableCellMergeRevisionContinuation(marker.verticalMergeOriginal) && rectangle.top === 0) return false;
|
|
49
|
+
const decisions = tableMergeFoldDecisions({
|
|
50
|
+
table: context.table,
|
|
51
|
+
mode,
|
|
52
|
+
revisionSet
|
|
57
53
|
});
|
|
54
|
+
if (decisions.invalid.has(context.relativeCellPos)) return false;
|
|
55
|
+
const folds = decisions.folds.get(context.relativeCellPos);
|
|
56
|
+
if (folds === void 0) return panic("Merge resolution lost its cell");
|
|
57
|
+
for (const origin of decisions.origins) {
|
|
58
|
+
if (origin === context.relativeCellPos) continue;
|
|
59
|
+
const originPos = context.tableStart + origin;
|
|
60
|
+
const originCell = tr.doc.nodeAt(originPos);
|
|
61
|
+
if (!originCell) return panic("Merge resolution lost its origin");
|
|
62
|
+
tr.setNodeMarkup(originPos, void 0, resolvedTableMergeOriginAttrs(originCell));
|
|
63
|
+
}
|
|
64
|
+
if (folds) return mergeTableCellWithCellAbove(tr, cellPos);
|
|
65
|
+
tr.setNodeMarkup(cellPos, void 0, resolvedVisibleTableCellMergeAttrs({
|
|
66
|
+
cell,
|
|
67
|
+
mode,
|
|
68
|
+
origin: decisions.origins.has(context.relativeCellPos)
|
|
69
|
+
}));
|
|
58
70
|
return true;
|
|
59
71
|
};
|
|
60
72
|
const mergeTableCellWithCellAbove = (tr, cellPos) => {
|
|
@@ -73,11 +85,18 @@ const mergeTableCellWithCellAbove = (tr, cellPos) => {
|
|
|
73
85
|
const aboveRowspan = aboveCell?.attrs["rowspan"];
|
|
74
86
|
const cellRowspan = cell.attrs["rowspan"];
|
|
75
87
|
if (!aboveCell || typeof aboveRowspan !== "number" || typeof cellRowspan !== "number" || aboveRowspan < 1 || cellRowspan < 1) return false;
|
|
88
|
+
removeRowsWithoutCellsInRange({
|
|
89
|
+
tr,
|
|
90
|
+
from: cellPos + 1,
|
|
91
|
+
to: cellPos + cell.nodeSize - 1
|
|
92
|
+
});
|
|
93
|
+
const capturedCell = tr.doc.nodeAt(cellPos);
|
|
94
|
+
if (!capturedCell) panic("Nested table cleanup removed its owning cell");
|
|
76
95
|
const continuationCells = tableCellContinuationCells(aboveCell, aboveRowspan);
|
|
77
|
-
continuationCells.push(tableCellContinuationFromNode(
|
|
78
|
-
const nestedPayload = tableCellContinuationPayload(
|
|
96
|
+
continuationCells.push(tableCellContinuationFromNode(capturedCell));
|
|
97
|
+
const nestedPayload = tableCellContinuationPayload(capturedCell);
|
|
79
98
|
if (nestedPayload) continuationCells.push(...nestedPayload.cells);
|
|
80
|
-
tr.delete(cellPos, cellPos +
|
|
99
|
+
tr.delete(cellPos, cellPos + capturedCell.nodeSize);
|
|
81
100
|
tr.setNodeMarkup(abovePos, void 0, {
|
|
82
101
|
...aboveCell.attrs,
|
|
83
102
|
rowspan: aboveRowspan + cellRowspan,
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Node } from "prosemirror-model";
|
|
2
|
+
//#region src/prosemirror/commands/tableMergeFoldDecisions.d.ts
|
|
3
|
+
type TableMergeFoldDecisionsOptions = {
|
|
4
|
+
table: Node;
|
|
5
|
+
mode: "accept" | "reject";
|
|
6
|
+
revisionSet: ReadonlySet<number> | null;
|
|
7
|
+
};
|
|
8
|
+
/** Resolve raw merge states without converting unrelated table revisions. */
|
|
9
|
+
declare const tableMergeFoldDecisions: ({ table, mode, revisionSet }: TableMergeFoldDecisionsOptions) => {
|
|
10
|
+
folds: Map<number, boolean>;
|
|
11
|
+
origins: Set<number>;
|
|
12
|
+
invalid: Set<number>;
|
|
13
|
+
};
|
|
14
|
+
/** Persist an implicit merge origin even when reader rules retain its continuation. */
|
|
15
|
+
declare const resolvedTableMergeOriginAttrs: (cell: Node) => {
|
|
16
|
+
_originalFormatting: {
|
|
17
|
+
vMerge: string;
|
|
18
|
+
width?: import("@stll/docx-core/model").TableMeasurement;
|
|
19
|
+
borders?: import("@stll/docx-core/model").TableCellBorders;
|
|
20
|
+
margins?: import("@stll/docx-core/model").CellMargins;
|
|
21
|
+
shading?: import("@stll/docx-core/model").ShadingProperties;
|
|
22
|
+
verticalAlign?: "top" | "center" | "bottom";
|
|
23
|
+
textDirection?: import("@stll/docx-core/model").TextDirection;
|
|
24
|
+
gridSpan?: number;
|
|
25
|
+
fitText?: boolean;
|
|
26
|
+
noWrap?: boolean;
|
|
27
|
+
hideMark?: boolean;
|
|
28
|
+
conditionalFormat?: import("@stll/docx-core/model").ConditionalFormatStyle;
|
|
29
|
+
preserved?: import("@stll/docx-core/model").PreservedMarkup;
|
|
30
|
+
sourceXml?: string;
|
|
31
|
+
};
|
|
32
|
+
_preserveVMergeRestart: boolean;
|
|
33
|
+
};
|
|
34
|
+
type ResolvedVisibleTableCellMergeOptions = {
|
|
35
|
+
cell: Node;
|
|
36
|
+
mode: "accept" | "reject";
|
|
37
|
+
origin: boolean;
|
|
38
|
+
};
|
|
39
|
+
/** A retained continuation must save the merge state the reviewer resolved. */
|
|
40
|
+
declare const resolvedVisibleTableCellMergeAttrs: ({ cell, mode, origin }: ResolvedVisibleTableCellMergeOptions) => {
|
|
41
|
+
cellMarker: null;
|
|
42
|
+
_originalFormatting: {
|
|
43
|
+
width?: import("@stll/docx-core/model").TableMeasurement;
|
|
44
|
+
borders?: import("@stll/docx-core/model").TableCellBorders;
|
|
45
|
+
margins?: import("@stll/docx-core/model").CellMargins;
|
|
46
|
+
shading?: import("@stll/docx-core/model").ShadingProperties;
|
|
47
|
+
verticalAlign?: "top" | "center" | "bottom";
|
|
48
|
+
textDirection?: import("@stll/docx-core/model").TextDirection;
|
|
49
|
+
gridSpan?: number;
|
|
50
|
+
vMerge?: "restart" | "continue";
|
|
51
|
+
fitText?: boolean;
|
|
52
|
+
noWrap?: boolean;
|
|
53
|
+
hideMark?: boolean;
|
|
54
|
+
conditionalFormat?: import("@stll/docx-core/model").ConditionalFormatStyle;
|
|
55
|
+
preserved?: import("@stll/docx-core/model").PreservedMarkup;
|
|
56
|
+
sourceXml?: string;
|
|
57
|
+
};
|
|
58
|
+
_preserveVMergeRestart: boolean;
|
|
59
|
+
};
|
|
60
|
+
//#endregion
|
|
61
|
+
export { resolvedTableMergeOriginAttrs, resolvedVisibleTableCellMergeAttrs, tableMergeFoldDecisions };
|