@stll/folio-core 0.55.0 → 0.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-edits/apply.js +214 -52
- package/dist/ai-edits/batch-claims.d.ts +3 -1
- package/dist/ai-edits/batch-claims.js +25 -1
- package/dist/ai-edits/headless.js +2 -2
- package/dist/ai-edits/table-row-column-mutations.js +17 -3
- package/dist/ai-edits/types.d.ts +7 -1
- package/dist/ai-suggestions/apply.js +20 -1
- package/dist/compare/compare.js +1 -0
- package/dist/compare/inline-atoms.js +40 -16
- package/dist/compare/inline-provenance.js +12 -5
- package/dist/compare/reproducible-package.d.ts +0 -17
- package/dist/compare/reproducible-package.js +12 -18
- package/dist/compat/eigenpal.d.ts +2 -1
- package/dist/compat/eigenpal.js +2 -1
- package/dist/controller/canonicalClipboard.d.ts +23 -0
- package/dist/controller/canonicalClipboard.js +482 -0
- package/dist/controller/canonicalClipboardResources.d.ts +21 -0
- package/dist/controller/canonicalClipboardResources.js +382 -0
- package/dist/controller/canonicalComments.d.ts +41 -0
- package/dist/controller/canonicalComments.js +152 -0
- package/dist/controller/canonicalComposition.d.ts +24 -3
- package/dist/controller/canonicalComposition.js +208 -48
- package/dist/controller/canonicalInlineProjection.d.ts +118 -0
- package/dist/controller/canonicalInlineProjection.js +476 -0
- package/dist/controller/canonicalInput.d.ts +13 -4
- package/dist/controller/canonicalInput.js +62 -14
- package/dist/controller/canonicalInputTimer.d.ts +16 -0
- package/dist/controller/canonicalInputTimer.js +34 -0
- package/dist/controller/canonicalPublicOperations.d.ts +48 -0
- package/dist/controller/canonicalPublicOperations.js +648 -0
- package/dist/controller/canonicalSelection.d.ts +18 -0
- package/dist/controller/canonicalSelection.js +32 -0
- package/dist/controller/canonicalSession.d.ts +27 -6
- package/dist/controller/canonicalSession.js +298 -116
- package/dist/controller/canonicalStoryEditor.d.ts +7 -3
- package/dist/controller/canonicalStoryEditor.js +27 -2
- package/dist/controller/canonicalStructure.js +57 -4
- package/dist/controller/canonicalTocSelection.d.ts +11 -0
- package/dist/controller/canonicalTocSelection.js +43 -0
- package/dist/controller/folioEditor.d.ts +2 -9
- package/dist/controller/folioEditor.js +18 -4
- package/dist/controller/headerFooterEditorManager.d.ts +2 -1
- package/dist/controller/headerFooterEditorManager.js +26 -11
- package/dist/controller/hiddenEditorApi.d.ts +24 -3
- package/dist/controller/hiddenEditorApi.js +8 -0
- package/dist/controller/hiddenEditorManager.d.ts +5 -1
- package/dist/controller/hiddenEditorManager.js +378 -43
- package/dist/controller/noteEditorManager.d.ts +2 -1
- package/dist/controller/noteEditorManager.js +29 -13
- package/dist/document-operations.d.ts +8 -1
- package/dist/document-operations.js +6 -4
- package/dist/docx/blockPlainText.d.ts +1 -1
- package/dist/docx/blockPlainText.js +11 -3
- package/dist/docx/builtInStyles.js +13 -6
- package/dist/docx/canonicalResourceSave.d.ts +16 -0
- package/dist/docx/canonicalResourceSave.js +27 -0
- package/dist/docx/canonicalSave.d.ts +29 -0
- package/dist/docx/canonicalSave.js +101 -0
- package/dist/docx/canonicalStoryRepack.d.ts +1 -1
- package/dist/docx/canonicalStoryRepack.js +38 -5
- package/dist/docx/containerChildren.gen.d.ts +3 -1
- package/dist/docx/containerChildren.gen.js +33 -1
- package/dist/docx/documentParser.d.ts +1 -13
- package/dist/docx/documentParser.js +1 -47
- package/dist/docx/ensureParaIds.js +10 -4
- package/dist/docx/fieldParser.js +14 -2
- package/dist/docx/footnoteParser.d.ts +1 -11
- package/dist/docx/footnoteParser.js +1 -16
- package/dist/docx/headerFooterParser.d.ts +1 -9
- package/dist/docx/headerFooterParser.js +1 -12
- package/dist/docx/headerFooterVerbatim.d.ts +26 -1
- package/dist/docx/headerFooterVerbatim.js +81 -3
- package/dist/docx/hyperlinkParser.d.ts +1 -1
- package/dist/docx/hyperlinkParser.js +20 -1
- package/dist/docx/imageParser.d.ts +13 -1
- package/dist/docx/imageParser.js +20 -11
- package/dist/docx/inlineWrapperContent.d.ts +4 -4
- package/dist/docx/inlineWrapperContent.js +4 -4
- package/dist/docx/linkedSdtPreservation.d.ts +10 -0
- package/dist/docx/linkedSdtPreservation.js +37 -0
- package/dist/docx/metadataPrivacy.js +6 -1
- package/dist/docx/packageParts.js +9 -3
- package/dist/docx/paragraphParser.js +88 -67
- package/dist/docx/paragraphPropertySource.d.ts +22 -1
- package/dist/docx/paragraphPropertySource.js +109 -2
- package/dist/docx/parser.js +2 -1
- package/dist/docx/preservedRunContent.js +2 -1
- package/dist/docx/relsParser.js +26 -2
- package/dist/docx/removeHeaderFooterParts.js +17 -6
- package/dist/docx/rezip.d.ts +49 -5
- package/dist/docx/rezip.js +754 -235
- package/dist/docx/saveDiagnostics.d.ts +11 -0
- package/dist/docx/selectiveSave.d.ts +2 -1
- package/dist/docx/selectiveSave.js +42 -11
- package/dist/docx/selectiveXmlPatch.js +7 -5
- package/dist/docx/serializer/commentSerializer.d.ts +4 -1
- package/dist/docx/serializer/commentSerializer.js +7 -3
- package/dist/docx/serializer/documentSerializer.d.ts +9 -2
- package/dist/docx/serializer/documentSerializer.js +29 -10
- package/dist/docx/serializer/paragraphSerializer.js +207 -94
- package/dist/docx/server/applyDocxXmlPatchProposal.js +14 -9
- package/dist/docx/server/materializeYjsDocx.js +14 -6
- package/dist/docx/server/migrateYjsAttrSchema.js +17 -5
- package/dist/docx/storyBlockReplay.d.ts +21 -1
- package/dist/docx/storyBlockReplay.js +113 -9
- package/dist/docx/storyPlainText.d.ts +20 -0
- package/dist/docx/storyPlainText.js +23 -0
- package/dist/docx/structuralXmlPatch.js +10 -22
- package/dist/docx/styleParser.d.ts +5 -1
- package/dist/docx/styleParser.js +1 -1
- package/dist/docx/tableParser.d.ts +1 -8
- package/dist/docx/tableParser.js +1 -28
- package/dist/docx/textBoxParser.d.ts +1 -5
- package/dist/docx/textBoxParser.js +1 -20
- package/dist/docx/unzip.js +6 -1
- package/dist/i18n/messages/ar.gen.js +4 -0
- package/dist/i18n/messages/catalogs.gen.d.ts +68 -0
- package/dist/i18n/messages/catalogs.gen.js +68 -0
- package/dist/i18n/messages/cs.gen.js +4 -0
- package/dist/i18n/messages/de.gen.js +4 -0
- package/dist/i18n/messages/en.gen.js +4 -0
- package/dist/i18n/messages/es.gen.js +4 -0
- package/dist/i18n/messages/et.gen.js +4 -0
- package/dist/i18n/messages/fr.gen.js +4 -0
- package/dist/i18n/messages/he.gen.js +4 -0
- package/dist/i18n/messages/hi.gen.js +4 -0
- package/dist/i18n/messages/hu.gen.js +4 -0
- package/dist/i18n/messages/lt.gen.js +4 -0
- package/dist/i18n/messages/lv.gen.js +4 -0
- package/dist/i18n/messages/messages.gen.d.ts +4 -0
- package/dist/i18n/messages/pl.gen.js +4 -0
- package/dist/i18n/messages/pt-BR.gen.js +4 -0
- package/dist/i18n/messages/sk.gen.js +4 -0
- package/dist/i18n/messages/tr.gen.js +4 -0
- package/dist/i18n/messages/zh-CN.gen.js +4 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/internal/acceptedBlockProjection.d.ts +12 -0
- package/dist/internal/acceptedBlockProjection.js +45 -0
- package/dist/internal/revisionResolutionInline.js +25 -3
- package/dist/managers/DocumentLoaderManager.js +2 -1
- package/dist/markdown/escape.d.ts +3 -1
- package/dist/markdown/escape.js +9 -2
- package/dist/markdown/renderBlock.js +5 -120
- package/dist/markdown/renderParagraph.js +4 -2
- package/dist/markdown/renderRuns.d.ts +7 -1
- package/dist/markdown/renderRuns.js +33 -24
- package/dist/panel-layout.d.ts +11 -9
- package/dist/panel-layout.js +13 -9
- package/dist/prosemirror/addTrackedDeletionMark.d.ts +18 -0
- package/dist/prosemirror/addTrackedDeletionMark.js +87 -0
- package/dist/prosemirror/attrs/index.js +5 -0
- package/dist/prosemirror/canonicalCommands.d.ts +28 -4
- package/dist/prosemirror/canonicalCommands.js +11 -4
- package/dist/prosemirror/canonicalSelectionRange.d.ts +9 -0
- package/dist/prosemirror/canonicalSelectionRange.js +15 -0
- package/dist/prosemirror/clipboardIntent.d.ts +7 -0
- package/dist/prosemirror/clipboardIntent.js +9 -0
- package/dist/prosemirror/commands/comments.js +60 -35
- package/dist/prosemirror/commands/pageBreak.js +2 -2
- package/dist/prosemirror/commands/pastePlainText.js +2 -1
- package/dist/prosemirror/commands/propertyChangeScope.js +3 -6
- package/dist/prosemirror/commands/resolveParagraphProperties.js +22 -13
- package/dist/prosemirror/commentOps.js +15 -1
- package/dist/prosemirror/conversion/fromProseDoc.js +22 -3
- package/dist/prosemirror/conversion/hyphenTextCarriers.d.ts +8 -0
- package/dist/prosemirror/conversion/hyphenTextCarriers.js +8 -0
- package/dist/prosemirror/conversion/toProseDoc.d.ts +7 -1
- package/dist/prosemirror/conversion/toProseDoc.js +124 -22
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +61 -35
- package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +74 -25
- package/dist/prosemirror/extensions/marks/FootnoteRefExtension.js +11 -0
- package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +65 -29
- package/dist/prosemirror/extensions/marks/markUtils.js +11 -8
- package/dist/prosemirror/extensions/marks/noteReferenceDeletion.js +5 -2
- package/dist/prosemirror/fieldRepresentation.d.ts +8 -0
- package/dist/prosemirror/fieldRepresentation.js +18 -0
- package/dist/prosemirror/hyperlinkRemoval.d.ts +13 -1
- package/dist/prosemirror/hyperlinkRemoval.js +28 -9
- package/dist/prosemirror/insertOperations.js +2 -1
- package/dist/prosemirror/listNumbering.js +11 -5
- package/dist/prosemirror/noteReferenceOccurrenceId.d.ts +5 -0
- package/dist/prosemirror/noteReferenceOccurrenceId.js +5 -0
- package/dist/prosemirror/noteReferenceOccurrences.d.ts +21 -0
- package/dist/prosemirror/noteReferenceOccurrences.js +185 -0
- package/dist/prosemirror/noteReferenceReview.js +14 -1
- package/dist/prosemirror/paragraphPropertyCarry.d.ts +7 -1
- package/dist/prosemirror/paragraphPropertyCarry.js +8 -3
- package/dist/prosemirror/plugins/documentStyles.d.ts +4 -1
- package/dist/prosemirror/plugins/documentStyles.js +17 -10
- package/dist/prosemirror/plugins/suggestionMode.js +48 -48
- package/dist/prosemirror/preservedXmlReview.d.ts +6 -0
- package/dist/prosemirror/preservedXmlReview.js +35 -0
- package/dist/prosemirror/runFormattingFromMarks.js +2 -2
- package/dist/prosemirror/runFormattingReconciliation.js +5 -4
- package/dist/prosemirror/runPropertyChangeResolution.d.ts +8 -1
- package/dist/prosemirror/runPropertyChangeResolution.js +24 -2
- package/dist/prosemirror/runStyleFormatting.d.ts +3 -1
- package/dist/prosemirror/runStyleFormatting.js +3 -1
- package/dist/prosemirror/schema/marks.d.ts +1 -0
- package/dist/prosemirror/schema/nodes.d.ts +2 -0
- package/dist/prosemirror/styles/paragraphStyleCascade.js +4 -1
- package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +15 -15
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +69 -28
- package/dist/prosemirror/textInput.d.ts +5 -1
- package/dist/prosemirror/textInput.js +3 -3
- package/dist/prosemirror/trackedRevisionPath.d.ts +5 -1
- package/dist/prosemirror/trackedRevisionPath.js +39 -1
- package/dist/prosemirror/validation.js +3 -5
- package/dist/prosemirror/yjsDocumentMetadata.d.ts +9 -3
- package/dist/prosemirror/yjsDocumentMetadata.js +37 -8
- package/dist/types/canonicalCapabilities.d.ts +201 -0
- package/dist/types/canonicalCapabilities.js +198 -0
- package/dist/types/canonicalComments.d.ts +51 -0
- package/dist/types/canonicalComments.js +0 -0
- package/dist/types/canonicalSave.d.ts +11 -0
- package/dist/types/canonicalSave.js +0 -0
- package/dist/types/canonicalSections.d.ts +12 -0
- package/dist/types/canonicalSections.js +0 -0
- package/dist/types/docxSerialization.d.ts +14 -0
- package/dist/types/docxSerialization.js +7 -0
- package/dist/utils/headingCollector.js +45 -4
- package/dist/utils/outlineDepth.d.ts +9 -0
- package/dist/utils/outlineDepth.js +9 -0
- package/package.json +4 -4
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { runFormattingInlineAtomDisposition } from "./runFormattingInlineCarriers.js";
|
|
1
2
|
import { RUN_FORMATTING_MARK_NAMES } from "./runFormattingMarkNames.js";
|
|
2
|
-
import { reconcileRunFormattingMarks } from "./runFormattingReconciliation.js";
|
|
3
|
+
import { readAuthoredRunFormatting, reconcileRunFormattingMarks } from "./runFormattingReconciliation.js";
|
|
3
4
|
//#region src/prosemirror/runPropertyChangeResolution.ts
|
|
4
5
|
/**
|
|
5
6
|
* Rebuild the pre-change run marks against the paragraph's live style cascade.
|
|
@@ -14,5 +15,26 @@ const reconstructRejectedRunFormattingMarks = ({ node, paragraphContext, previou
|
|
|
14
15
|
...styleResolver !== void 0 ? { styleResolver } : {}
|
|
15
16
|
}).filter(({ type }) => RUN_FORMATTING_MARK_NAMES.has(type.name));
|
|
16
17
|
};
|
|
18
|
+
/** Restored deletions inherit the live paragraph cascade without authoring their historical visuals. */
|
|
19
|
+
const restoreHistoricalRunFormatting = ({ node, paragraphContext, styleResolver }) => {
|
|
20
|
+
const disposition = runFormattingInlineAtomDisposition(node);
|
|
21
|
+
if (disposition === null || disposition === "not-a-run") return node.marks;
|
|
22
|
+
if (paragraphContext.paragraphMarkFormatting === void 0) return node.marks;
|
|
23
|
+
return reconcileRunFormattingMarks({
|
|
24
|
+
authoredFormatting: readAuthoredRunFormatting({
|
|
25
|
+
context: {
|
|
26
|
+
baseParagraphFormatting: paragraphContext.baseParagraphFormatting,
|
|
27
|
+
paragraphFormatting: paragraphContext.baseParagraphFormatting,
|
|
28
|
+
paragraphMarkFormatting: void 0,
|
|
29
|
+
paragraphMarkPrecedesStyle: false
|
|
30
|
+
},
|
|
31
|
+
marks: node.marks,
|
|
32
|
+
...styleResolver !== void 0 ? { styleResolver } : {}
|
|
33
|
+
}),
|
|
34
|
+
context: paragraphContext,
|
|
35
|
+
node,
|
|
36
|
+
...styleResolver !== void 0 ? { styleResolver } : {}
|
|
37
|
+
});
|
|
38
|
+
};
|
|
17
39
|
//#endregion
|
|
18
|
-
export { reconstructRejectedRunFormattingMarks };
|
|
40
|
+
export { reconstructRejectedRunFormattingMarks, restoreHistoricalRunFormatting };
|
|
@@ -5,6 +5,8 @@ import { cascadeStyleTextFormatting } from "./styles/styleToggleCascade.js";
|
|
|
5
5
|
import { Mark, Node } from "prosemirror-model";
|
|
6
6
|
//#region src/prosemirror/runStyleFormatting.d.ts
|
|
7
7
|
declare const hasDirectRunFormatting: (formatting: document_d_exports.TextFormatting | undefined) => boolean;
|
|
8
|
+
/** A stated run property or character style establishes paragraph-mark suppression. */
|
|
9
|
+
declare const isParagraphMarkSuppressionEligible: (formatting: document_d_exports.TextFormatting | undefined) => boolean;
|
|
8
10
|
declare const stripParagraphMarkOnlyFormatting: (formatting: document_d_exports.TextFormatting) => document_d_exports.TextFormatting | undefined;
|
|
9
11
|
declare const stripParagraphMarkFormattingForBodyRuns: (formatting: document_d_exports.TextFormatting) => document_d_exports.TextFormatting | undefined;
|
|
10
12
|
type SuppressParagraphMarkFormattingOptions = {
|
|
@@ -66,4 +68,4 @@ type ResolveEffectiveRunStyleFormattingOptions = {
|
|
|
66
68
|
/** Resolve the non-direct run cascade from shared document styles and the current paragraph. */
|
|
67
69
|
declare const resolveEffectiveRunStyleFormatting: ({ marks, paragraphFormatting, styleResolver }: ResolveEffectiveRunStyleFormattingOptions) => document_d_exports.TextFormatting | undefined;
|
|
68
70
|
//#endregion
|
|
69
|
-
export { ParagraphRunStyleContext, RunStyleResolver, getParagraphMarkSuppressionOverrides, hasDirectRunFormatting, nearestParagraphRunStyleContext, paragraphFormattingForRun, paragraphRunStyleContext, paragraphRunStyleContextAt, resolveEffectiveRunStyleFormatting, resolveParagraphBodyRunFormatting, stripParagraphMarkFormattingForBodyRuns, stripParagraphMarkOnlyFormatting, suppressParagraphMarkFormatting };
|
|
71
|
+
export { ParagraphRunStyleContext, RunStyleResolver, getParagraphMarkSuppressionOverrides, hasDirectRunFormatting, isParagraphMarkSuppressionEligible, nearestParagraphRunStyleContext, paragraphFormattingForRun, paragraphRunStyleContext, paragraphRunStyleContextAt, resolveEffectiveRunStyleFormatting, resolveParagraphBodyRunFormatting, stripParagraphMarkFormattingForBodyRuns, stripParagraphMarkOnlyFormatting, suppressParagraphMarkFormatting };
|
|
@@ -20,6 +20,8 @@ const hasDirectRunFormatting = (formatting) => {
|
|
|
20
20
|
if (!formatting) return false;
|
|
21
21
|
return Object.entries(formatting).some(([property, value]) => property !== "styleId" && value !== void 0);
|
|
22
22
|
};
|
|
23
|
+
/** A stated run property or character style establishes paragraph-mark suppression. */
|
|
24
|
+
const isParagraphMarkSuppressionEligible = (formatting) => hasDirectRunFormatting(formatting) || formatting?.styleId !== void 0;
|
|
23
25
|
const stripParagraphMarkOnlyFormatting = (formatting) => {
|
|
24
26
|
const { allCaps: _allCaps, highlight: _highlight, shading: _shading, smallCaps: _smallCaps, vertAlign: _vertAlign, preserved: _preserved, ...formattingForBody } = formatting;
|
|
25
27
|
return Object.keys(formattingForBody).length > 0 ? formattingForBody : void 0;
|
|
@@ -182,4 +184,4 @@ const resolveEffectiveRunStyleFormatting = ({ marks, paragraphFormatting, styleR
|
|
|
182
184
|
});
|
|
183
185
|
};
|
|
184
186
|
//#endregion
|
|
185
|
-
export { getParagraphMarkSuppressionOverrides, hasDirectRunFormatting, nearestParagraphRunStyleContext, paragraphFormattingForRun, paragraphRunStyleContext, paragraphRunStyleContextAt, resolveEffectiveRunStyleFormatting, resolveParagraphBodyRunFormatting, stripParagraphMarkFormattingForBodyRuns, stripParagraphMarkOnlyFormatting, suppressParagraphMarkFormatting };
|
|
187
|
+
export { getParagraphMarkSuppressionOverrides, hasDirectRunFormatting, isParagraphMarkSuppressionEligible, nearestParagraphRunStyleContext, paragraphFormattingForRun, paragraphRunStyleContext, paragraphRunStyleContextAt, resolveEffectiveRunStyleFormatting, resolveParagraphBodyRunFormatting, stripParagraphMarkFormattingForBodyRuns, stripParagraphMarkOnlyFormatting, suppressParagraphMarkFormatting };
|
|
@@ -272,6 +272,8 @@ type ParagraphAttrs = {
|
|
|
272
272
|
* paragraph. `TableCellAttrs._resolvedBorders` is the same device.
|
|
273
273
|
*/
|
|
274
274
|
_resolvedFormatting?: document_d_exports.ParagraphFormatting;
|
|
275
|
+
/** Style-only inheritance baseline, before numbering-level indentation. PM-only. */
|
|
276
|
+
_styleResolvedFormatting?: document_d_exports.ParagraphFormatting;
|
|
275
277
|
/** Import-effective spacing baseline for HTML auto-spacing detection.
|
|
276
278
|
* PM-only; never serialized back into DOCX formatting. */
|
|
277
279
|
_autospacingBase?: {
|
|
@@ -59,7 +59,10 @@ function paragraphStyleCascadeAttrs({ styleId, formatting, styleResolver, tableP
|
|
|
59
59
|
};
|
|
60
60
|
const stylePpr = styleResolver.resolveParagraphStyleInTable(styleId, tableParagraphOverlay).paragraphFormatting;
|
|
61
61
|
const resolvedFormatting = styleResolvedParagraphFormatting(stylePpr);
|
|
62
|
-
if (resolvedFormatting)
|
|
62
|
+
if (resolvedFormatting) {
|
|
63
|
+
attrs._resolvedFormatting = resolvedFormatting;
|
|
64
|
+
attrs._styleResolvedFormatting = resolvedFormatting;
|
|
65
|
+
}
|
|
63
66
|
set("alignment", formatting?.alignment ?? stylePpr?.alignment);
|
|
64
67
|
set("alignmentFromStyle", stylePpr?.alignment);
|
|
65
68
|
set("spaceBefore", formatting?.spaceBefore ?? stylePpr?.spaceBefore);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { document_d_exports } from "../../types/document.js";
|
|
1
2
|
import { ParagraphAttrs, ParagraphAttrsPatch } from "../schema/nodes.js";
|
|
2
3
|
import { ResolvedParagraphStyle } from "./styleResolver.js";
|
|
3
4
|
import { NumberingMap } from "../../docx/numberingParser.js";
|
|
@@ -38,17 +39,18 @@ declare function listAttrsFromNumbering(numPr: {
|
|
|
38
39
|
numId: number;
|
|
39
40
|
ilvl: number;
|
|
40
41
|
}, numbering: NumberingMap | null | undefined): ParagraphAttrsPatch;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
42
|
+
type ListIndentationProvenanceOptions = {
|
|
43
|
+
direct: DirectParagraphIndentation | undefined;
|
|
44
|
+
styleFormatting: document_d_exports.ParagraphFormatting | undefined;
|
|
45
|
+
numberingSource: "style" | "paragraph";
|
|
46
|
+
numPr: {
|
|
47
|
+
numId: number;
|
|
48
|
+
ilvl: number;
|
|
49
|
+
} | undefined;
|
|
50
|
+
numbering: NumberingMap | null | undefined;
|
|
51
|
+
};
|
|
52
|
+
/** Project effective indentation and both inheritance layers together. */
|
|
53
|
+
declare function listIndentationProvenancePatch({ direct, styleFormatting, numberingSource, numPr, numbering }: ListIndentationProvenanceOptions): ParagraphAttrsPatch;
|
|
52
54
|
/**
|
|
53
55
|
* The indentation a paragraph leaving its list keeps: the level's indentation
|
|
54
56
|
* it only read from its numbering goes with the numbering, back to what its
|
|
@@ -57,11 +59,9 @@ declare function listLevelIndentAttrPatch(stated: DirectParagraphIndentation | u
|
|
|
57
59
|
*/
|
|
58
60
|
declare function listLevelIndentRemovalPatch(attrs: Readonly<ParagraphAttrs>, numbering: NumberingMap | null | undefined): ParagraphAttrsPatch;
|
|
59
61
|
/** Recompute every level-dependent attr when a paragraph changes list level. */
|
|
60
|
-
declare function listLevelAttrPatch(attrs: {
|
|
61
|
-
listImplicitChildLevelAdvances?: number | null;
|
|
62
|
-
}, numPr: {
|
|
62
|
+
declare function listLevelAttrPatch(attrs: Pick<ParagraphAttrs, "listImplicitChildLevelAdvances" | "_originalFormatting" | "_resolvedFormatting" | "_styleResolvedFormatting" | "numPr" | "numPrFromStyle" | "indentLeft" | "indentRight" | "indentFirstLine" | "hangingIndent">, numPr: {
|
|
63
63
|
numId: number;
|
|
64
64
|
ilvl: number;
|
|
65
65
|
}, numbering: NumberingMap | null | undefined): ParagraphAttrsPatch;
|
|
66
66
|
//#endregion
|
|
67
|
-
export { listAttrsFromNumbering, listAttrsFromResolvedStyle,
|
|
67
|
+
export { listAttrsFromNumbering, listAttrsFromResolvedStyle, listIndentationProvenancePatch, listLevelAttrPatch, listLevelIndentRemovalPatch, paragraphAttrsFromResolvedStyle };
|
|
@@ -6,6 +6,7 @@ import { CLEARED_LIST_RENDERING_ATTRS } from "../listMarker.js";
|
|
|
6
6
|
import { listRenderingAttrPatch } from "../listRenderingAttrs.js";
|
|
7
7
|
import { paragraphNumberingAttr } from "../numberingAttr.js";
|
|
8
8
|
import { styleResolvedParagraphFormatting } from "../paragraphFormattingProvenance.js";
|
|
9
|
+
import { directParagraphIndentation, paragraphIndentationAttrPatch, paragraphIndentationFromFormatting, withDirectParagraphIndentation } from "../paragraphIndentation.js";
|
|
9
10
|
//#region src/prosemirror/styles/resolvedStyleAttrs.ts
|
|
10
11
|
/**
|
|
11
12
|
* Shared helper for projecting a resolved paragraph style onto ProseMirror
|
|
@@ -48,6 +49,7 @@ function paragraphAttrsFromResolvedStyle(resolved, identity) {
|
|
|
48
49
|
borders: ppr?.borders ?? null,
|
|
49
50
|
defaultTextFormatting: hasRunFormatting ? runFormatting : null,
|
|
50
51
|
_resolvedFormatting: styleResolvedParagraphFormatting(ppr),
|
|
52
|
+
_styleResolvedFormatting: styleResolvedParagraphFormatting(ppr),
|
|
51
53
|
_autospacingBase: autospacingBaseFromResolvedParagraphFormatting(ppr),
|
|
52
54
|
_tableOfContentsLevel: tableOfContentsStyleLevel(identity) ?? null
|
|
53
55
|
};
|
|
@@ -84,19 +86,26 @@ function listAttrsFromResolvedStyle(resolved, numbering) {
|
|
|
84
86
|
numId,
|
|
85
87
|
ilvl
|
|
86
88
|
}, numbering);
|
|
87
|
-
const level = numbering?.getLevel(numId, ilvl);
|
|
88
89
|
attrs.numPrFromStyle = paragraphNumberingAttr(paragraphNumberingReference({
|
|
89
90
|
numId,
|
|
90
91
|
ilvl
|
|
91
92
|
}));
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
93
|
+
Object.assign(attrs, listIndentationProvenancePatch({
|
|
94
|
+
direct: void 0,
|
|
95
|
+
styleFormatting: resolved.paragraphFormatting,
|
|
96
|
+
numberingSource: "style",
|
|
97
|
+
numPr: {
|
|
98
|
+
numId,
|
|
99
|
+
ilvl
|
|
100
|
+
},
|
|
101
|
+
numbering
|
|
102
|
+
}));
|
|
103
|
+
for (const key of [
|
|
104
|
+
"indentLeft",
|
|
105
|
+
"indentRight",
|
|
106
|
+
"indentFirstLine"
|
|
107
|
+
]) if (attrs[key] == null) Reflect.deleteProperty(attrs, key);
|
|
108
|
+
if (attrs.indentFirstLine === void 0 && resolved.paragraphFormatting?.hangingIndent === void 0) Reflect.deleteProperty(attrs, "hangingIndent");
|
|
100
109
|
return attrs;
|
|
101
110
|
}
|
|
102
111
|
/** Project one resolved numbering level into the complete editor attr group. */
|
|
@@ -115,9 +124,9 @@ function listAttrsFromNumbering(numPr, numbering) {
|
|
|
115
124
|
/**
|
|
116
125
|
* The numbering level's indentation a directly numbered paragraph reads as its
|
|
117
126
|
* own where it states none: the load path folds the level's `w:ind` into the
|
|
118
|
-
* paragraph (a direct `w:ind` wins per group, left vs first line/hanging)
|
|
119
|
-
*
|
|
120
|
-
*
|
|
127
|
+
* paragraph (a direct `w:ind` wins per group, left vs first line/hanging).
|
|
128
|
+
* Keep this projection private: callers use the paired provenance helper so
|
|
129
|
+
* effective level values cannot be mistaken for authored indentation.
|
|
121
130
|
*/
|
|
122
131
|
function listLevelIndentAttrPatch(stated, numPr, numbering) {
|
|
123
132
|
const level = numbering?.getLevel(numPr.numId, numPr.ilvl);
|
|
@@ -130,6 +139,33 @@ function listLevelIndentAttrPatch(stated, numPr, numbering) {
|
|
|
130
139
|
}
|
|
131
140
|
return patch;
|
|
132
141
|
}
|
|
142
|
+
/** Project effective indentation and both inheritance layers together. */
|
|
143
|
+
function listIndentationProvenancePatch({ direct, styleFormatting, numberingSource, numPr, numbering }) {
|
|
144
|
+
const style = {
|
|
145
|
+
...styleResolvedParagraphFormatting(styleFormatting),
|
|
146
|
+
...styleFormatting?.hangingIndent === void 0 ? {} : { hangingIndent: styleFormatting.hangingIndent }
|
|
147
|
+
};
|
|
148
|
+
const level = numPr === void 0 ? {} : listLevelIndentAttrPatch(numberingSource === "style" ? paragraphIndentationFromFormatting(style) : void 0, numPr, numbering);
|
|
149
|
+
if (level.indentLeft === 0 && style.indentLeft === void 0) Reflect.deleteProperty(level, "indentLeft");
|
|
150
|
+
if (level.indentFirstLine === 0 && style.indentFirstLine === void 0 && style.hangingIndent === void 0) {
|
|
151
|
+
Reflect.deleteProperty(level, "indentFirstLine");
|
|
152
|
+
Reflect.deleteProperty(level, "hangingIndent");
|
|
153
|
+
}
|
|
154
|
+
const resolved = {
|
|
155
|
+
...style,
|
|
156
|
+
...typeof level.indentLeft === "number" ? { indentLeft: level.indentLeft } : {},
|
|
157
|
+
...typeof level.indentFirstLine === "number" ? { indentFirstLine: level.indentFirstLine } : {},
|
|
158
|
+
...typeof level.hangingIndent === "boolean" ? { hangingIndent: level.hangingIndent } : {}
|
|
159
|
+
};
|
|
160
|
+
return {
|
|
161
|
+
...paragraphIndentationAttrPatch({
|
|
162
|
+
direct,
|
|
163
|
+
inherited: paragraphIndentationFromFormatting(resolved)
|
|
164
|
+
}),
|
|
165
|
+
_resolvedFormatting: Object.keys(resolved).length === 0 ? null : resolved,
|
|
166
|
+
_styleResolvedFormatting: Object.keys(style).length === 0 ? null : style
|
|
167
|
+
};
|
|
168
|
+
}
|
|
133
169
|
/**
|
|
134
170
|
* The indentation a paragraph leaving its list keeps: the level's indentation
|
|
135
171
|
* it only read from its numbering goes with the numbering, back to what its
|
|
@@ -138,28 +174,33 @@ function listLevelIndentAttrPatch(stated, numPr, numbering) {
|
|
|
138
174
|
*/
|
|
139
175
|
function listLevelIndentRemovalPatch(attrs, numbering) {
|
|
140
176
|
if (attrs.numPr?.kind !== "reference") return {};
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
177
|
+
const direct = directParagraphIndentation(attrs);
|
|
178
|
+
return {
|
|
179
|
+
...listIndentationProvenancePatch({
|
|
180
|
+
direct,
|
|
181
|
+
styleFormatting: attrs._styleResolvedFormatting,
|
|
182
|
+
numberingSource: "paragraph",
|
|
183
|
+
numPr: void 0,
|
|
184
|
+
numbering
|
|
185
|
+
}),
|
|
186
|
+
_originalFormatting: withDirectParagraphIndentation(attrs._originalFormatting, direct) ?? null
|
|
187
|
+
};
|
|
151
188
|
}
|
|
152
189
|
/** Recompute every level-dependent attr when a paragraph changes list level. */
|
|
153
190
|
function listLevelAttrPatch(attrs, numPr, numbering) {
|
|
154
|
-
const
|
|
155
|
-
const hasMarkerSlot = level ? numberingLevelHasMarkerSlot(level) : false;
|
|
191
|
+
const direct = directParagraphIndentation(attrs);
|
|
156
192
|
return {
|
|
157
193
|
...listAttrsFromNumbering(numPr, numbering),
|
|
158
194
|
listImplicitChildLevelAdvances: attrs.listImplicitChildLevelAdvances ?? null,
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
195
|
+
...listIndentationProvenancePatch({
|
|
196
|
+
direct,
|
|
197
|
+
styleFormatting: attrs._styleResolvedFormatting,
|
|
198
|
+
numberingSource: attrs.numPrFromStyle == null ? "paragraph" : "style",
|
|
199
|
+
numPr,
|
|
200
|
+
numbering
|
|
201
|
+
}),
|
|
202
|
+
_originalFormatting: withDirectParagraphIndentation(attrs._originalFormatting, direct) ?? null
|
|
162
203
|
};
|
|
163
204
|
}
|
|
164
205
|
//#endregion
|
|
165
|
-
export { listAttrsFromNumbering, listAttrsFromResolvedStyle,
|
|
206
|
+
export { listAttrsFromNumbering, listAttrsFromResolvedStyle, listIndentationProvenancePatch, listLevelAttrPatch, listLevelIndentRemovalPatch, paragraphAttrsFromResolvedStyle };
|
|
@@ -13,6 +13,10 @@ type TextInput = {
|
|
|
13
13
|
to: number;
|
|
14
14
|
};
|
|
15
15
|
declare const dispatchEditorTextInput: <TView extends TextInputDispatchTarget<TView>>(view: TView, input: string | TextInput) => void;
|
|
16
|
+
declare const getEditorInputTargetRange: (view: EditorView, event: InputEvent) => {
|
|
17
|
+
from: number;
|
|
18
|
+
to: number;
|
|
19
|
+
} | null;
|
|
16
20
|
/** Shared DOM boundary for editor runtimes and standalone suggestion views. */
|
|
17
21
|
declare const handleEditorBeforeInput: (view: EditorView, event: InputEvent) => boolean;
|
|
18
22
|
/**
|
|
@@ -23,4 +27,4 @@ declare const afterNativeCompositionFlush: (callback: () => void) => void;
|
|
|
23
27
|
/** Route committed text through the model before the browser mutates mark spans. */
|
|
24
28
|
declare const createTextInputPlugin: () => Plugin<any>;
|
|
25
29
|
//#endregion
|
|
26
|
-
export { afterNativeCompositionFlush, createTextInputPlugin, dispatchEditorTextInput, handleEditorBeforeInput };
|
|
30
|
+
export { afterNativeCompositionFlush, createTextInputPlugin, dispatchEditorTextInput, getEditorInputTargetRange, handleEditorBeforeInput };
|
|
@@ -19,7 +19,7 @@ const dispatchEditorTextInput = (view, input) => {
|
|
|
19
19
|
};
|
|
20
20
|
if (!view.someProp("handleTextInput", (handler) => handler(view, from, to, text, defaultTransaction))) view.dispatch(defaultTransaction());
|
|
21
21
|
};
|
|
22
|
-
const
|
|
22
|
+
const getEditorInputTargetRange = (view, event) => {
|
|
23
23
|
if (typeof event.getTargetRanges !== "function") return null;
|
|
24
24
|
const ranges = event.getTargetRanges();
|
|
25
25
|
if (ranges.length !== 1) return null;
|
|
@@ -39,7 +39,7 @@ const handleEditorBeforeInput = (view, event) => {
|
|
|
39
39
|
if (event.inputType !== "insertText" && event.inputType !== "insertReplacementText") return false;
|
|
40
40
|
const text = event.data ?? (event.dataTransfer?.types.includes("text/plain") ? event.dataTransfer.getData("text/plain") : null);
|
|
41
41
|
if (text === null) return false;
|
|
42
|
-
const selection = event.inputType === "insertReplacementText" ?
|
|
42
|
+
const selection = event.inputType === "insertReplacementText" ? getEditorInputTargetRange(view, event) : view.state.selection;
|
|
43
43
|
if (!selection) return false;
|
|
44
44
|
event.preventDefault();
|
|
45
45
|
dispatchEditorTextInput(view, {
|
|
@@ -78,4 +78,4 @@ const createTextInputPlugin = () => {
|
|
|
78
78
|
} } });
|
|
79
79
|
};
|
|
80
80
|
//#endregion
|
|
81
|
-
export { afterNativeCompositionFlush, createTextInputPlugin, dispatchEditorTextInput, handleEditorBeforeInput };
|
|
81
|
+
export { afterNativeCompositionFlush, createTextInputPlugin, dispatchEditorTextInput, getEditorInputTargetRange, handleEditorBeforeInput };
|
|
@@ -13,5 +13,9 @@ type EnclosingInsertionAncestorsOptions = {
|
|
|
13
13
|
};
|
|
14
14
|
/** The deletion's ancestor path, with the insertion it sits in as the outermost layer. */
|
|
15
15
|
declare const enclosingInsertionAncestors: ({ insertionMark, ancestors, node }: EnclosingInsertionAncestorsOptions) => readonly TrackedRevisionAncestor[];
|
|
16
|
+
/** The authored revision layers already owned by a mark, outermost first. */
|
|
17
|
+
declare const trackedRevisionPathOf: (mark: Mark) => readonly TrackedRevisionAncestor[];
|
|
18
|
+
/** Promote a surviving existing layer; callers cannot supply a fresh identity. */
|
|
19
|
+
declare const retainedTrackedRevisionMark: (mark: Mark, keepLayer: (layer: TrackedRevisionAncestor) => boolean) => Mark | null;
|
|
16
20
|
//#endregion
|
|
17
|
-
export { enclosingInsertionAncestors, inlineWrapperStackOf, trackedRevisionLayerOf };
|
|
21
|
+
export { enclosingInsertionAncestors, inlineWrapperStackOf, retainedTrackedRevisionMark, trackedRevisionLayerOf, trackedRevisionPathOf };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { expectInlineWrapperMarkAttrs, expectTrackedChangeMarkAttrs } from "./attrs/index.js";
|
|
2
2
|
import { INLINE_WRAPPER_MARK_NAME } from "./extensions/marks/InlineWrapperExtension.js";
|
|
3
|
+
import { panic } from "better-result";
|
|
3
4
|
//#region src/prosemirror/trackedRevisionPath.ts
|
|
4
5
|
/** The wrappers `node` sits inside, outermost first; empty when it sits in none. */
|
|
5
6
|
const inlineWrapperStackOf = (node) => {
|
|
@@ -29,5 +30,42 @@ const enclosingInsertionAncestors = ({ insertionMark, ancestors, node }) => {
|
|
|
29
30
|
if (ancestors.some(({ revisionId }) => revisionId === attrs.revisionId)) return ancestors;
|
|
30
31
|
return [trackedRevisionLayerOf(insertionMark, node), ...ancestors];
|
|
31
32
|
};
|
|
33
|
+
const revisionLayerOf = (mark) => {
|
|
34
|
+
const attrs = expectTrackedChangeMarkAttrs(mark);
|
|
35
|
+
let type;
|
|
36
|
+
if (mark.type.name === "insertion") type = attrs.moveKind === "moveTo" ? "moveTo" : "insertion";
|
|
37
|
+
else type = attrs.moveKind === "moveFrom" ? "moveFrom" : "deletion";
|
|
38
|
+
return {
|
|
39
|
+
type,
|
|
40
|
+
revisionId: attrs.revisionId,
|
|
41
|
+
author: attrs.author,
|
|
42
|
+
...attrs.date ? { date: attrs.date } : {},
|
|
43
|
+
...attrs.utcDate ? { utcDate: attrs.utcDate } : {},
|
|
44
|
+
...attrs.initials ? { initials: attrs.initials } : {},
|
|
45
|
+
outerWrapperCount: attrs._docxOuterWrapperCount ?? 0
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
/** The authored revision layers already owned by a mark, outermost first. */
|
|
49
|
+
const trackedRevisionPathOf = (mark) => [...expectTrackedChangeMarkAttrs(mark)._docxRevisionAncestors ?? [], revisionLayerOf(mark)];
|
|
50
|
+
/** Promote a surviving existing layer; callers cannot supply a fresh identity. */
|
|
51
|
+
const retainedTrackedRevisionMark = (mark, keepLayer) => {
|
|
52
|
+
const remaining = trackedRevisionPathOf(mark).filter(keepLayer);
|
|
53
|
+
const active = remaining.at(-1);
|
|
54
|
+
if (!active) return null;
|
|
55
|
+
const name = active.type === "insertion" || active.type === "moveTo" ? "insertion" : "deletion";
|
|
56
|
+
const type = mark.type.schema.marks[name];
|
|
57
|
+
if (!type) panic("A nested tracked revision has no editor mark type");
|
|
58
|
+
return type.create({
|
|
59
|
+
revisionId: active.revisionId,
|
|
60
|
+
author: active.author,
|
|
61
|
+
date: active.date ?? null,
|
|
62
|
+
utcDate: active.utcDate ?? null,
|
|
63
|
+
initials: active.initials ?? null,
|
|
64
|
+
moveKind: active.type === "moveTo" || active.type === "moveFrom" ? active.type : null,
|
|
65
|
+
_historicalFormatting: active.type === "deletion" || active.type === "moveFrom" ? true : null,
|
|
66
|
+
_docxOuterWrapperCount: active.outerWrapperCount,
|
|
67
|
+
_docxRevisionAncestors: remaining.length > 1 ? remaining.slice(0, -1) : null
|
|
68
|
+
});
|
|
69
|
+
};
|
|
32
70
|
//#endregion
|
|
33
|
-
export { enclosingInsertionAncestors, inlineWrapperStackOf, trackedRevisionLayerOf };
|
|
71
|
+
export { enclosingInsertionAncestors, inlineWrapperStackOf, retainedTrackedRevisionMark, trackedRevisionLayerOf, trackedRevisionPathOf };
|
|
@@ -2,7 +2,7 @@ import { readNoteMarkerAttrs } from "../internal/noteMarkerAttrs.js";
|
|
|
2
2
|
import { readBlockCustomXmlAttrs, readBlockSdtAttrs, readCharacterSpacingMarkAttrs, readCharacterStyleMarkAttrs, readCommentMarkAttrs, readEmphasisMarkAttrs, readFieldAttrs, readFontFamilyMarkAttrs, readFontSizeMarkAttrs, readFootnoteRefMarkAttrs, readHardBreakAttrs, readHighlightMarkAttrs, readHyperlinkMarkAttrs, readImageAttrs, readInlineWrapperMarkAttrs, readLanguageMarkAttrs, readMathAttrs, readPageBreakRunAttrs, readParagraphAttrs, readPreservedBlockAttrs, readPreservedXmlAttrs, readRunFormattingOverrideMarkAttrs, readRunIdentityMarkAttrs, readRunPropertyChangeMarkAttrs, readRunShadingMarkAttrs, readSdtAttrs, readShapeAttrs, readStrikeMarkAttrs, readSymbolAttrs, readTabAttrs, readTableAttrs, readTableCellAttrs, readTableRowAttrs, readTextBoxAttrs, readTextColorMarkAttrs, readTextEffectMarkAttrs, readTrackedChangeMarkAttrs, readUnderlineMarkAttrs } from "./attrs/index.js";
|
|
3
3
|
import { readBookmarkBoundaryAttrs } from "./bookmarkBoundaryAttrs.js";
|
|
4
4
|
import { readCommentReferenceAttrs } from "./commentReferenceAttrs.js";
|
|
5
|
-
import {
|
|
5
|
+
import { fieldRequiresStructuredContent } from "./fieldRepresentation.js";
|
|
6
6
|
import { readMoveRangeBoundaryAttrs } from "./moveRangeBoundaryAttrs.js";
|
|
7
7
|
import { readRangeAnchorAttrs } from "./rangeAnchorAttrs.js";
|
|
8
8
|
import { readTextBoxAnchorAttrs } from "./textBoxAnchorAttrs.js";
|
|
@@ -249,8 +249,6 @@ const validateNodeAttrs = (node, path, issues) => {
|
|
|
249
249
|
if (fieldAttrs.ok) {
|
|
250
250
|
const hasStructuredHyperlink = node.content.content.some((child) => child.marks.some((mark) => mark.type.name === "hyperlink"));
|
|
251
251
|
const hasPageBreakCarrier = node.content.content.some((child) => child.type.name === "pageBreakRun");
|
|
252
|
-
const hasPreservedCapture = node.content.content.some((child) => child.type.name === "preservedXml");
|
|
253
|
-
const hasInlineWrapper = node.content.content.some((child) => child.marks.some((mark) => mark.type.name === INLINE_WRAPPER_MARK_NAME));
|
|
254
252
|
if (fieldAttrs.value.fieldKind === "complex" && !hasPageBreakCarrier) issues.push({
|
|
255
253
|
path: `${path}.content`,
|
|
256
254
|
message: "Complex fields cannot contain structured result children."
|
|
@@ -259,9 +257,9 @@ const validateNodeAttrs = (node, path, issues) => {
|
|
|
259
257
|
path: `${path}.content`,
|
|
260
258
|
message: "Complex field results cannot contain hyperlink content."
|
|
261
259
|
});
|
|
262
|
-
else if (!
|
|
260
|
+
else if (!fieldRequiresStructuredContent(node.content.content)) issues.push({
|
|
263
261
|
path: `${path}.content`,
|
|
264
|
-
message: "Structured simple fields require
|
|
262
|
+
message: "Structured simple fields require non-text, hyperlink, wrapper or tracked content."
|
|
265
263
|
});
|
|
266
264
|
node.forEach((child, _offset, index) => {
|
|
267
265
|
const childPath = `${path}.content[${index}]`;
|
|
@@ -8,14 +8,20 @@ import * as Y from "yjs";
|
|
|
8
8
|
*/
|
|
9
9
|
type AttrSchemaMigrationStep = (fragment: Y.XmlFragment) => number;
|
|
10
10
|
/** Every attr-schema version this build reads, oldest first, with no gaps. */
|
|
11
|
-
declare const FOLIO_YJS_ATTR_SCHEMA_VERSIONS: readonly [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
|
|
11
|
+
declare const FOLIO_YJS_ATTR_SCHEMA_VERSIONS: readonly [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
|
|
12
12
|
/** An attr-schema version this build can read. */
|
|
13
13
|
type FolioYjsAttrSchemaVersion = (typeof FOLIO_YJS_ATTR_SCHEMA_VERSIONS)[number];
|
|
14
14
|
/**
|
|
15
15
|
* The attr-schema version this build writes. Derived against the migration map
|
|
16
16
|
* so the constant and the map cannot disagree.
|
|
17
17
|
*/
|
|
18
|
-
declare const FOLIO_YJS_ATTR_SCHEMA_VERSION =
|
|
18
|
+
declare const FOLIO_YJS_ATTR_SCHEMA_VERSION = 12;
|
|
19
|
+
declare const FolioYjsNoteReferenceSchemaError_base: import("better-result").TaggedErrorClass<"FolioYjsNoteReferenceSchemaError">;
|
|
20
|
+
declare class FolioYjsNoteReferenceSchemaError extends FolioYjsNoteReferenceSchemaError_base<{
|
|
21
|
+
message: string;
|
|
22
|
+
schemaVersion: FolioYjsAttrSchemaVersion;
|
|
23
|
+
requiredSchemaVersion: FolioYjsAttrSchemaVersion;
|
|
24
|
+
}> {}
|
|
19
25
|
/**
|
|
20
26
|
* The steps that carry a snapshot written under `fromVersion` up to
|
|
21
27
|
* {@link FOLIO_YJS_ATTR_SCHEMA_VERSION}, in order. Empty when the snapshot is
|
|
@@ -70,4 +76,4 @@ declare const writeYjsDocumentMetadata: (ydoc: Y.Doc, document: Node) => void;
|
|
|
70
76
|
declare const readYjsParagraphSourceContract: (ydoc: Y.Doc) => string | null;
|
|
71
77
|
declare const withParagraphSourceContract: (document: Node, contract: string) => Node;
|
|
72
78
|
//#endregion
|
|
73
|
-
export { FOLIO_YJS_ATTR_SCHEMA_VERSION, FolioYjsAttrSchemaVersion, FolioYjsAttrSchemaVersionError, applyAttrSchemaMigrations, attrSchemaMigrationSteps, proseDocumentParagraphSourceContract, readYjsAttrSchemaVersion, readYjsParagraphSourceContract, withParagraphSourceContract, writeYjsAttrSchemaVersion, writeYjsDocumentMetadata };
|
|
79
|
+
export { FOLIO_YJS_ATTR_SCHEMA_VERSION, FolioYjsAttrSchemaVersion, FolioYjsAttrSchemaVersionError, FolioYjsNoteReferenceSchemaError, applyAttrSchemaMigrations, attrSchemaMigrationSteps, proseDocumentParagraphSourceContract, readYjsAttrSchemaVersion, readYjsParagraphSourceContract, withParagraphSourceContract, writeYjsAttrSchemaVersion, writeYjsDocumentMetadata };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, getProseDocumentParagraphPropertySourceContract } from "../docx/paragraphPropertySource.js";
|
|
2
|
+
import { isNoteReferenceOccurrenceId } from "./noteReferenceOccurrenceId.js";
|
|
2
3
|
import { mintSectionProperties, parseSectionBreakType } from "./sectionCarrier.js";
|
|
3
4
|
import { Result, TaggedError, panic } from "better-result";
|
|
4
5
|
import { DRAWING_RAW_XML_MODES, outlineLevelFromStatedValue, paragraphNumberingFromSlots } from "@stll/docx-core/model";
|
|
@@ -473,7 +474,8 @@ const FOLIO_YJS_ATTR_SCHEMA_VERSIONS = [
|
|
|
473
474
|
8,
|
|
474
475
|
9,
|
|
475
476
|
10,
|
|
476
|
-
11
|
|
477
|
+
11,
|
|
478
|
+
12
|
|
477
479
|
];
|
|
478
480
|
/**
|
|
479
481
|
* The one place a persisted attr-shape change is decided.
|
|
@@ -497,13 +499,39 @@ const ATTR_SCHEMA_MIGRATIONS = {
|
|
|
497
499
|
8: mintSectionPropertiesFromBreakType,
|
|
498
500
|
9: dropUnstatedPlaceholderFlags,
|
|
499
501
|
10: renamePageBreakRunOwnerMarkAttr,
|
|
500
|
-
11:
|
|
502
|
+
11: stampMarkerOnly,
|
|
503
|
+
12: "current"
|
|
501
504
|
};
|
|
502
505
|
/**
|
|
503
506
|
* The attr-schema version this build writes. Derived against the migration map
|
|
504
507
|
* so the constant and the map cannot disagree.
|
|
505
508
|
*/
|
|
506
|
-
const FOLIO_YJS_ATTR_SCHEMA_VERSION =
|
|
509
|
+
const FOLIO_YJS_ATTR_SCHEMA_VERSION = 12;
|
|
510
|
+
var FolioYjsNoteReferenceSchemaError = class extends TaggedError("FolioYjsNoteReferenceSchemaError") {};
|
|
511
|
+
/** Check before any migration mutates the snapshot or any PM builder can drop text. */
|
|
512
|
+
const requireNoteOccurrenceAttribution = (fragment, schemaVersion) => {
|
|
513
|
+
const visit = (node) => {
|
|
514
|
+
for (const child of node.toArray()) {
|
|
515
|
+
if (typeof child === "string") continue;
|
|
516
|
+
if (!isXmlText(child)) {
|
|
517
|
+
if ("toArray" in child) visit(child);
|
|
518
|
+
continue;
|
|
519
|
+
}
|
|
520
|
+
for (const op of child.toDelta()) {
|
|
521
|
+
const attributes = op.attributes;
|
|
522
|
+
if (!isRecord(attributes) || attributes["footnoteRef"] == null) continue;
|
|
523
|
+
const reference = attributes["footnoteRef"];
|
|
524
|
+
if (isRecord(reference) && isNoteReferenceOccurrenceId(reference["occurrenceId"])) continue;
|
|
525
|
+
throw new FolioYjsNoteReferenceSchemaError({
|
|
526
|
+
schemaVersion,
|
|
527
|
+
requiredSchemaVersion: 12,
|
|
528
|
+
message: `Yjs schema ${schemaVersion} has unattributed note references; schema 12 requires occurrence identities. Rebuild the collaboration state from the saved DOCX.`
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
};
|
|
533
|
+
visit(fragment);
|
|
534
|
+
};
|
|
507
535
|
/**
|
|
508
536
|
* The steps that carry a snapshot written under `fromVersion` up to
|
|
509
537
|
* {@link FOLIO_YJS_ATTR_SCHEMA_VERSION}, in order. Empty when the snapshot is
|
|
@@ -528,7 +556,8 @@ const attrSchemaMigrationSteps = (fromVersion) => FOLIO_YJS_ATTR_SCHEMA_VERSIONS
|
|
|
528
556
|
* Returns how many elements the steps rewrote.
|
|
529
557
|
*/
|
|
530
558
|
const applyAttrSchemaMigrations = (ydoc, fragment, fromVersion) => {
|
|
531
|
-
|
|
559
|
+
requireNoteOccurrenceAttribution(fragment, fromVersion);
|
|
560
|
+
if (fromVersion === 12) return 0;
|
|
532
561
|
let rewritten = 0;
|
|
533
562
|
ydoc.transact(() => {
|
|
534
563
|
for (const step of attrSchemaMigrationSteps(fromVersion)) rewritten += step(fragment);
|
|
@@ -538,7 +567,7 @@ const applyAttrSchemaMigrations = (ydoc, fragment, fromVersion) => {
|
|
|
538
567
|
};
|
|
539
568
|
/** Raised when a snapshot's attr-schema marker is ahead of the running code. */
|
|
540
569
|
var FolioYjsAttrSchemaVersionError = class extends TaggedError("FolioYjsAttrSchemaVersionError") {};
|
|
541
|
-
const isReadableVersion = (marker) => typeof marker === "number" && Number.isInteger(marker) && marker >= 0 && marker <=
|
|
570
|
+
const isReadableVersion = (marker) => typeof marker === "number" && Number.isInteger(marker) && marker >= 0 && marker <= 12;
|
|
542
571
|
/**
|
|
543
572
|
* The attr-schema version a collaboration document was written under.
|
|
544
573
|
*
|
|
@@ -556,7 +585,7 @@ const readYjsAttrSchemaVersion = (ydoc) => {
|
|
|
556
585
|
return Result.err(new FolioYjsAttrSchemaVersionError({
|
|
557
586
|
marker,
|
|
558
587
|
message: "The collaboration snapshot was written by a newer Folio attr schema than this build reads.",
|
|
559
|
-
supportedVersion:
|
|
588
|
+
supportedVersion: 12
|
|
560
589
|
}));
|
|
561
590
|
};
|
|
562
591
|
const proseDocumentParagraphSourceContract = (document) => {
|
|
@@ -564,7 +593,7 @@ const proseDocumentParagraphSourceContract = (document) => {
|
|
|
564
593
|
};
|
|
565
594
|
/** Stamp the attr-schema version of the build that wrote the current fragment. */
|
|
566
595
|
const writeYjsAttrSchemaVersion = (ydoc) => {
|
|
567
|
-
ydoc.getMap(FOLIO_YJS_METADATA_MAP_NAME).set(ATTR_SCHEMA_VERSION_KEY,
|
|
596
|
+
ydoc.getMap(FOLIO_YJS_METADATA_MAP_NAME).set(ATTR_SCHEMA_VERSION_KEY, 12);
|
|
568
597
|
};
|
|
569
598
|
/**
|
|
570
599
|
* Write both metadata bindings for a freshly seeded collaboration document.
|
|
@@ -589,4 +618,4 @@ const withParagraphSourceContract = (document, contract) => {
|
|
|
589
618
|
}, document.content, document.marks);
|
|
590
619
|
};
|
|
591
620
|
//#endregion
|
|
592
|
-
export { FOLIO_YJS_ATTR_SCHEMA_VERSION, FolioYjsAttrSchemaVersionError, applyAttrSchemaMigrations, attrSchemaMigrationSteps, proseDocumentParagraphSourceContract, readYjsAttrSchemaVersion, readYjsParagraphSourceContract, withParagraphSourceContract, writeYjsAttrSchemaVersion, writeYjsDocumentMetadata };
|
|
621
|
+
export { FOLIO_YJS_ATTR_SCHEMA_VERSION, FolioYjsAttrSchemaVersionError, FolioYjsNoteReferenceSchemaError, applyAttrSchemaMigrations, attrSchemaMigrationSteps, proseDocumentParagraphSourceContract, readYjsAttrSchemaVersion, readYjsParagraphSourceContract, withParagraphSourceContract, writeYjsAttrSchemaVersion, writeYjsDocumentMetadata };
|