@stll/folio-core 0.56.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 +45 -14
- package/dist/ai-edits/batch-claims.d.ts +3 -1
- package/dist/ai-edits/batch-claims.js +25 -1
- package/dist/ai-edits/table-row-column-mutations.js +17 -3
- package/dist/ai-suggestions/apply.js +20 -1
- package/dist/compare/inline-atoms.js +40 -16
- package/dist/compare/inline-provenance.js +12 -5
- package/dist/compat/eigenpal.d.ts +2 -1
- package/dist/compat/eigenpal.js +2 -1
- package/dist/controller/canonicalClipboard.js +7 -1
- package/dist/controller/canonicalComments.d.ts +41 -0
- package/dist/controller/canonicalComments.js +152 -0
- package/dist/controller/canonicalComposition.d.ts +4 -0
- package/dist/controller/canonicalComposition.js +43 -11
- package/dist/controller/canonicalInlineProjection.d.ts +6 -1
- package/dist/controller/canonicalInlineProjection.js +86 -3
- package/dist/controller/canonicalInput.js +10 -1
- package/dist/controller/canonicalInputTimer.d.ts +10 -1
- package/dist/controller/canonicalInputTimer.js +24 -1
- package/dist/controller/canonicalPublicOperations.d.ts +2 -2
- package/dist/controller/canonicalPublicOperations.js +107 -15
- package/dist/controller/canonicalSelection.d.ts +18 -0
- package/dist/controller/canonicalSelection.js +32 -0
- package/dist/controller/canonicalSession.d.ts +3 -0
- package/dist/controller/canonicalSession.js +58 -24
- package/dist/controller/canonicalStoryEditor.d.ts +2 -0
- package/dist/controller/canonicalStoryEditor.js +20 -0
- package/dist/controller/folioEditor.js +13 -0
- package/dist/controller/headerFooterEditorManager.d.ts +1 -1
- package/dist/controller/headerFooterEditorManager.js +25 -11
- package/dist/controller/hiddenEditorApi.d.ts +13 -2
- package/dist/controller/hiddenEditorApi.js +4 -0
- package/dist/controller/hiddenEditorManager.d.ts +3 -1
- package/dist/controller/hiddenEditorManager.js +166 -13
- package/dist/controller/noteEditorManager.d.ts +1 -1
- package/dist/controller/noteEditorManager.js +28 -13
- package/dist/docx/builtInStyles.js +13 -6
- package/dist/docx/containerChildren.gen.d.ts +3 -1
- package/dist/docx/containerChildren.gen.js +33 -1
- package/dist/docx/fieldParser.js +14 -2
- package/dist/docx/hyperlinkParser.d.ts +1 -1
- package/dist/docx/hyperlinkParser.js +20 -1
- 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/paragraphParser.js +88 -67
- package/dist/docx/paragraphPropertySource.d.ts +22 -1
- package/dist/docx/paragraphPropertySource.js +107 -1
- package/dist/docx/preservedRunContent.js +2 -1
- package/dist/docx/relsParser.js +26 -2
- package/dist/docx/rezip.js +9 -6
- package/dist/docx/selectiveSave.js +10 -8
- package/dist/docx/serializer/commentSerializer.d.ts +4 -1
- package/dist/docx/serializer/commentSerializer.js +7 -3
- package/dist/docx/serializer/paragraphSerializer.js +207 -94
- package/dist/docx/server/materializeYjsDocx.js +14 -6
- package/dist/docx/server/migrateYjsAttrSchema.js +17 -5
- 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/revisionResolutionInline.js +25 -3
- package/dist/markdown/renderRuns.js +1 -11
- 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/commands/comments.js +60 -35
- 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/toProseDoc.js +119 -18
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +22 -5
- 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 +22 -14
- package/dist/prosemirror/extensions/marks/markUtils.js +8 -7
- 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/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/plugins/documentStyles.d.ts +4 -1
- package/dist/prosemirror/plugins/documentStyles.js +17 -10
- package/dist/prosemirror/plugins/suggestionMode.js +47 -49
- 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 +6 -20
- package/dist/types/canonicalCapabilities.js +6 -20
- package/dist/types/canonicalComments.d.ts +51 -0
- package/dist/types/canonicalComments.js +0 -0
- package/dist/types/canonicalSections.d.ts +12 -0
- package/dist/types/canonicalSections.js +0 -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 +2 -2
|
@@ -4,7 +4,7 @@ import { normalizeFoldedListNumbers } from "../../docx/foldedListNumberFields.js
|
|
|
4
4
|
import { EDITED_PREVIEW_FINGERPRINT, imageRawXmlFingerprint } from "../../docx/imageRawXml.js";
|
|
5
5
|
import { isInlineSdtContent, isSimpleFieldContent } from "../../docx/inlineWrapperContent.js";
|
|
6
6
|
import { paragraphNumberingReferenceId as paragraphNumberingReferenceId$1, sameStatedParagraphNumbering as sameStatedParagraphNumbering$1 } from "../../docx/numberingReference.js";
|
|
7
|
-
import { PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, ParagraphPropertySourceValidationError, copyDocumentParagraphPropertySourceContract, copyDocumentParagraphPropertySources, copyParagraphPropertyCapture, copyParagraphPropertySource, decodeTableCellParagraphSourcePayload, getDocumentParagraphPropertySourceContract, getParagraphPropertySource, getParagraphPropertySourceCandidate, getParagraphPropertySourceToken, getParagraphPropertySourceTransferId, getProseDocumentParagraphPropertySourceContract, getProseParagraphPropertySourceToken, inspectParagraphSourceIdentity, isParagraphPropertySourceToken, linkParagraphPropertySourceCandidate, paragraphPropertySourceTokenMatchesContract, recreateProseNodeWithParagraphPropertySource, restoreTableCellsWithParagraphPropertySources, visitDocumentStoryParagraphs, visitTableCellParagraphPropertySourceBindings } from "../../docx/paragraphPropertySource.js";
|
|
7
|
+
import { PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, ParagraphPropertySourceValidationError, assignParagraphIndentationProjection, copyDocumentParagraphPropertySourceContract, copyDocumentParagraphPropertySources, copyParagraphPropertyCapture, copyParagraphPropertySource, decodeTableCellParagraphSourcePayload, getDocumentParagraphPropertySourceContract, getParagraphPropertySource, getParagraphPropertySourceCandidate, getParagraphPropertySourceToken, getParagraphPropertySourceTransferId, getProseDocumentParagraphPropertySourceContract, getProseParagraphPropertySourceToken, inspectParagraphSourceIdentity, isParagraphPropertySourceToken, linkParagraphPropertySourceCandidate, paragraphFormattingWithAuthoredIndentation, paragraphPropertySourceTokenMatchesContract, recreateProseNodeWithParagraphPropertySource, restoreTableCellsWithParagraphPropertySources, visitDocumentStoryParagraphs, visitTableCellParagraphPropertySourceBindings } from "../../docx/paragraphPropertySource.js";
|
|
8
8
|
import { BLOCK_TREE_DESCENT, visitBlockTreeRecords, visitDocxParagraphs } from "../../docx/paragraphTraversal.js";
|
|
9
9
|
import { refingerprintShapeAlternateContent } from "../../docx/shapeAlternateContent.js";
|
|
10
10
|
import { DATE_UTC_ATTRIBUTE } from "../../docx/trackedChangeInfo.js";
|
|
@@ -33,9 +33,11 @@ import { inlineWrapperMember, inlineWrapperStackKey } from "../inlineWrapperStac
|
|
|
33
33
|
import { completeNumberingForDoc } from "../listInstanceReferences.js";
|
|
34
34
|
import { hasListRendering, listRenderingFromAttrs as listRenderingFromAttrs$1 } from "../listRenderingAttrs.js";
|
|
35
35
|
import { expectMoveRangeBoundaryAttrs } from "../moveRangeBoundaryAttrs.js";
|
|
36
|
+
import { assertNoteReferenceOccurrences, coalesceNoteReferenceOccurrences } from "../noteReferenceOccurrences.js";
|
|
36
37
|
import { resolveNumberedRefFields } from "../numberedRefFields.js";
|
|
37
38
|
import { directParagraphAlignment } from "../paragraphAlignment.js";
|
|
38
39
|
import { directionToAuthoredBidi } from "../paragraphDirection.js";
|
|
40
|
+
import { paragraphIndentationFromFormatting } from "../paragraphIndentation.js";
|
|
39
41
|
import { directParagraphSpacing } from "../paragraphSpacing.js";
|
|
40
42
|
import { expectRangeAnchorAttrs } from "../rangeAnchorAttrs.js";
|
|
41
43
|
import { marksToTextFormatting, sameFormattingValue } from "../runFormattingFromMarks.js";
|
|
@@ -161,6 +163,13 @@ const restoreParagraphPropertySource = (paragraph, baseParagraph) => {
|
|
|
161
163
|
copyParagraphPropertySource(paragraph, baseParagraph);
|
|
162
164
|
const baseFormatting = baseParagraph.formatting;
|
|
163
165
|
if (!baseFormatting) return;
|
|
166
|
+
if (baseFormatting.indentLeft !== void 0 || baseFormatting.indentRight !== void 0 || baseFormatting.indentFirstLine !== void 0 || baseFormatting.hangingIndent !== void 0) {
|
|
167
|
+
const authored = paragraphFormattingWithAuthoredIndentation(baseParagraph);
|
|
168
|
+
if ((authored?.indentLeft !== baseFormatting.indentLeft || authored?.indentRight !== baseFormatting.indentRight || authored?.indentFirstLine !== baseFormatting.indentFirstLine || authored?.hangingIndent !== baseFormatting.hangingIndent) && canonicalJson(modelParagraphFormattingEmission(paragraph.formatting)) === canonicalJson(modelParagraphFormattingEmission(authored))) {
|
|
169
|
+
paragraph.formatting = { ...baseFormatting };
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
164
173
|
const { numPr, numPrFromStyle } = baseFormatting;
|
|
165
174
|
if (!numPr || !numPrFromStyle || !isStyleSourcedParagraphNumbering(numPr, numPrFromStyle)) return;
|
|
166
175
|
if (canonicalJson(modelParagraphFormattingEmission(paragraph.formatting)) !== canonicalJson(modelParagraphFormattingEmission(baseFormatting))) return;
|
|
@@ -263,6 +272,7 @@ const restoreLinkedParagraphPropertySources = (content) => {
|
|
|
263
272
|
};
|
|
264
273
|
/** Convert a ProseMirror document to the document model. */
|
|
265
274
|
function fromProseDoc(pmDoc, baseDocument, { reuse = "none" } = {}) {
|
|
275
|
+
assertNoteReferenceOccurrences(pmDoc);
|
|
266
276
|
switch (reuse) {
|
|
267
277
|
case "none": break;
|
|
268
278
|
case "matched": panic("fromProseDoc: reuse \"matched\" is not implemented");
|
|
@@ -970,6 +980,14 @@ function convertPMParagraph(node, documentCounts, textBoxAnchorMarkers, styleRes
|
|
|
970
980
|
if (attrs.reviewCarrier) paragraph.reviewCarrier = attrs.reviewCarrier;
|
|
971
981
|
const pFormatting = paragraphAttrsToFormatting(attrs);
|
|
972
982
|
if (pFormatting) paragraph.formatting = pFormatting;
|
|
983
|
+
if (attrs.numPr?.kind === "reference") {
|
|
984
|
+
const inheritedIndentation = paragraphIndentationFromFormatting(attrs._resolvedFormatting);
|
|
985
|
+
if (inheritedIndentation) assignParagraphIndentationProjection({
|
|
986
|
+
paragraph,
|
|
987
|
+
authored: pFormatting,
|
|
988
|
+
inherited: inheritedIndentation
|
|
989
|
+
});
|
|
990
|
+
}
|
|
973
991
|
const listRendering = listRenderingFromAttrs(attrs);
|
|
974
992
|
if (listRendering) paragraph.listRendering = listRendering;
|
|
975
993
|
normalizeFoldedListNumbers(paragraph);
|
|
@@ -1373,7 +1391,8 @@ const nestInlineWrapperGroups = (items, groups, hyperlinkIndices, revisionOuterW
|
|
|
1373
1391
|
}
|
|
1374
1392
|
return coalesced;
|
|
1375
1393
|
};
|
|
1376
|
-
function extractParagraphContent(
|
|
1394
|
+
function extractParagraphContent(originalParagraph, _documentCounts, emptyHyperlinks, textBoxAnchorMarkers, skipLeadingRenderedPageBreak = false, inheritedFormattingOverride) {
|
|
1395
|
+
const paragraph = coalesceNoteReferenceOccurrences(originalParagraph);
|
|
1377
1396
|
const content = [];
|
|
1378
1397
|
const paragraphStyleContext = paragraph.type.name === "paragraph" ? paragraphRunStyleContext(paragraph) : void 0;
|
|
1379
1398
|
const formattingContext = inheritedFormattingOverride ?? {
|
|
@@ -2463,7 +2482,7 @@ const synchronizeFieldDisplayText = (content, displayText, fallbackRun) => {
|
|
|
2463
2482
|
visit(child);
|
|
2464
2483
|
continue;
|
|
2465
2484
|
}
|
|
2466
|
-
if (child.type === "hyperlink" || child.type === "inlineWrapper") visitRunsIn(child.type === "hyperlink" ? child.children : child.content, visit);
|
|
2485
|
+
if (child.type === "hyperlink" || child.type === "inlineWrapper" || child.type === "insertion" || child.type === "deletion" || child.type === "moveFrom" || child.type === "moveTo") visitRunsIn(child.type === "hyperlink" ? child.children : child.content, visit);
|
|
2467
2486
|
}
|
|
2468
2487
|
};
|
|
2469
2488
|
const visitRuns = (visit) => {
|
|
@@ -2,7 +2,7 @@ import { rangedCommentIds } from "../../docx/commentAnchorIndex.js";
|
|
|
2
2
|
import { resolveColorValueToHex } from "../../docx/drawingUtils.js";
|
|
3
3
|
import { isInlineSdtContent, isTrackedChangeWrapperChild } from "../../docx/inlineWrapperContent.js";
|
|
4
4
|
import { computeListRendering, getCachedNumberingMap } from "../../docx/numberingParser.js";
|
|
5
|
-
import { PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, createProseParagraphWithPropertySource, getDocumentParagraphPropertySourceContract, proseParagraphAttrsWithoutPropertySource, recreateProseNodeWithParagraphPropertySource, transportTableCellsWithParagraphPropertySources } from "../../docx/paragraphPropertySource.js";
|
|
5
|
+
import { PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, createProseParagraphWithPropertySource, getDocumentParagraphPropertySourceContract, paragraphFormattingWithAuthoredIndentation, proseParagraphAttrsWithoutPropertySource, recreateProseNodeWithParagraphPropertySource, transportTableCellsWithParagraphPropertySources } from "../../docx/paragraphPropertySource.js";
|
|
6
6
|
import { isBaselineVertAlign } from "../../docx/runParser.js";
|
|
7
7
|
import { replayableShapeAlternateContent } from "../../docx/shapeAlternateContent.js";
|
|
8
8
|
import { resolveTableLook } from "../../docx/tableLook.js";
|
|
@@ -25,11 +25,11 @@ import { setAutospacingBaseValue } from "../autospacingBase.js";
|
|
|
25
25
|
import { withEnclosingRevision } from "../contentControlRevisions.js";
|
|
26
26
|
import { emptyFieldRunPropertyChanges } from "../emptyFieldResultRuns.js";
|
|
27
27
|
import { planEmptyRanges } from "../emptyRangeAnchor.js";
|
|
28
|
-
import { INLINE_WRAPPER_MARK_NAME } from "../extensions/marks/InlineWrapperExtension.js";
|
|
29
28
|
import { textFormattingToMarks } from "../extensions/marks/markUtils.js";
|
|
30
29
|
import { MOVE_RANGE_BOUNDARY_NODE_NAME } from "../extensions/nodes/MoveRangeBoundaryExtension.js";
|
|
31
30
|
import { RANGE_ANCHOR_NODE_NAME } from "../extensions/nodes/RangeAnchorExtension.js";
|
|
32
31
|
import "../extensions/nodes/SdtExtension.js";
|
|
32
|
+
import { fieldRequiresStructuredContent } from "../fieldRepresentation.js";
|
|
33
33
|
import { inlineWrapperLayer } from "../inlineWrapperStack.js";
|
|
34
34
|
import { CLEARED_LIST_RENDERING_ATTRS } from "../listMarker.js";
|
|
35
35
|
import { listRenderingAttrPatch } from "../listRenderingAttrs.js";
|
|
@@ -37,13 +37,15 @@ import { stampNumberedRefFieldBaselines } from "../numberedRefFields.js";
|
|
|
37
37
|
import { paragraphNumberingAttr } from "../numberingAttr.js";
|
|
38
38
|
import { pageBreakRunParagraphProjectionDispositionForFeatures } from "../pageBreakRunProjection.js";
|
|
39
39
|
import { directionFromBidi } from "../paragraphDirection.js";
|
|
40
|
+
import { paragraphIndentationFromFormatting } from "../paragraphIndentation.js";
|
|
40
41
|
import { lineSpacingProvenanceFromSpacing } from "../paragraphSpacing.js";
|
|
41
42
|
import { RUN_IDENTITY_MARK_NAME, hasRunIdentityPayload, runIdentityAttrs } from "../runIdentity.js";
|
|
42
43
|
import { continueRunIdentitiesAcrossRevisions } from "../runIdentityAcrossRevisions.js";
|
|
43
|
-
import { getParagraphMarkSuppressionOverrides, hasDirectRunFormatting, resolveParagraphBodyRunFormatting, stripParagraphMarkFormattingForBodyRuns, stripParagraphMarkOnlyFormatting, suppressParagraphMarkFormatting } from "../runStyleFormatting.js";
|
|
44
|
+
import { getParagraphMarkSuppressionOverrides, hasDirectRunFormatting, isParagraphMarkSuppressionEligible, resolveParagraphBodyRunFormatting, stripParagraphMarkFormattingForBodyRuns, stripParagraphMarkOnlyFormatting, suppressParagraphMarkFormatting } from "../runStyleFormatting.js";
|
|
44
45
|
import { schema } from "../schema/index.js";
|
|
45
46
|
import { PRESERVED_XML_LEVELS } from "../schema/nodes.js";
|
|
46
47
|
import { extractTableParagraphOverlay, paragraphStyleCascadeAttrs, resolveRunFormattingWithoutDefaults } from "../styles/paragraphStyleCascade.js";
|
|
48
|
+
import { listIndentationProvenancePatch } from "../styles/resolvedStyleAttrs.js";
|
|
47
49
|
import { cascadeStyleTextFormatting } from "../styles/styleToggleCascade.js";
|
|
48
50
|
import { tableCellStyleRegions, tableRowBand } from "../styles/tableStyleRegions.js";
|
|
49
51
|
import { canCarryTrackedRunMark, trackedRunInlineAtomDisposition } from "../trackedRunInlineAtoms.js";
|
|
@@ -57,6 +59,19 @@ import { sdtAttrsFromProperties } from "./sdtAttrs.js";
|
|
|
57
59
|
import { panic } from "better-result";
|
|
58
60
|
import { DRAWING_RAW_XML_MODES, PARSE_WARNING_CODES, mergeParagraphNumbering } from "@stll/docx-core/model";
|
|
59
61
|
//#region src/prosemirror/conversion/toProseDoc.ts
|
|
62
|
+
/**
|
|
63
|
+
* Document to ProseMirror Conversion
|
|
64
|
+
*
|
|
65
|
+
* Converts our Document type (from DOCX parsing) to a ProseMirror document.
|
|
66
|
+
* Preserves all formatting attributes for round-trip fidelity.
|
|
67
|
+
*
|
|
68
|
+
* Style Resolution:
|
|
69
|
+
* When styles are provided, paragraph properties are resolved from the style chain:
|
|
70
|
+
* - Document defaults (docDefaults)
|
|
71
|
+
* - Normal style (if no explicit styleId)
|
|
72
|
+
* - Style chain (basedOn inheritance)
|
|
73
|
+
* - Inline properties (highest priority)
|
|
74
|
+
*/
|
|
60
75
|
const DETACHED_WATERMARK_HOST = Symbol.for("stll.detachedWatermarkHost");
|
|
61
76
|
const noPageBreakProjectionWarning = () => {};
|
|
62
77
|
const pageBreakProjectionWarn = (warn) => warn === void 0 ? noPageBreakProjectionWarning : (detail) => {
|
|
@@ -106,6 +121,11 @@ const createHyperlinkInstanceIndexAllocator = () => {
|
|
|
106
121
|
let index = 0;
|
|
107
122
|
return () => index++;
|
|
108
123
|
};
|
|
124
|
+
/** Imported occurrences belong to the projection walk, not to the referenced note. */
|
|
125
|
+
const createNoteReferenceOccurrenceAllocator = () => {
|
|
126
|
+
let index = 0;
|
|
127
|
+
return () => `source-note:${index++}`;
|
|
128
|
+
};
|
|
109
129
|
/**
|
|
110
130
|
* Find bookmark pairs across every editable inline wrapper in a document story.
|
|
111
131
|
* Each endpoint is converted at its own structural position, so a range may
|
|
@@ -232,6 +252,7 @@ function toProseDoc(document, options) {
|
|
|
232
252
|
const theme = options?.theme ?? document.package.theme ?? null;
|
|
233
253
|
const nextTextBoxGroupId = createTextBoxGroupIdFactory();
|
|
234
254
|
const nextHyperlinkInstanceIndex = createHyperlinkInstanceIndexAllocator();
|
|
255
|
+
const nextNoteReferenceOccurrenceId = createNoteReferenceOccurrenceAllocator();
|
|
235
256
|
const pairedBookmarkIds = collectPairedBookmarkIds(paragraphs);
|
|
236
257
|
const conversionContext = {
|
|
237
258
|
listRenderings: /* @__PURE__ */ new Map(),
|
|
@@ -239,6 +260,7 @@ function toProseDoc(document, options) {
|
|
|
239
260
|
theme,
|
|
240
261
|
nextTextBoxGroupId,
|
|
241
262
|
nextHyperlinkInstanceIndex,
|
|
263
|
+
nextNoteReferenceOccurrenceId,
|
|
242
264
|
pairedBookmarkIds,
|
|
243
265
|
pageBreakRunSourceDescendants: buildPageBreakRunSourceDescendantIndex(paragraphs),
|
|
244
266
|
storyRangedCommentIds: rangedCommentIds(paragraphs),
|
|
@@ -406,12 +428,26 @@ function convertParagraph(paragraph, styleResolver, context, extraRunFormatting,
|
|
|
406
428
|
let runIdentityId = 0;
|
|
407
429
|
const runScope = {
|
|
408
430
|
nextRunIdentityId: () => runIdentityId++,
|
|
431
|
+
nextNoteReferenceOccurrenceId: context.nextNoteReferenceOccurrenceId,
|
|
409
432
|
createMark: context.createMark
|
|
410
433
|
};
|
|
434
|
+
const directFormatting = paragraphFormattingWithAuthoredIndentation(paragraph);
|
|
411
435
|
const { attrs, effectiveFrame } = paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOverlay);
|
|
436
|
+
if (directFormatting === void 0) Reflect.deleteProperty(attrs, "_originalFormatting");
|
|
437
|
+
else attrs._originalFormatting = directFormatting;
|
|
412
438
|
const numPr = mergeParagraphNumbering(attrs.numPrFromStyle ?? void 0, attrs.numPr ?? void 0);
|
|
413
439
|
if (numPr?.kind === "none") Object.assign(attrs, CLEARED_LIST_RENDERING_ATTRS);
|
|
414
440
|
else if (context.numbering !== void 0 && numPr?.kind === "reference") {
|
|
441
|
+
Object.assign(attrs, listIndentationProvenancePatch({
|
|
442
|
+
direct: paragraphIndentationFromFormatting(directFormatting),
|
|
443
|
+
styleFormatting: attrs._styleResolvedFormatting,
|
|
444
|
+
numberingSource: attrs.numPrFromStyle == null ? "paragraph" : "style",
|
|
445
|
+
numPr: {
|
|
446
|
+
numId: numPr.numId,
|
|
447
|
+
ilvl: numPr.ilvl ?? 0
|
|
448
|
+
},
|
|
449
|
+
numbering: context.numbering
|
|
450
|
+
}));
|
|
415
451
|
const { rendering, nextSlotOffset } = resolveListRendering(numPr, context);
|
|
416
452
|
if (rendering !== null) {
|
|
417
453
|
const cached = paragraph.listRendering;
|
|
@@ -476,7 +512,7 @@ function convertParagraph(paragraph, styleResolver, context, extraRunFormatting,
|
|
|
476
512
|
...!hasCharacterStyle ? { implicitCharacterStyleApplied: true } : {},
|
|
477
513
|
toggleCascade: inheritedToggleCascade
|
|
478
514
|
};
|
|
479
|
-
if (!(
|
|
515
|
+
if (!isParagraphMarkSuppressionEligible(formatting)) return {
|
|
480
516
|
formatting: defaultRunFormatting,
|
|
481
517
|
implicitCharacterStyleApplied: true,
|
|
482
518
|
toggleCascade: defaultToggleCascade
|
|
@@ -643,7 +679,7 @@ function applyCommentMarks(nodes, commentIds) {
|
|
|
643
679
|
if (!commentMarkType) return nodes;
|
|
644
680
|
const commentMarks = [...commentIds].toSorted((left, right) => left - right).map((commentId) => commentMarkType.create({ commentId }));
|
|
645
681
|
return nodes.map((node) => {
|
|
646
|
-
if (!node.
|
|
682
|
+
if (!node.isInline) return node;
|
|
647
683
|
let marks = node.marks;
|
|
648
684
|
for (const commentMark of commentMarks) marks = commentMark.addToSet(marks);
|
|
649
685
|
return node.mark(marks);
|
|
@@ -1290,6 +1326,7 @@ function convertTableCell({ cell, styleResolver, context, isHeader, gridWidthPer
|
|
|
1290
1326
|
function standaloneTableCellToProseMirror(cell, nodeType) {
|
|
1291
1327
|
const nextTextBoxGroupId = createTextBoxGroupIdFactory();
|
|
1292
1328
|
const nextHyperlinkInstanceIndex = createHyperlinkInstanceIndexAllocator();
|
|
1329
|
+
const nextNoteReferenceOccurrenceId = createNoteReferenceOccurrenceAllocator();
|
|
1293
1330
|
const pageBreakRunSourceDescendants = buildPageBreakRunSourceDescendantIndex(cell.content);
|
|
1294
1331
|
reportSourceContainerPageBreakRun(cell.content, "table-cell", pageBreakRunSourceDescendants, noPageBreakProjectionWarning);
|
|
1295
1332
|
return convertTableCell({
|
|
@@ -1301,6 +1338,7 @@ function standaloneTableCellToProseMirror(cell, nodeType) {
|
|
|
1301
1338
|
numbering: void 0,
|
|
1302
1339
|
nextTextBoxGroupId,
|
|
1303
1340
|
nextHyperlinkInstanceIndex,
|
|
1341
|
+
nextNoteReferenceOccurrenceId,
|
|
1304
1342
|
pairedBookmarkIds: collectPairedBookmarkIds(cell.content),
|
|
1305
1343
|
pageBreakRunSourceDescendants,
|
|
1306
1344
|
storyRangedCommentIds: rangedCommentIds(cell.content),
|
|
@@ -1324,14 +1362,56 @@ function convertField(field, { getInheritedRunFormatting, styleResolver, nextHyp
|
|
|
1324
1362
|
let fieldFormatting;
|
|
1325
1363
|
let fieldPropertyChanges;
|
|
1326
1364
|
const inlineNodes = [];
|
|
1327
|
-
const hasStructuredSourceContent = fieldResultHasPageBreakContent(field) || field.type === "simpleField" && field.content.some((content) => content.type === "hyperlink" || content.type === "preservedInline" || content.type === "inlineWrapper");
|
|
1365
|
+
const hasStructuredSourceContent = fieldResultHasPageBreakContent(field) || field.type === "simpleField" && field.content.some((content) => content.type === "hyperlink" || content.type === "preservedInline" || content.type === "inlineWrapper" || content.type === "insertion" || content.type === "deletion" || content.type === "moveFrom" || content.type === "moveTo");
|
|
1328
1366
|
const appendRun = (run, into) => {
|
|
1329
1367
|
for (const content of run.content) if (content.type === "text") displayText += content.text;
|
|
1330
1368
|
fieldFormatting ??= run.formatting;
|
|
1331
1369
|
fieldPropertyChanges ??= run.propertyChanges;
|
|
1332
|
-
if (!hasStructuredSourceContent) return;
|
|
1370
|
+
if (field.type !== "simpleField" && !hasStructuredSourceContent) return;
|
|
1333
1371
|
into.push(...convertRun(run, getInheritedRunFormatting(run.formatting, field.fieldType), runScope, styleResolver, textBoxAnchors));
|
|
1334
1372
|
};
|
|
1373
|
+
const collectDisplay = (items) => {
|
|
1374
|
+
for (const item of items) switch (item.type) {
|
|
1375
|
+
case "run":
|
|
1376
|
+
for (const child of item.content) if (child.type === "text") displayText += child.text;
|
|
1377
|
+
fieldFormatting ??= item.formatting;
|
|
1378
|
+
fieldPropertyChanges ??= item.propertyChanges;
|
|
1379
|
+
break;
|
|
1380
|
+
case "hyperlink":
|
|
1381
|
+
collectDisplay(item.children);
|
|
1382
|
+
break;
|
|
1383
|
+
case "inlineWrapper":
|
|
1384
|
+
case "inlineSdt":
|
|
1385
|
+
case "insertion":
|
|
1386
|
+
case "deletion":
|
|
1387
|
+
case "moveFrom":
|
|
1388
|
+
case "moveTo":
|
|
1389
|
+
collectDisplay(item.content);
|
|
1390
|
+
break;
|
|
1391
|
+
case "simpleField":
|
|
1392
|
+
collectDisplay(item.content);
|
|
1393
|
+
break;
|
|
1394
|
+
case "complexField":
|
|
1395
|
+
collectDisplay(item.fieldResult);
|
|
1396
|
+
break;
|
|
1397
|
+
case "preservedInline":
|
|
1398
|
+
displayText += item.text;
|
|
1399
|
+
break;
|
|
1400
|
+
case "mathEquation":
|
|
1401
|
+
displayText += item.plainText ?? "";
|
|
1402
|
+
break;
|
|
1403
|
+
case "bookmarkStart":
|
|
1404
|
+
case "bookmarkEnd":
|
|
1405
|
+
case "commentRangeStart":
|
|
1406
|
+
case "commentRangeEnd":
|
|
1407
|
+
case "commentReference":
|
|
1408
|
+
case "moveFromRangeStart":
|
|
1409
|
+
case "moveFromRangeEnd":
|
|
1410
|
+
case "moveToRangeStart":
|
|
1411
|
+
case "moveToRangeEnd": break;
|
|
1412
|
+
default: panic(`Unsupported field display content: ${JSON.stringify(item)}`);
|
|
1413
|
+
}
|
|
1414
|
+
};
|
|
1335
1415
|
if (field.type === "simpleField") for (const { content, stack } of withInlineWrapperStacks(field.content)) {
|
|
1336
1416
|
const itemNodes = [];
|
|
1337
1417
|
switch (content.type) {
|
|
@@ -1355,6 +1435,16 @@ function convertField(field, { getInheritedRunFormatting, styleResolver, nextHyp
|
|
|
1355
1435
|
runScope
|
|
1356
1436
|
}));
|
|
1357
1437
|
break;
|
|
1438
|
+
case "insertion":
|
|
1439
|
+
case "deletion":
|
|
1440
|
+
case "moveFrom":
|
|
1441
|
+
case "moveTo":
|
|
1442
|
+
collectDisplay(content.content);
|
|
1443
|
+
itemNodes.push(...convertTrackedChange(content, content.type === "insertion" || content.type === "moveTo" ? "insertion" : "deletion", nextHyperlinkInstanceIndex, runScope, {
|
|
1444
|
+
current: getInheritedRunFormatting,
|
|
1445
|
+
historical: getInheritedRunFormatting
|
|
1446
|
+
}, styleResolver, content.type === "moveFrom" || content.type === "moveTo" ? content.type : null, textBoxAnchors));
|
|
1447
|
+
break;
|
|
1358
1448
|
default: break;
|
|
1359
1449
|
}
|
|
1360
1450
|
inlineNodes.push(...withInlineWrapperMark(itemNodes, stack));
|
|
@@ -1368,11 +1458,7 @@ function convertField(field, { getInheritedRunFormatting, styleResolver, nextHyp
|
|
|
1368
1458
|
styleResolver,
|
|
1369
1459
|
createMark: runScope.createMark
|
|
1370
1460
|
});
|
|
1371
|
-
const
|
|
1372
|
-
const hasConvertedPageBreakContent = inlineNodes.some((node) => node.type.name === "pageBreakRun");
|
|
1373
|
-
const hasConvertedPreservedContent = inlineNodes.some((node) => node.type.name === "preservedXml");
|
|
1374
|
-
const hasConvertedWrapperContent = inlineNodes.some((node) => node.marks.some((mark) => mark.type.name === INLINE_WRAPPER_MARK_NAME));
|
|
1375
|
-
const createStructuredField = hasConvertedPageBreakContent || hasConvertedPreservedContent || hasStructuredSourceContent && (hasConvertedHyperlinkContent || hasConvertedWrapperContent);
|
|
1461
|
+
const createStructuredField = fieldRequiresStructuredContent(inlineNodes);
|
|
1376
1462
|
const resultRuns = field.type === "simpleField" ? field.content.flatMap((content) => content.type === "run" ? [content] : []) : field.fieldResult;
|
|
1377
1463
|
const emptyResultRuns = displayText === "" && resultRuns.length > 0 && (field.type === "complexField" || field.content.length === resultRuns.length) && resultRuns.every((run) => run.content.every((item) => item.type === "text" && item.text === "")) ? resultRuns : void 0;
|
|
1378
1464
|
const resultPropertyChanges = emptyResultRuns ? emptyFieldRunPropertyChanges(emptyResultRuns) : fieldPropertyChanges;
|
|
@@ -1564,7 +1650,14 @@ function convertRun(run, resolvedStyleFormatting, runScope, styleResolver, textB
|
|
|
1564
1650
|
const identity = runIdentityMark(run, runScope.nextRunIdentityId);
|
|
1565
1651
|
if (identity) marks.push(identity);
|
|
1566
1652
|
for (const content of run.content) {
|
|
1567
|
-
const contentNodes = convertRunContent(
|
|
1653
|
+
const contentNodes = convertRunContent({
|
|
1654
|
+
content,
|
|
1655
|
+
marks,
|
|
1656
|
+
formatting: mergedFormatting,
|
|
1657
|
+
textBoxAnchors,
|
|
1658
|
+
authoredFormatting: run.formatting,
|
|
1659
|
+
nextNoteReferenceOccurrenceId: runScope.nextNoteReferenceOccurrenceId
|
|
1660
|
+
});
|
|
1568
1661
|
nodes.push(...contentNodes);
|
|
1569
1662
|
}
|
|
1570
1663
|
return nodes;
|
|
@@ -1970,10 +2063,7 @@ const noteReferenceVertAlign = (vertAlign) => {
|
|
|
1970
2063
|
* run was authored with.
|
|
1971
2064
|
*/
|
|
1972
2065
|
const carriedRunFormatting = (formatting) => formatting && Object.keys(formatting).length > 0 ? formatting : void 0;
|
|
1973
|
-
|
|
1974
|
-
* Convert RunContent to ProseMirror nodes
|
|
1975
|
-
*/
|
|
1976
|
-
function convertRunContent(content, marks, formatting, textBoxAnchors, authoredFormatting) {
|
|
2066
|
+
function convertRunContent({ content, marks, formatting, textBoxAnchors, authoredFormatting, nextNoteReferenceOccurrenceId }) {
|
|
1977
2067
|
switch (content.type) {
|
|
1978
2068
|
case "noteMarker": return [schema.node("noteMarker", { kind: content.kind }).mark(marks)];
|
|
1979
2069
|
case "text":
|
|
@@ -2013,6 +2103,7 @@ function convertRunContent(content, marks, formatting, textBoxAnchors, authoredF
|
|
|
2013
2103
|
case "footnoteRef": {
|
|
2014
2104
|
const footnoteMark = schema.mark("footnoteRef", {
|
|
2015
2105
|
id: content.id.toString(),
|
|
2106
|
+
occurrenceId: nextNoteReferenceOccurrenceId(),
|
|
2016
2107
|
noteType: "footnote",
|
|
2017
2108
|
vertAlign: noteReferenceVertAlign(formatting?.vertAlign),
|
|
2018
2109
|
customMarkFollows: content.customMarkFollows
|
|
@@ -2022,6 +2113,7 @@ function convertRunContent(content, marks, formatting, textBoxAnchors, authoredF
|
|
|
2022
2113
|
case "endnoteRef": {
|
|
2023
2114
|
const endnoteMark = schema.mark("footnoteRef", {
|
|
2024
2115
|
id: content.id.toString(),
|
|
2116
|
+
occurrenceId: nextNoteReferenceOccurrenceId(),
|
|
2025
2117
|
noteType: "endnote",
|
|
2026
2118
|
vertAlign: noteReferenceVertAlign(formatting?.vertAlign),
|
|
2027
2119
|
customMarkFollows: content.customMarkFollows
|
|
@@ -2251,7 +2343,14 @@ function convertHyperlink(hyperlink, { getInheritedRunFormatting, styleResolver,
|
|
|
2251
2343
|
const identity = runIdentityMark(child, runScope.nextRunIdentityId);
|
|
2252
2344
|
if (identity) runMarks.push(identity);
|
|
2253
2345
|
const allMarks = [...runMarks, linkMark];
|
|
2254
|
-
for (const content of child.content) childNodes.push(...convertRunContent(
|
|
2346
|
+
for (const content of child.content) childNodes.push(...convertRunContent({
|
|
2347
|
+
content,
|
|
2348
|
+
marks: allMarks,
|
|
2349
|
+
formatting: mergedFormatting,
|
|
2350
|
+
textBoxAnchors,
|
|
2351
|
+
authoredFormatting: child.formatting,
|
|
2352
|
+
nextNoteReferenceOccurrenceId: runScope.nextNoteReferenceOccurrenceId
|
|
2353
|
+
}));
|
|
2255
2354
|
break;
|
|
2256
2355
|
}
|
|
2257
2356
|
default: break;
|
|
@@ -2695,6 +2794,7 @@ function headerFooterToProseDoc(content, options) {
|
|
|
2695
2794
|
const theme = options?.theme ?? null;
|
|
2696
2795
|
const nextTextBoxGroupId = createTextBoxGroupIdFactory();
|
|
2697
2796
|
const nextHyperlinkInstanceIndex = createHyperlinkInstanceIndexAllocator();
|
|
2797
|
+
const nextNoteReferenceOccurrenceId = createNoteReferenceOccurrenceAllocator();
|
|
2698
2798
|
const pairedBookmarkIds = collectPairedBookmarkIds(content);
|
|
2699
2799
|
const conversionContext = {
|
|
2700
2800
|
listRenderings: /* @__PURE__ */ new Map(),
|
|
@@ -2702,6 +2802,7 @@ function headerFooterToProseDoc(content, options) {
|
|
|
2702
2802
|
numbering: options?.numbering === void 0 ? void 0 : getCachedNumberingMap(options.numbering),
|
|
2703
2803
|
nextTextBoxGroupId,
|
|
2704
2804
|
nextHyperlinkInstanceIndex,
|
|
2805
|
+
nextNoteReferenceOccurrenceId,
|
|
2705
2806
|
pairedBookmarkIds,
|
|
2706
2807
|
pageBreakRunSourceDescendants: buildPageBreakRunSourceDescendantIndex(content),
|
|
2707
2808
|
storyRangedCommentIds: rangedCommentIds(content),
|
|
@@ -14,12 +14,14 @@ import { CLEARED_LIST_RENDERING_ATTRS } from "../../listMarker.js";
|
|
|
14
14
|
import { directParagraphAlignment } from "../../paragraphAlignment.js";
|
|
15
15
|
import { directionIsRtl } from "../../paragraphDirection.js";
|
|
16
16
|
import { directParagraphIndentation } from "../../paragraphIndentation.js";
|
|
17
|
+
import { recordReplacedParagraphProperties } from "../../paragraphPropertyCarry.js";
|
|
17
18
|
import { directParagraphSpacing, withDirectParagraphSpacing } from "../../paragraphSpacing.js";
|
|
18
19
|
import { getDocumentNumbering } from "../../plugins/documentNumbering.js";
|
|
19
20
|
import { getDocumentBuiltInStyles, getDocumentStyleResolver } from "../../plugins/documentStyleState.js";
|
|
21
|
+
import { SUGGESTION_META, makeRevisionInfo } from "../../plugins/suggestionMode.js";
|
|
20
22
|
import { rebaseParagraphRuns } from "../../rebaseParagraphRuns.js";
|
|
21
23
|
import { mintSectionProperties, parseSectionBreakType, sectionBreakTypeOf } from "../../sectionCarrier.js";
|
|
22
|
-
import { listAttrsFromResolvedStyle,
|
|
24
|
+
import { listAttrsFromResolvedStyle, listIndentationProvenancePatch, paragraphAttrsFromResolvedStyle } from "../../styles/resolvedStyleAttrs.js";
|
|
23
25
|
import { createNodeExtension } from "../create.js";
|
|
24
26
|
import { headingOutlineLevel, paragraphNumberingLevel, paragraphNumberingReferenceId } from "@stll/docx-core/model";
|
|
25
27
|
import { Fragment } from "prosemirror-model";
|
|
@@ -263,6 +265,7 @@ const paragraphNodeSpec = {
|
|
|
263
265
|
_emptyHyperlinks: { default: null },
|
|
264
266
|
_originalFormatting: { default: null },
|
|
265
267
|
_resolvedFormatting: { default: void 0 },
|
|
268
|
+
_styleResolvedFormatting: { default: void 0 },
|
|
266
269
|
_autospacingBase: { default: null },
|
|
267
270
|
_sectionProperties: { default: null },
|
|
268
271
|
_propertyChanges: { default: null },
|
|
@@ -548,6 +551,7 @@ function makeApplyStyle() {
|
|
|
548
551
|
const { $from, $to } = state.selection;
|
|
549
552
|
if (!dispatch) return true;
|
|
550
553
|
let tr = state.tr;
|
|
554
|
+
const revision = makeRevisionInfo(state);
|
|
551
555
|
const seen = /* @__PURE__ */ new Set();
|
|
552
556
|
state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => {
|
|
553
557
|
if (node.type.name === "paragraph" && !seen.has(pos)) {
|
|
@@ -583,12 +587,24 @@ function makeApplyStyle() {
|
|
|
583
587
|
numPr: null,
|
|
584
588
|
numPrFromStyle: null
|
|
585
589
|
});
|
|
586
|
-
else if (directNumId !== void 0) Object.assign(newAttrs,
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
+
else if (directNumId !== void 0) Object.assign(newAttrs, listIndentationProvenancePatch({
|
|
591
|
+
direct: restyledIndentation(styleAttrs, restyledOriginal),
|
|
592
|
+
styleFormatting: resolvedAttrs.paragraphFormatting,
|
|
593
|
+
numberingSource: "paragraph",
|
|
594
|
+
numPr: {
|
|
595
|
+
numId: directNumId,
|
|
596
|
+
ilvl: paragraphNumberingLevel(current.numPr ?? void 0) ?? 0
|
|
597
|
+
},
|
|
598
|
+
numbering: resolvedAttrs.numbering ?? getDocumentNumbering(state)
|
|
599
|
+
}));
|
|
590
600
|
}
|
|
591
601
|
tr = tr.setNodeMarkup(pos, void 0, newAttrs);
|
|
602
|
+
if (revision) recordReplacedParagraphProperties({
|
|
603
|
+
tr,
|
|
604
|
+
position: pos,
|
|
605
|
+
replaced: node,
|
|
606
|
+
revision
|
|
607
|
+
});
|
|
592
608
|
rebaseParagraphRuns({
|
|
593
609
|
tr,
|
|
594
610
|
position: pos,
|
|
@@ -598,6 +614,7 @@ function makeApplyStyle() {
|
|
|
598
614
|
});
|
|
599
615
|
}
|
|
600
616
|
});
|
|
617
|
+
if (revision) tr.setMeta(SUGGESTION_META, true);
|
|
601
618
|
dispatch(tr.scrollIntoView());
|
|
602
619
|
return true;
|
|
603
620
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { mergeTextFormatting } from "../../../utils/textFormattingMerge.js";
|
|
2
|
-
import { expectCharacterStyleMarkAttrs, expectRunFormattingOverrideMarkAttrs } from "../../attrs/index.js";
|
|
2
|
+
import { expectCharacterStyleMarkAttrs, expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs } from "../../attrs/index.js";
|
|
3
3
|
import { clearIndentOnBackspace } from "../../commands/clearParagraphIndent.js";
|
|
4
4
|
import { keepSectionBreaksOnSurvivingMarks } from "../../commands/sectionBreak.js";
|
|
5
5
|
import { getDocumentStyleResolver } from "../../plugins/documentStyleState.js";
|
|
@@ -23,27 +23,55 @@ function chainCommands(...commands) {
|
|
|
23
23
|
return false;
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
|
-
/**
|
|
27
|
-
* Custom Enter handler: splits the block, inherits style-related attrs,
|
|
28
|
-
* clears paragraph borders, and preserves run formatting on the new paragraph.
|
|
29
|
-
*
|
|
30
|
-
* splitBlock creates a new paragraph with default attrs (all null),
|
|
31
|
-
* so we must manually copy style-related attrs from the source paragraph.
|
|
32
|
-
* Word does NOT propagate paragraph borders (w:pBdr) on Enter.
|
|
33
|
-
*/
|
|
34
26
|
const INHERITED_PARA_ATTRS = [
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
27
|
+
{
|
|
28
|
+
attr: "defaultTextFormatting",
|
|
29
|
+
formattingFields: ["runProperties"]
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
attr: "styleId",
|
|
33
|
+
formattingFields: ["styleId"]
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
attr: "_tableOfContentsLevel",
|
|
37
|
+
formattingFields: []
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
attr: "lineSpacing",
|
|
41
|
+
formattingFields: ["lineSpacing", "spacingPreservedAttributes"]
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
attr: "lineSpacingRule",
|
|
45
|
+
formattingFields: ["lineSpacingRule", "spacingPreservedAttributes"]
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
attr: "snapToGrid",
|
|
49
|
+
formattingFields: ["snapToGrid"]
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
attr: "spaceAfter",
|
|
53
|
+
formattingFields: ["spaceAfter", "spacingPreservedAttributes"]
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
attr: "spaceBefore",
|
|
57
|
+
formattingFields: ["spaceBefore", "spacingPreservedAttributes"]
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
attr: "spacingExplicit",
|
|
61
|
+
formattingFields: ["spacingExplicit"]
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
attr: "spacingFromDocDefaults",
|
|
65
|
+
formattingFields: []
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
attr: "spacingFromImplicitDefaultStyle",
|
|
69
|
+
formattingFields: []
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
attr: "contextualSpacing",
|
|
73
|
+
formattingFields: ["contextualSpacing"]
|
|
74
|
+
}
|
|
47
75
|
];
|
|
48
76
|
/** Style formatting needed when the caret has no marks of its own. */
|
|
49
77
|
const STYLE_MARK_NAMES = /* @__PURE__ */ new Set([
|
|
@@ -142,10 +170,31 @@ const splitBlockClearBorders = (state, dispatch, view) => {
|
|
|
142
170
|
}
|
|
143
171
|
const newAttrs = { ...newPara.attrs };
|
|
144
172
|
let attrsChanged = false;
|
|
145
|
-
if (sourcePara)
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
173
|
+
if (sourcePara) {
|
|
174
|
+
const sourceAttrs = expectParagraphAttrs(sourcePara);
|
|
175
|
+
const addedAttrs = expectParagraphAttrs(newPara);
|
|
176
|
+
const originalFormatting = { ...addedAttrs._originalFormatting };
|
|
177
|
+
const resolvedFormatting = { ...addedAttrs._resolvedFormatting };
|
|
178
|
+
for (const { attr, formattingFields } of INHERITED_PARA_ATTRS) {
|
|
179
|
+
const srcVal = sourceAttrs[attr];
|
|
180
|
+
if (srcVal !== null && newAttrs[attr] === null) {
|
|
181
|
+
newAttrs[attr] = srcVal;
|
|
182
|
+
attrsChanged = true;
|
|
183
|
+
}
|
|
184
|
+
if (newAttrs[attr] !== srcVal) continue;
|
|
185
|
+
for (const field of formattingFields) {
|
|
186
|
+
const original = sourceAttrs._originalFormatting?.[field];
|
|
187
|
+
if (original !== void 0) Reflect.set(originalFormatting, field, original);
|
|
188
|
+
const resolved = sourceAttrs._resolvedFormatting?.[field];
|
|
189
|
+
if (resolved !== void 0) Reflect.set(resolvedFormatting, field, resolved);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (Object.keys(originalFormatting).length > 0) {
|
|
193
|
+
newAttrs["_originalFormatting"] = originalFormatting;
|
|
194
|
+
attrsChanged = true;
|
|
195
|
+
}
|
|
196
|
+
if (Object.keys(resolvedFormatting).length > 0) {
|
|
197
|
+
newAttrs["_resolvedFormatting"] = resolvedFormatting;
|
|
149
198
|
attrsChanged = true;
|
|
150
199
|
}
|
|
151
200
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { expectFootnoteRefMarkAttrs } from "../../attrs/index.js";
|
|
2
|
+
import { mintNoteReferenceOccurrenceId, noteReferenceOccurrencePlugin } from "../../noteReferenceOccurrences.js";
|
|
2
3
|
import { suggestRangeDeletion, suggestionModeKey } from "../../plugins/suggestionMode.js";
|
|
3
4
|
import { createMarkExtension } from "../create.js";
|
|
4
5
|
import { expandNoteReferenceDeletionRange, noteReferenceRanges } from "./noteReferenceDeletion.js";
|
|
@@ -9,7 +10,9 @@ import { panic } from "better-result";
|
|
|
9
10
|
*
|
|
10
11
|
* Provides footnoteRef mark + insert/delete commands for footnotes and endnotes.
|
|
11
12
|
*/
|
|
13
|
+
const NOTE_REFERENCE_PARSE_PRIORITY = 60;
|
|
12
14
|
const noteRefAttrsFromDom = (dom, noteType, vertAlign) => ({
|
|
15
|
+
occurrenceId: dom.dataset["noteOccurrence"] ?? mintNoteReferenceOccurrenceId(),
|
|
13
16
|
id: dom.dataset["id"] ?? "",
|
|
14
17
|
noteType: dom.dataset["noteType"] ?? noteType,
|
|
15
18
|
...vertAlign ? { vertAlign } : {}
|
|
@@ -21,6 +24,7 @@ const FootnoteRefExtension = createMarkExtension({
|
|
|
21
24
|
inclusive: false,
|
|
22
25
|
attrs: {
|
|
23
26
|
id: {},
|
|
27
|
+
occurrenceId: {},
|
|
24
28
|
noteType: { default: "footnote" },
|
|
25
29
|
vertAlign: { default: null },
|
|
26
30
|
customMarkFollows: { default: null }
|
|
@@ -28,18 +32,22 @@ const FootnoteRefExtension = createMarkExtension({
|
|
|
28
32
|
parseDOM: [
|
|
29
33
|
{
|
|
30
34
|
tag: "sup.docx-footnote-ref",
|
|
35
|
+
priority: NOTE_REFERENCE_PARSE_PRIORITY,
|
|
31
36
|
getAttrs: (dom) => noteRefAttrsFromDom(dom, "footnote", "superscript")
|
|
32
37
|
},
|
|
33
38
|
{
|
|
34
39
|
tag: "sup.docx-endnote-ref",
|
|
40
|
+
priority: NOTE_REFERENCE_PARSE_PRIORITY,
|
|
35
41
|
getAttrs: (dom) => noteRefAttrsFromDom(dom, "endnote", "superscript")
|
|
36
42
|
},
|
|
37
43
|
{
|
|
38
44
|
tag: "span.docx-footnote-ref",
|
|
45
|
+
priority: NOTE_REFERENCE_PARSE_PRIORITY,
|
|
39
46
|
getAttrs: (dom) => noteRefAttrsFromDom(dom, "footnote", "baseline")
|
|
40
47
|
},
|
|
41
48
|
{
|
|
42
49
|
tag: "span.docx-endnote-ref",
|
|
50
|
+
priority: NOTE_REFERENCE_PARSE_PRIORITY,
|
|
43
51
|
getAttrs: (dom) => noteRefAttrsFromDom(dom, "endnote", "baseline")
|
|
44
52
|
}
|
|
45
53
|
],
|
|
@@ -53,6 +61,7 @@ const FootnoteRefExtension = createMarkExtension({
|
|
|
53
61
|
{
|
|
54
62
|
class: `docx-${noteType}-ref ${isSuperscript ? "docx-note-ref-superscript" : "docx-note-ref-baseline"}`,
|
|
55
63
|
"data-id": id,
|
|
64
|
+
"data-note-occurrence": attrs.occurrenceId,
|
|
56
65
|
"data-note-type": noteType
|
|
57
66
|
},
|
|
58
67
|
0
|
|
@@ -76,6 +85,7 @@ const FootnoteRefExtension = createMarkExtension({
|
|
|
76
85
|
if (!footnoteRefType) panic("Missing mark type: footnoteRef");
|
|
77
86
|
const mark = footnoteRefType.create({
|
|
78
87
|
id: String(id),
|
|
88
|
+
occurrenceId: mintNoteReferenceOccurrenceId(),
|
|
79
89
|
noteType,
|
|
80
90
|
vertAlign: "superscript"
|
|
81
91
|
});
|
|
@@ -100,6 +110,7 @@ const FootnoteRefExtension = createMarkExtension({
|
|
|
100
110
|
return true;
|
|
101
111
|
};
|
|
102
112
|
return {
|
|
113
|
+
plugins: [noteReferenceOccurrencePlugin()],
|
|
103
114
|
keyboardShortcuts: {
|
|
104
115
|
Backspace: deleteWholeNoteReference("backward"),
|
|
105
116
|
Delete: deleteWholeNoteReference("forward")
|