@stll/folio-core 0.35.1 → 0.37.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/README.md +59 -1
- package/dist/ai-edits/apply.js +878 -377
- package/dist/ai-edits/block-identity.d.ts +4 -1
- package/dist/ai-edits/block-identity.js +4 -1
- package/dist/ai-edits/blockRange.js +14 -14
- package/dist/ai-edits/clean-text.d.ts +40 -1
- package/dist/ai-edits/clean-text.js +52 -2
- package/dist/ai-edits/headless.d.ts +3 -1
- package/dist/ai-edits/headless.js +141 -73
- package/dist/ai-edits/index.d.ts +3 -3
- package/dist/ai-edits/index.js +2 -2
- package/dist/ai-edits/read.js +38 -20
- package/dist/ai-edits/snapshot.d.ts +14 -6
- package/dist/ai-edits/snapshot.js +105 -20
- package/dist/ai-edits/table-cell-mutations.js +1 -1
- package/dist/ai-edits/table-row-column-mutations.js +7 -0
- package/dist/ai-edits/table-template.d.ts +11 -1
- package/dist/ai-edits/table-template.js +49 -17
- package/dist/ai-edits/types.d.ts +62 -61
- package/dist/ai-edits/word-diff.d.ts +18 -3
- package/dist/ai-edits/word-diff.js +556 -67
- package/dist/ai-suggestions/conflict.js +1 -4
- package/dist/ai-suggestions/text-positions.d.ts +8 -0
- package/dist/ai-suggestions/text-positions.js +27 -5
- package/dist/compare/__fixtures__/body-sequence.js +3 -4
- package/dist/compare/column-alignment.d.ts +13 -13
- package/dist/compare/column-alignment.js +78 -39
- package/dist/compare/compare.d.ts +4 -3
- package/dist/compare/compare.js +48 -21
- package/dist/compare/content-alignment.d.ts +95 -0
- package/dist/compare/content-alignment.js +1450 -0
- package/dist/compare/content-types.d.ts +100 -0
- package/dist/compare/content-types.js +0 -0
- package/dist/compare/content.d.ts +209 -0
- package/dist/compare/content.js +885 -0
- package/dist/compare/formatting.d.ts +5 -5
- package/dist/compare/formatting.js +6 -4
- package/dist/compare/plan.d.ts +6 -1
- package/dist/compare/plan.js +171 -566
- package/dist/compare/scenario.d.ts +2 -2
- package/dist/compare/types.d.ts +3 -3
- package/dist/compare/verification.d.ts +8 -9
- package/dist/compare/verification.js +72 -50
- package/dist/compat/eigenpal.d.ts +5 -3
- package/dist/compat/eigenpal.js +3 -2
- package/dist/controller/headerFooterEditorManager.js +18 -10
- package/dist/controller/hiddenEditorApi.js +1 -1
- package/dist/controller/hiddenEditorManager.d.ts +7 -2
- package/dist/controller/hiddenEditorManager.js +15 -6
- package/dist/controller/layoutPipeline.js +5 -3
- package/dist/controller/noteEditorManager.js +12 -7
- package/dist/display-list/build/headerFooterPrimitives.js +1 -0
- package/dist/display-list/build/storyPrimitives.d.ts +5 -2
- package/dist/display-list/build/storyPrimitives.js +60 -3
- package/dist/display-list/build/tablePrimitives.js +30 -0
- package/dist/display-list/primitives.d.ts +1 -1
- package/dist/document-operations.d.ts +8 -4
- package/dist/document-operations.js +104 -12
- package/dist/docx/blockContentParser.js +6 -27
- package/dist/docx/commentParser.js +2 -4
- package/dist/docx/commentRangeIntegrity.js +2 -4
- package/dist/docx/documentClone.d.ts +2 -0
- package/dist/docx/documentClone.js +2 -0
- package/dist/docx/ensureParaIds.js +9 -4
- package/dist/docx/headerFooterParser.js +2 -4
- package/dist/docx/normalizeBaseDirection.js +5 -7
- package/dist/docx/numberingParser.d.ts +3 -1
- package/dist/docx/numberingParser.js +4 -1
- package/dist/docx/paragraphParser.js +34 -35
- package/dist/docx/paragraphPropertySource.d.ts +49 -0
- package/dist/docx/paragraphPropertySource.js +113 -0
- package/dist/docx/paragraphTraversal.js +30 -34
- package/dist/docx/rezip.d.ts +0 -8
- package/dist/docx/rezip.js +41 -16
- package/dist/docx/runConsolidator.js +2 -4
- package/dist/docx/runParser.js +6 -17
- package/dist/docx/sectionParser.js +1 -15
- package/dist/docx/serializer/paragraphSerializer.js +289 -30
- package/dist/docx/serializer/runSerializer.js +6 -12
- package/dist/docx/serializer/sectionPropertiesSerializer.js +2 -10
- package/dist/docx/serializer/tableSerializer.js +4 -23
- package/dist/docx/serializer/trackedChangeAttributes.d.ts +11 -0
- package/dist/docx/serializer/trackedChangeAttributes.js +31 -0
- package/dist/docx/server/build.d.ts +1 -1
- package/dist/docx/server/createBilingualDocument.js +8 -10
- package/dist/docx/server/evaluateDocxXmlPatchProposal.js +22 -13
- package/dist/docx/server/validateDocxConformance.js +17 -13
- package/dist/docx/tableParser.js +1 -37
- package/dist/docx/trackedChangeInfo.d.ts +11 -0
- package/dist/docx/trackedChangeInfo.js +38 -0
- package/dist/docx/verbatimCapture.d.ts +20 -9
- package/dist/docx/verbatimCapture.js +208 -8
- package/dist/docx/xmlParser.d.ts +3 -1
- package/dist/docx/xmlParser.js +6 -1
- package/dist/docx/xmlSafety.d.ts +1 -1
- package/dist/docx/xmlSafety.js +157 -0
- package/dist/headless-layout.js +5 -4
- package/dist/index.d.ts +5 -3
- package/dist/index.js +3 -2
- package/dist/internal/headlessRevisionResolution.d.ts +23 -0
- package/dist/internal/headlessRevisionResolution.js +155 -0
- package/dist/internal/headlessRevisionResolutionGuard.d.ts +12 -0
- package/dist/internal/headlessRevisionResolutionGuard.js +28 -0
- package/dist/internal/pageBreakRunDescendantIndex.d.ts +9 -0
- package/dist/internal/pageBreakRunDescendantIndex.js +27 -0
- package/dist/internal/pageBreakRunPartition.d.ts +26 -0
- package/dist/internal/pageBreakRunPartition.js +35 -0
- package/dist/internal/pageBreakRunSourceDescendantIndex.d.ts +15 -0
- package/dist/internal/pageBreakRunSourceDescendantIndex.js +126 -0
- package/dist/internal/sectionEndpointResolution.d.ts +32 -0
- package/dist/internal/sectionEndpointResolution.js +38 -0
- package/dist/layout-bridge/convert/footnoteLayout.js +1 -0
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +16 -4
- package/dist/layout-bridge/convert/headerFooterLayout.js +52 -9
- package/dist/layout-bridge/convert/toFlowBlocks.d.ts +4 -0
- package/dist/layout-bridge/convert/toFlowBlocks.js +391 -82
- package/dist/layout-bridge/dom/clickToPositionDom.d.ts +8 -1
- package/dist/layout-bridge/dom/clickToPositionDom.js +114 -40
- package/dist/layout-bridge/dom/textStreamDom.d.ts +24 -0
- package/dist/layout-bridge/dom/textStreamDom.js +75 -0
- package/dist/layout-bridge/headerFooterLayout.js +16 -30
- package/dist/layout-engine/index.js +12 -3
- package/dist/layout-engine/measure/tableFragmentBorderGeometry.d.ts +17 -0
- package/dist/layout-engine/measure/tableFragmentBorderGeometry.js +24 -0
- package/dist/layout-engine/renderedBreakReconciliation.js +1 -1
- package/dist/layout-engine/types.d.ts +7 -0
- package/dist/layout-painter/imageLayout.d.ts +1 -1
- package/dist/layout-painter/renderTable.js +20 -0
- package/dist/markdown/renderBlock.js +7 -10
- package/dist/model.d.ts +1 -1
- package/dist/paged-layout/rangeProjection.js +6 -9
- package/dist/paged-layout/transactionDirtyRange.d.ts +3 -1
- package/dist/paged-layout/transactionDirtyRange.js +23 -1
- package/dist/prosemirror/attrs/index.d.ts +7 -3
- package/dist/prosemirror/attrs/index.js +128 -7
- package/dist/prosemirror/bookmarkBoundaryIntegrity.d.ts +9 -0
- package/dist/prosemirror/bookmarkBoundaryIntegrity.js +22 -0
- package/dist/prosemirror/commands/comments.d.ts +10 -1
- package/dist/prosemirror/commands/comments.js +551 -87
- package/dist/prosemirror/commands/formatPainter.d.ts +45 -10
- package/dist/prosemirror/commands/formatPainter.js +319 -63
- package/dist/prosemirror/commands/index.d.ts +2 -2
- package/dist/prosemirror/commands/pageBreak.d.ts +5 -2
- package/dist/prosemirror/commands/pageBreak.js +18 -36
- package/dist/prosemirror/commands/propertyChangeScope.d.ts +27 -3
- package/dist/prosemirror/commands/propertyChangeScope.js +85 -14
- package/dist/prosemirror/conversion/fromProseDoc.d.ts +8 -5
- package/dist/prosemirror/conversion/fromProseDoc.js +935 -223
- package/dist/prosemirror/conversion/runShadingMark.js +2 -2
- package/dist/prosemirror/conversion/toProseDoc.d.ts +26 -1
- package/dist/prosemirror/conversion/toProseDoc.js +439 -291
- package/dist/prosemirror/extensions/StarterKit.js +4 -0
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +54 -6
- package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +7 -1
- package/dist/prosemirror/extensions/features/ListExtension.js +95 -123
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +19 -6
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +27 -1
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +134 -30
- package/dist/prosemirror/extensions/features/pasteCleanup.js +9 -15
- package/dist/prosemirror/extensions/marks/BoldExtension.js +4 -3
- package/dist/prosemirror/extensions/marks/CharacterStyleExtension.d.ts +4 -7
- package/dist/prosemirror/extensions/marks/CharacterStyleExtension.js +5 -11
- package/dist/prosemirror/extensions/marks/FontSizeExtension.js +3 -3
- package/dist/prosemirror/extensions/marks/ItalicExtension.js +4 -3
- package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.d.ts +13 -0
- package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.js +39 -0
- package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.d.ts +7 -1
- package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.js +67 -21
- package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +2 -0
- package/dist/prosemirror/extensions/marks/markUtils.d.ts +8 -1
- package/dist/prosemirror/extensions/marks/markUtils.js +88 -2
- package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.js +44 -3
- package/dist/prosemirror/extensions/nodes/FieldExtension.js +1 -1
- package/dist/prosemirror/extensions/nodes/HardBreakExtension.js +15 -4
- package/dist/prosemirror/extensions/nodes/PageBreakExtension.d.ts +6 -0
- package/dist/prosemirror/extensions/nodes/PageBreakExtension.js +6 -0
- package/dist/prosemirror/extensions/nodes/PageBreakRunExtension.d.ts +6 -0
- package/dist/prosemirror/extensions/nodes/PageBreakRunExtension.js +36 -0
- package/dist/prosemirror/findReplaceSelection.js +8 -3
- package/dist/prosemirror/index.d.ts +3 -3
- package/dist/prosemirror/listMarker.d.ts +26 -1
- package/dist/prosemirror/listMarker.js +108 -14
- package/dist/prosemirror/pageBreakRunProjection.d.ts +28 -0
- package/dist/prosemirror/pageBreakRunProjection.js +47 -0
- package/dist/prosemirror/paraText.js +6 -0
- package/dist/prosemirror/paragraphAlignment.d.ts +12 -0
- package/dist/prosemirror/paragraphAlignment.js +13 -0
- package/dist/prosemirror/paragraphSpacing.d.ts +29 -0
- package/dist/prosemirror/paragraphSpacing.js +125 -0
- package/dist/prosemirror/plugins/documentNumbering.d.ts +8 -0
- package/dist/prosemirror/plugins/documentNumbering.js +18 -0
- package/dist/prosemirror/plugins/pmTextScan.d.ts +3 -2
- package/dist/prosemirror/plugins/pmTextScan.js +14 -4
- package/dist/prosemirror/plugins/suggestionMode.js +9 -11
- package/dist/prosemirror/rebaseParagraphRunFormatting.d.ts +16 -0
- package/dist/prosemirror/rebaseParagraphRunFormatting.js +61 -0
- package/dist/prosemirror/runFormattingInlineCarriers.d.ts +64 -0
- package/dist/prosemirror/runFormattingInlineCarriers.js +121 -0
- package/dist/prosemirror/runFormattingProvenance.d.ts +12 -0
- package/dist/prosemirror/runFormattingProvenance.js +48 -0
- package/dist/prosemirror/runFormattingReconciliation.d.ts +25 -0
- package/dist/prosemirror/runFormattingReconciliation.js +54 -0
- package/dist/prosemirror/runPropertyChangeResolution.d.ts +18 -0
- package/dist/prosemirror/runPropertyChangeResolution.js +18 -0
- package/dist/prosemirror/runStyleFormatting.d.ts +50 -0
- package/dist/prosemirror/runStyleFormatting.js +105 -0
- package/dist/prosemirror/schema/index.d.ts +3 -3
- package/dist/prosemirror/schema/marks.d.ts +84 -9
- package/dist/prosemirror/schema/marks.js +73 -1
- package/dist/prosemirror/schema/nodes.d.ts +30 -6
- package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +14 -2
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +45 -23
- package/dist/prosemirror/styles/styleResolver.d.ts +10 -13
- package/dist/prosemirror/styles/styleResolver.js +3 -3
- package/dist/prosemirror/styles/styleToggleCascade.d.ts +8 -1
- package/dist/prosemirror/styles/styleToggleCascade.js +24 -1
- package/dist/prosemirror/tableGridMutation.d.ts +20 -0
- package/dist/prosemirror/tableGridMutation.js +30 -0
- package/dist/prosemirror/trackedRunInlineAtoms.d.ts +31 -0
- package/dist/prosemirror/trackedRunInlineAtoms.js +39 -0
- package/dist/prosemirror/utils/visualLineNavigation.js +27 -31
- package/dist/prosemirror/validation.js +23 -4
- package/dist/redline.js +4 -1
- package/dist/render-dom/HeaderFooterSelectionOverlay.js +20 -20
- package/dist/render-dom/RenderedDomContext.js +17 -34
- package/dist/server.d.ts +4 -4
- package/dist/server.js +2 -2
- package/dist/style-engine/styleEngine.d.ts +1 -1
- package/dist/utils/clipboard.js +1 -1
- package/dist/utils/findReplace.js +38 -21
- package/dist/utils/mergeDocumentContent.js +3 -3
- package/dist/utils/replaceText.js +2 -1
- package/dist/version-comparison.d.ts +38 -44
- package/dist/version-comparison.js +270 -399
- package/dist/watermark/index.js +2 -4
- package/package.json +8 -2
|
@@ -6,7 +6,13 @@ import { SpacingExplicit } from "../../types/formatting.js";
|
|
|
6
6
|
import { ParagraphDirection } from "../paragraphDirection.js";
|
|
7
7
|
//#region src/prosemirror/schema/nodes.d.ts
|
|
8
8
|
type HardBreakAttrs = {
|
|
9
|
-
|
|
9
|
+
/** Absent means the source `w:br` omitted `w:type`. */
|
|
10
|
+
breakType?: "column" | "textWrapping";
|
|
11
|
+
clear?: "none" | "left" | "right" | "all";
|
|
12
|
+
};
|
|
13
|
+
/** Attributes preserved from an authored `<w:br w:type="page"/>`. */
|
|
14
|
+
type PageBreakRunAttrs = {
|
|
15
|
+
clear?: "none" | "left" | "right" | "all";
|
|
10
16
|
};
|
|
11
17
|
type TabAttrs = {
|
|
12
18
|
positional?: document_d_exports.PositionalTab;
|
|
@@ -32,6 +38,8 @@ type ParagraphAttrs = {
|
|
|
32
38
|
paraId?: string;
|
|
33
39
|
textId?: string;
|
|
34
40
|
alignment?: document_d_exports.ParagraphAlignment;
|
|
41
|
+
/** Effective inherited alignment beneath any direct `w:jc` override. */
|
|
42
|
+
alignmentFromStyle?: document_d_exports.ParagraphAlignment;
|
|
35
43
|
/** Effective East Asian line-edge policy (`w:kinsoku`). */
|
|
36
44
|
kinsoku?: boolean;
|
|
37
45
|
/** Effective hanging-punctuation policy (`w:overflowPunct`). */
|
|
@@ -42,12 +50,17 @@ type ParagraphAttrs = {
|
|
|
42
50
|
spaceAfter?: number;
|
|
43
51
|
lineSpacing?: number;
|
|
44
52
|
lineSpacingRule?: document_d_exports.LineSpacingRule;
|
|
45
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Which line-spacing attributes came from this paragraph's own `w:spacing`.
|
|
55
|
+
* `true` is accepted for editor states written before provenance became
|
|
56
|
+
* field-specific; newly created state uses the exact discriminator.
|
|
57
|
+
*/
|
|
58
|
+
lineSpacingExplicit?: boolean | "value" | "rule" | "both";
|
|
46
59
|
snapToGrid?: boolean;
|
|
47
60
|
spacingExplicit?: SpacingExplicit;
|
|
48
61
|
/** Layout provenance: document defaults survive on empty paragraphs. */
|
|
49
62
|
spacingFromDocDefaults?: SpacingExplicit;
|
|
50
|
-
/** Layout provenance:
|
|
63
|
+
/** Layout provenance: resolved paragraph/table-style spacing survives on empty paragraphs. */
|
|
51
64
|
spacingFromImplicitDefaultStyle?: SpacingExplicit;
|
|
52
65
|
indentLeft?: number;
|
|
53
66
|
indentRight?: number;
|
|
@@ -77,6 +90,8 @@ type ParagraphAttrs = {
|
|
|
77
90
|
listIsLegal?: boolean;
|
|
78
91
|
/** Computed list marker text (e.g., "1.", "1.1.", "•") */
|
|
79
92
|
listMarker?: string;
|
|
93
|
+
/** Source numbering pattern used to compute markers for inserted list siblings. */
|
|
94
|
+
listMarkerTemplate?: string;
|
|
80
95
|
/** Whether the list marker is hidden (w:vanish on numbering level rPr) */
|
|
81
96
|
listMarkerHidden?: boolean;
|
|
82
97
|
/** Canonical numbering-level marker typography, in OOXML units. */
|
|
@@ -205,10 +220,15 @@ type ParagraphAttrs = {
|
|
|
205
220
|
* snapshot fields alongside the canonical paragraph formatting fields.
|
|
206
221
|
* Keeping that shape typed here lets layout consume validated attrs directly.
|
|
207
222
|
*/
|
|
208
|
-
type ParagraphPropertyChangeAttrs = Omit<document_d_exports.ParagraphPropertyChange, "previousFormatting" | "currentFormatting"> & {
|
|
223
|
+
type ParagraphPropertyChangeAttrs = Omit<document_d_exports.ParagraphPropertyChange, "info" | "previousFormatting" | "currentFormatting"> & {
|
|
224
|
+
info: document_d_exports.ParagraphPropertyChange["info"] & {
|
|
225
|
+
/** Editor-only proposal provenance; stripped or re-authored before OOXML serialization. */
|
|
226
|
+
provenance?: TrackedChangeProvenance;
|
|
227
|
+
suggestionId?: string | null;
|
|
228
|
+
};
|
|
209
229
|
previousFormatting?: Omit<document_d_exports.ParagraphFormatting, "numPr"> & {
|
|
210
230
|
numPr?: document_d_exports.ParagraphFormatting["numPr"] | null;
|
|
211
|
-
} & Partial<Pick<ParagraphAttrs, "listIsBullet" | "listIsLegal" | "listNumFmt" | "listMarker" | "listMarkerHidden" | "listMarkerFormatting" | "listMarkerAlignment" | "listMarkerSuffix" | "listLevelNumFmts" | "listLevelStarts" | "listAbstractNumId" | "listStartOverride" | "lineSpacingExplicit" | "direction" | "_autospacingBase">>;
|
|
231
|
+
} & Partial<Pick<ParagraphAttrs, "listIsBullet" | "listIsLegal" | "listNumFmt" | "listMarker" | "listMarkerTemplate" | "listMarkerHidden" | "listMarkerFormatting" | "listMarkerAlignment" | "listMarkerSuffix" | "listMarkerAllCaps" | "listImplicitChildLevelAdvances" | "listMarkerSecondSlotOffsetTwips" | "listLevelNumFmts" | "listLevelStarts" | "listAbstractNumId" | "listStartOverride" | "lineSpacingExplicit" | "direction" | "_autospacingBase">>;
|
|
212
232
|
currentFormatting?: document_d_exports.ParagraphFormatting;
|
|
213
233
|
};
|
|
214
234
|
/**
|
|
@@ -622,6 +642,7 @@ type TableRowAttrs = {
|
|
|
622
642
|
revisionId: number;
|
|
623
643
|
author: string;
|
|
624
644
|
date?: string | null;
|
|
645
|
+
utcDate?: string | null;
|
|
625
646
|
initials?: string | null;
|
|
626
647
|
provenance?: TrackedChangeProvenance;
|
|
627
648
|
suggestionId?: string | null;
|
|
@@ -634,6 +655,7 @@ type TableRowAttrs = {
|
|
|
634
655
|
revisionId: number;
|
|
635
656
|
author: string;
|
|
636
657
|
date?: string | null;
|
|
658
|
+
utcDate?: string | null;
|
|
637
659
|
initials?: string | null;
|
|
638
660
|
provenance?: TrackedChangeProvenance;
|
|
639
661
|
suggestionId?: string | null;
|
|
@@ -717,6 +739,7 @@ type TableCellAttrs = {
|
|
|
717
739
|
revisionId: number;
|
|
718
740
|
author: string;
|
|
719
741
|
date?: string | null;
|
|
742
|
+
utcDate?: string | null;
|
|
720
743
|
initials?: string | null;
|
|
721
744
|
/** `"suggested"` marks this as an AI proposal (stripped until accepted). */
|
|
722
745
|
provenance?: TrackedChangeProvenance;
|
|
@@ -733,6 +756,7 @@ type TableCellAttrs = {
|
|
|
733
756
|
revisionId: number;
|
|
734
757
|
author: string;
|
|
735
758
|
date?: string | null;
|
|
759
|
+
utcDate?: string | null;
|
|
736
760
|
initials?: string | null;
|
|
737
761
|
};
|
|
738
762
|
verticalMerge?: "continue" | "rest";
|
|
@@ -744,4 +768,4 @@ type TableCellAttrs = {
|
|
|
744
768
|
_docxVMergeContinuationCells?: document_d_exports.TableCell[];
|
|
745
769
|
};
|
|
746
770
|
//#endregion
|
|
747
|
-
export { BlockSdtAttrs, BookmarkBoundaryAttrs, FieldAttrs, HardBreakAttrs, ImageAttrs, ImagePositionAttrs, MathAttrs, ParagraphAttrs, ParagraphPropertyChangeAttrs, SdtAttrs, ShapeAttrs, SuggestedStructuralMarker, SymbolAttrs, TabAttrs, TableAttrs, TableCellAttrs, TableRowAttrs, TextBoxAnchorAttrs, TextBoxAttrs };
|
|
771
|
+
export { BlockSdtAttrs, BookmarkBoundaryAttrs, FieldAttrs, HardBreakAttrs, ImageAttrs, ImagePositionAttrs, MathAttrs, PageBreakRunAttrs, ParagraphAttrs, ParagraphPropertyChangeAttrs, SdtAttrs, ShapeAttrs, SuggestedStructuralMarker, SymbolAttrs, TabAttrs, TableAttrs, TableCellAttrs, TableRowAttrs, TextBoxAnchorAttrs, TextBoxAttrs };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { NumberingMap } from "../../docx/numberingParser.js";
|
|
2
1
|
import { ResolvedParagraphStyle } from "./styleResolver.js";
|
|
2
|
+
import { NumberingMap } from "../../docx/numberingParser.js";
|
|
3
3
|
//#region src/prosemirror/styles/resolvedStyleAttrs.d.ts
|
|
4
4
|
type ResolvedStyleIdentity = {
|
|
5
5
|
styleId: string;
|
|
@@ -31,5 +31,17 @@ declare function paragraphAttrsFromResolvedStyle(resolved: ResolvedParagraphStyl
|
|
|
31
31
|
* subsequent save + reload re-derives them from the document content.
|
|
32
32
|
*/
|
|
33
33
|
declare function listAttrsFromResolvedStyle(resolved: ResolvedParagraphStyle, numbering: NumberingMap | null | undefined): Record<string, unknown> | null;
|
|
34
|
+
/** Project one resolved numbering level into the complete editor attr group. */
|
|
35
|
+
declare function listAttrsFromNumbering(numPr: {
|
|
36
|
+
numId: number;
|
|
37
|
+
ilvl: number;
|
|
38
|
+
}, numbering: NumberingMap | null | undefined): Record<string, unknown>;
|
|
39
|
+
/** Recompute every level-dependent attr when a paragraph changes list level. */
|
|
40
|
+
declare function listLevelAttrPatch(attrs: {
|
|
41
|
+
listImplicitChildLevelAdvances?: number | null;
|
|
42
|
+
}, numPr: {
|
|
43
|
+
numId: number;
|
|
44
|
+
ilvl: number;
|
|
45
|
+
}, numbering: NumberingMap | null | undefined): Record<string, unknown>;
|
|
34
46
|
//#endregion
|
|
35
|
-
export { listAttrsFromResolvedStyle, paragraphAttrsFromResolvedStyle };
|
|
47
|
+
export { listAttrsFromNumbering, listAttrsFromResolvedStyle, listLevelAttrPatch, paragraphAttrsFromResolvedStyle };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { computeListRendering } from "../../docx/numberingParser.js";
|
|
1
|
+
import { computeListRendering, numberingLevelHasMarkerSlot } from "../../docx/numberingParser.js";
|
|
2
2
|
import { tableOfContentsStyleLevel } from "../../utils/tableOfContentsStyle.js";
|
|
3
3
|
import { setAutospacingBaseValue } from "../autospacingBase.js";
|
|
4
|
+
import { CLEARED_LIST_RENDERING_ATTRS } from "../listMarker.js";
|
|
4
5
|
//#region src/prosemirror/styles/resolvedStyleAttrs.ts
|
|
5
6
|
/**
|
|
6
7
|
* Shared helper for projecting a resolved paragraph style onto ProseMirror
|
|
@@ -24,6 +25,7 @@ function paragraphAttrsFromResolvedStyle(resolved, identity) {
|
|
|
24
25
|
const hasRunFormatting = !!runFormatting && Object.keys(runFormatting).length > 0;
|
|
25
26
|
return {
|
|
26
27
|
alignment: ppr?.alignment ?? null,
|
|
28
|
+
alignmentFromStyle: ppr?.alignment,
|
|
27
29
|
spaceBefore: ppr?.spaceBefore ?? null,
|
|
28
30
|
spaceAfter: ppr?.spaceAfter ?? null,
|
|
29
31
|
lineSpacing: ppr?.lineSpacing ?? null,
|
|
@@ -72,42 +74,62 @@ function autospacingBaseFromResolvedParagraphFormatting(ppr) {
|
|
|
72
74
|
function listAttrsFromResolvedStyle(resolved, numbering) {
|
|
73
75
|
const numPr = resolved.paragraphFormatting?.numPr;
|
|
74
76
|
if (!numPr || numPr.numId === void 0 || numPr.numId === 0) return null;
|
|
75
|
-
const
|
|
77
|
+
const attrs = listAttrsFromNumbering({
|
|
78
|
+
numId: numPr.numId,
|
|
79
|
+
ilvl: numPr.ilvl ?? 0
|
|
80
|
+
}, numbering);
|
|
76
81
|
const level = numbering?.getLevel(numPr.numId, numPr.ilvl ?? 0);
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
attrs["numPrFromStyle"] = {
|
|
83
|
+
numId: numPr.numId,
|
|
84
|
+
ilvl: numPr.ilvl ?? 0
|
|
85
|
+
};
|
|
86
|
+
const ppr = resolved.paragraphFormatting;
|
|
87
|
+
if (level?.pPr) {
|
|
88
|
+
if (ppr?.indentLeft === void 0 && level.pPr.indentLeft !== void 0) attrs["indentLeft"] = level.pPr.indentLeft;
|
|
89
|
+
if (!(ppr?.indentFirstLine !== void 0 || ppr?.hangingIndent !== void 0) && numberingLevelHasMarkerSlot(level)) {
|
|
90
|
+
if (level.pPr.indentFirstLine !== void 0) attrs["indentFirstLine"] = level.pPr.indentFirstLine;
|
|
91
|
+
if (level.pPr.hangingIndent !== void 0) attrs["hangingIndent"] = level.pPr.hangingIndent;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return attrs;
|
|
95
|
+
}
|
|
96
|
+
/** Project one resolved numbering level into the complete editor attr group. */
|
|
97
|
+
function listAttrsFromNumbering(numPr, numbering) {
|
|
98
|
+
const targetNumPr = {
|
|
99
|
+
numId: numPr.numId,
|
|
100
|
+
ilvl: numPr.ilvl
|
|
101
|
+
};
|
|
102
|
+
const rendering = numbering ? computeListRendering(targetNumPr, numbering) : null;
|
|
103
|
+
return {
|
|
104
|
+
...CLEARED_LIST_RENDERING_ATTRS,
|
|
105
|
+
numPr: targetNumPr,
|
|
86
106
|
listNumFmt: rendering?.numFmt ?? null,
|
|
87
107
|
listIsBullet: rendering?.isBullet ?? null,
|
|
88
108
|
listIsLegal: rendering?.isLegal ?? null,
|
|
89
109
|
listMarker: rendering?.marker ?? null,
|
|
110
|
+
listMarkerTemplate: rendering?.markerTemplate ?? null,
|
|
90
111
|
listMarkerHidden: rendering?.markerHidden ?? null,
|
|
91
112
|
listMarkerFormatting: rendering?.markerFormatting ?? null,
|
|
92
113
|
listMarkerAlignment: rendering?.markerAlignment ?? null,
|
|
93
114
|
listMarkerSuffix: rendering?.markerSuffix ?? null,
|
|
94
115
|
listMarkerAllCaps: rendering?.markerAllCaps ?? null,
|
|
95
|
-
listImplicitChildLevelAdvances: null,
|
|
96
|
-
listMarkerSecondSlotOffsetTwips: null,
|
|
97
116
|
listLevelNumFmts: rendering?.levelNumFmts ?? null,
|
|
98
117
|
listLevelStarts: rendering?.levelStarts ?? null,
|
|
99
118
|
listAbstractNumId: rendering?.abstractNumId ?? null,
|
|
100
119
|
listStartOverride: rendering?.startOverride ?? null
|
|
101
120
|
};
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
121
|
+
}
|
|
122
|
+
/** Recompute every level-dependent attr when a paragraph changes list level. */
|
|
123
|
+
function listLevelAttrPatch(attrs, numPr, numbering) {
|
|
124
|
+
const level = numbering?.getLevel(numPr.numId, numPr.ilvl);
|
|
125
|
+
const hasMarkerSlot = level ? numberingLevelHasMarkerSlot(level) : false;
|
|
126
|
+
return {
|
|
127
|
+
...listAttrsFromNumbering(numPr, numbering),
|
|
128
|
+
listImplicitChildLevelAdvances: attrs.listImplicitChildLevelAdvances ?? null,
|
|
129
|
+
indentLeft: level?.pPr?.indentLeft ?? null,
|
|
130
|
+
indentFirstLine: hasMarkerSlot ? level?.pPr?.indentFirstLine ?? null : null,
|
|
131
|
+
hangingIndent: hasMarkerSlot ? level?.pPr?.hangingIndent ?? null : null
|
|
132
|
+
};
|
|
111
133
|
}
|
|
112
134
|
//#endregion
|
|
113
|
-
export { listAttrsFromResolvedStyle, paragraphAttrsFromResolvedStyle };
|
|
135
|
+
export { listAttrsFromNumbering, listAttrsFromResolvedStyle, listLevelAttrPatch, paragraphAttrsFromResolvedStyle };
|
|
@@ -10,21 +10,18 @@ type ResolvedParagraphStyle = {
|
|
|
10
10
|
runFormatting?: document_d_exports.TextFormatting;
|
|
11
11
|
};
|
|
12
12
|
/**
|
|
13
|
-
* Paragraph
|
|
14
|
-
*
|
|
13
|
+
* Paragraph fields sourced from the table style enclosing a cell paragraph:
|
|
14
|
+
* the table style's own `w:pPr`, then the applicable
|
|
15
15
|
* `w:tblStylePr` conditional region's `w:pPr` layered on top (already merged
|
|
16
16
|
* by the caller — see `resolveTableBaseStyle`/`resolveTableStyleConditional`
|
|
17
17
|
* in toProseDoc.ts).
|
|
18
18
|
*
|
|
19
|
-
* Deliberately narrower than the full {@link ParagraphFormatting}:
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* to `docDefaults`). Alignment, indentation, borders, etc. are out of scope
|
|
24
|
-
* here — applying the whole `pPr` would risk regressing unrelated cell
|
|
25
|
-
* layout that isn't part of this fix.
|
|
19
|
+
* Deliberately narrower than the full {@link ParagraphFormatting}: spacing
|
|
20
|
+
* affects table-row height, while `frame` participates in lossless page-break
|
|
21
|
+
* ownership checks. Other fields remain out of scope until their table-style
|
|
22
|
+
* projection is modeled end to end.
|
|
26
23
|
*/
|
|
27
|
-
type TableCellParagraphSpacingOverlay = Pick<document_d_exports.ParagraphFormatting, "spaceBefore" | "spaceAfter" | "lineSpacing" | "lineSpacingRule" | "contextualSpacing">;
|
|
24
|
+
type TableCellParagraphSpacingOverlay = Pick<document_d_exports.ParagraphFormatting, "spaceBefore" | "spaceAfter" | "lineSpacing" | "lineSpacingRule" | "contextualSpacing" | "frame">;
|
|
28
25
|
/**
|
|
29
26
|
* StyleResolver provides efficient access to resolved style properties
|
|
30
27
|
*/
|
|
@@ -52,7 +49,7 @@ declare class StyleResolver {
|
|
|
52
49
|
resolveParagraphStyle(styleId: string | undefined | null): ResolvedParagraphStyle;
|
|
53
50
|
/**
|
|
54
51
|
* Resolve paragraph style properties for a paragraph inside a table cell,
|
|
55
|
-
* layering the enclosing
|
|
52
|
+
* layering the modeled enclosing-table paragraph fields into the
|
|
56
53
|
* cascade between docDefaults and the paragraph's own style chain.
|
|
57
54
|
*
|
|
58
55
|
* Per ECMA-376 §17.7.2, a cell paragraph's properties resolve in this
|
|
@@ -68,10 +65,10 @@ declare class StyleResolver {
|
|
|
68
65
|
* paragraph style still wins over the table for any field it sets.
|
|
69
66
|
*
|
|
70
67
|
* @param styleId - The paragraph's style ID (e.g., 'Heading1', 'Normal')
|
|
71
|
-
* @param tableParagraphOverlay -
|
|
68
|
+
* @param tableParagraphOverlay - Modeled paragraph fields from the
|
|
72
69
|
* enclosing table style (base `pPr` merged with the applicable
|
|
73
70
|
* conditional region), or `undefined` when the paragraph isn't in a
|
|
74
|
-
* table cell, the table has no style, or the style sets
|
|
71
|
+
* table cell, the table has no style, or the style sets none of them.
|
|
75
72
|
* @returns Resolved paragraph and run formatting
|
|
76
73
|
*/
|
|
77
74
|
resolveParagraphStyleInTable(styleId: string | undefined | null, tableParagraphOverlay: TableCellParagraphSpacingOverlay | undefined): ResolvedParagraphStyle;
|
|
@@ -74,7 +74,7 @@ var StyleResolver = class {
|
|
|
74
74
|
}
|
|
75
75
|
/**
|
|
76
76
|
* Resolve paragraph style properties for a paragraph inside a table cell,
|
|
77
|
-
* layering the enclosing
|
|
77
|
+
* layering the modeled enclosing-table paragraph fields into the
|
|
78
78
|
* cascade between docDefaults and the paragraph's own style chain.
|
|
79
79
|
*
|
|
80
80
|
* Per ECMA-376 §17.7.2, a cell paragraph's properties resolve in this
|
|
@@ -90,10 +90,10 @@ var StyleResolver = class {
|
|
|
90
90
|
* paragraph style still wins over the table for any field it sets.
|
|
91
91
|
*
|
|
92
92
|
* @param styleId - The paragraph's style ID (e.g., 'Heading1', 'Normal')
|
|
93
|
-
* @param tableParagraphOverlay -
|
|
93
|
+
* @param tableParagraphOverlay - Modeled paragraph fields from the
|
|
94
94
|
* enclosing table style (base `pPr` merged with the applicable
|
|
95
95
|
* conditional region), or `undefined` when the paragraph isn't in a
|
|
96
|
-
* table cell, the table has no style, or the style sets
|
|
96
|
+
* table cell, the table has no style, or the style sets none of them.
|
|
97
97
|
* @returns Resolved paragraph and run formatting
|
|
98
98
|
*/
|
|
99
99
|
resolveParagraphStyleInTable(styleId, tableParagraphOverlay) {
|
|
@@ -23,6 +23,13 @@ type StyleToggleCascadeOptions = {
|
|
|
23
23
|
/** Existing ordinary-property merge whose toggle fields this cascade replaces. */
|
|
24
24
|
ordinaryFormatting: document_d_exports.TextFormatting | undefined;
|
|
25
25
|
};
|
|
26
|
+
type CascadeStyleFromResolvedBaseOptions = {
|
|
27
|
+
baseFormatting: document_d_exports.TextFormatting | undefined;
|
|
28
|
+
defaultsActiveProperties: readonly StyleToggleKey[] | undefined;
|
|
29
|
+
styleFormatting: document_d_exports.TextFormatting | undefined;
|
|
30
|
+
};
|
|
31
|
+
/** Continue a style cascade from a compact resolved paragraph snapshot. */
|
|
32
|
+
declare const cascadeStyleFromResolvedBase: ({ baseFormatting, defaultsActiveProperties, styleFormatting }: CascadeStyleFromResolvedBaseOptions) => document_d_exports.TextFormatting | undefined;
|
|
26
33
|
/**
|
|
27
34
|
* Resolve run formatting across OOXML style hierarchy levels.
|
|
28
35
|
*
|
|
@@ -34,4 +41,4 @@ type StyleToggleCascadeOptions = {
|
|
|
34
41
|
*/
|
|
35
42
|
declare function cascadeStyleTextFormatting(levels: readonly StyleToggleLevel[], options?: StyleToggleCascadeOptions): StyleTextFormattingCascade;
|
|
36
43
|
//#endregion
|
|
37
|
-
export { cascadeStyleTextFormatting };
|
|
44
|
+
export { StyleToggleKey, cascadeStyleFromResolvedBase, cascadeStyleTextFormatting };
|
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
import { STYLE_TOGGLE_KEYS, mergeTextFormatting } from "../../utils/textFormattingMerge.js";
|
|
2
2
|
//#region src/prosemirror/styles/styleToggleCascade.ts
|
|
3
|
+
/** Continue a style cascade from a compact resolved paragraph snapshot. */
|
|
4
|
+
const cascadeStyleFromResolvedBase = ({ baseFormatting, defaultsActiveProperties, styleFormatting }) => {
|
|
5
|
+
const defaultsActive = new Set(defaultsActiveProperties);
|
|
6
|
+
const toggleStates = /* @__PURE__ */ new Map();
|
|
7
|
+
for (const key of STYLE_TOGGLE_KEYS) {
|
|
8
|
+
const value = baseFormatting?.[key];
|
|
9
|
+
if (value !== void 0) toggleStates.set(key, {
|
|
10
|
+
value,
|
|
11
|
+
defaultsActive: defaultsActive.has(key)
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
return cascadeStyleTextFormatting([{
|
|
15
|
+
cascade: {
|
|
16
|
+
formatting: baseFormatting,
|
|
17
|
+
toggleStates,
|
|
18
|
+
type: "styleToggleCascade"
|
|
19
|
+
},
|
|
20
|
+
type: "carried"
|
|
21
|
+
}, {
|
|
22
|
+
formatting: styleFormatting,
|
|
23
|
+
type: "style"
|
|
24
|
+
}]).formatting;
|
|
25
|
+
};
|
|
3
26
|
/**
|
|
4
27
|
* Resolve run formatting across OOXML style hierarchy levels.
|
|
5
28
|
*
|
|
@@ -49,4 +72,4 @@ function cascadeStyleTextFormatting(levels, options) {
|
|
|
49
72
|
};
|
|
50
73
|
}
|
|
51
74
|
//#endregion
|
|
52
|
-
export { cascadeStyleTextFormatting };
|
|
75
|
+
export { cascadeStyleFromResolvedBase, cascadeStyleTextFormatting };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Transaction } from "prosemirror-state";
|
|
2
|
+
import { Node } from "prosemirror-model";
|
|
3
|
+
//#region src/prosemirror/tableGridMutation.d.ts
|
|
4
|
+
type ReconcileTableGridAfterColumnRemovalOptions = {
|
|
5
|
+
tr: Transaction;
|
|
6
|
+
tablePosition: number;
|
|
7
|
+
previousTable: Node;
|
|
8
|
+
removedColumn: number;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Keep the editable table grid aligned with a physical column removal.
|
|
12
|
+
*
|
|
13
|
+
* `prosemirror-tables` owns cell topology, but Folio separately retains the
|
|
14
|
+
* authored `w:tblGrid` widths and source XML on the table node. A topology
|
|
15
|
+
* edit that leaves those attrs untouched serializes a new row shape against
|
|
16
|
+
* the old grid; reopening then has to interpret surviving cells as spans.
|
|
17
|
+
*/
|
|
18
|
+
declare const reconcileTableGridAfterColumnRemoval: ({ tr, tablePosition, previousTable, removedColumn }: ReconcileTableGridAfterColumnRemovalOptions) => void;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { reconcileTableGridAfterColumnRemoval };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { expectTableAttrs, mergeTableAttrs } from "./attrs/index.js";
|
|
2
|
+
import { TableMap } from "prosemirror-tables";
|
|
3
|
+
//#region src/prosemirror/tableGridMutation.ts
|
|
4
|
+
/**
|
|
5
|
+
* Keep the editable table grid aligned with a physical column removal.
|
|
6
|
+
*
|
|
7
|
+
* `prosemirror-tables` owns cell topology, but Folio separately retains the
|
|
8
|
+
* authored `w:tblGrid` widths and source XML on the table node. A topology
|
|
9
|
+
* edit that leaves those attrs untouched serializes a new row shape against
|
|
10
|
+
* the old grid; reopening then has to interpret surviving cells as spans.
|
|
11
|
+
*/
|
|
12
|
+
const reconcileTableGridAfterColumnRemoval = ({ tr, tablePosition, previousTable, removedColumn }) => {
|
|
13
|
+
const previousColumnCount = TableMap.get(previousTable).width;
|
|
14
|
+
const table = tr.doc.nodeAt(tablePosition);
|
|
15
|
+
if (!table || table.type.spec["tableRole"] !== "table") return;
|
|
16
|
+
const columnCount = TableMap.get(table).width;
|
|
17
|
+
if (columnCount >= previousColumnCount) return;
|
|
18
|
+
const removedColumnCount = previousColumnCount - columnCount;
|
|
19
|
+
const previousWidths = expectTableAttrs(previousTable).columnWidths;
|
|
20
|
+
const columnWidths = previousWidths?.length === previousColumnCount ? previousWidths.toSpliced(removedColumn, removedColumnCount) : void 0;
|
|
21
|
+
const formatting = expectTableAttrs(table)._originalFormatting;
|
|
22
|
+
const originalFormatting = formatting ? { ...formatting } : void 0;
|
|
23
|
+
if (originalFormatting) delete originalFormatting.gridSourceXml;
|
|
24
|
+
tr.setNodeMarkup(tablePosition, void 0, mergeTableAttrs(table, {
|
|
25
|
+
columnWidths: columnWidths?.length === columnCount ? columnWidths : void 0,
|
|
26
|
+
_originalFormatting: originalFormatting
|
|
27
|
+
}));
|
|
28
|
+
};
|
|
29
|
+
//#endregion
|
|
30
|
+
export { reconcileTableGridAfterColumnRemoval };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Node } from "prosemirror-model";
|
|
2
|
+
//#region src/prosemirror/trackedRunInlineAtoms.d.ts
|
|
3
|
+
type TrackedRunInlineAtomDisposition = "carry" | "field-carrier" | "outside-wrapper" | "page-break-carrier" | "text-carrier" | "transparent";
|
|
4
|
+
/**
|
|
5
|
+
* How every inline atom in the editor schema participates in an OOXML
|
|
6
|
+
* run-level tracked-change wrapper.
|
|
7
|
+
*
|
|
8
|
+
* The schema is assembled at runtime, so the fixed-point test binds this map
|
|
9
|
+
* to its complete inline-atom set. The lookup also panics on a missing entry:
|
|
10
|
+
* a new atom cannot silently lose revision ownership before that test runs.
|
|
11
|
+
*/
|
|
12
|
+
declare const TRACKED_RUN_INLINE_ATOM_DISPOSITIONS: Readonly<{
|
|
13
|
+
readonly bookmarkBoundary: "carry";
|
|
14
|
+
readonly field: "field-carrier";
|
|
15
|
+
readonly hardBreak: "carry";
|
|
16
|
+
readonly image: "carry";
|
|
17
|
+
readonly math: "outside-wrapper";
|
|
18
|
+
readonly pageBreakRun: "page-break-carrier";
|
|
19
|
+
readonly renderedPageBreak: "transparent";
|
|
20
|
+
readonly shape: "carry";
|
|
21
|
+
readonly structuredField: "carry";
|
|
22
|
+
readonly symbol: "carry";
|
|
23
|
+
readonly tab: "carry";
|
|
24
|
+
readonly text: "text-carrier";
|
|
25
|
+
readonly textBoxAnchor: "carry";
|
|
26
|
+
}>;
|
|
27
|
+
declare const trackedRunInlineAtomDisposition: (node: Node) => TrackedRunInlineAtomDisposition | null;
|
|
28
|
+
/** Whether an editor node can own an insertion/deletion mark as one run carrier. */
|
|
29
|
+
declare const canCarryTrackedRunMark: (node: Node) => boolean;
|
|
30
|
+
//#endregion
|
|
31
|
+
export { TRACKED_RUN_INLINE_ATOM_DISPOSITIONS, TrackedRunInlineAtomDisposition, canCarryTrackedRunMark, trackedRunInlineAtomDisposition };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { panic } from "better-result";
|
|
2
|
+
//#region src/prosemirror/trackedRunInlineAtoms.ts
|
|
3
|
+
/**
|
|
4
|
+
* How every inline atom in the editor schema participates in an OOXML
|
|
5
|
+
* run-level tracked-change wrapper.
|
|
6
|
+
*
|
|
7
|
+
* The schema is assembled at runtime, so the fixed-point test binds this map
|
|
8
|
+
* to its complete inline-atom set. The lookup also panics on a missing entry:
|
|
9
|
+
* a new atom cannot silently lose revision ownership before that test runs.
|
|
10
|
+
*/
|
|
11
|
+
const TRACKED_RUN_INLINE_ATOM_DISPOSITIONS = Object.freeze({
|
|
12
|
+
bookmarkBoundary: "carry",
|
|
13
|
+
field: "field-carrier",
|
|
14
|
+
hardBreak: "carry",
|
|
15
|
+
image: "carry",
|
|
16
|
+
math: "outside-wrapper",
|
|
17
|
+
pageBreakRun: "page-break-carrier",
|
|
18
|
+
renderedPageBreak: "transparent",
|
|
19
|
+
shape: "carry",
|
|
20
|
+
structuredField: "carry",
|
|
21
|
+
symbol: "carry",
|
|
22
|
+
tab: "carry",
|
|
23
|
+
text: "text-carrier",
|
|
24
|
+
textBoxAnchor: "carry"
|
|
25
|
+
});
|
|
26
|
+
const dispositionsByName = new Map(Object.entries(TRACKED_RUN_INLINE_ATOM_DISPOSITIONS));
|
|
27
|
+
const trackedRunInlineAtomDisposition = (node) => {
|
|
28
|
+
if (!node.isInline || !node.isAtom) return null;
|
|
29
|
+
const disposition = dispositionsByName.get(node.type.name);
|
|
30
|
+
if (!disposition) panic(`Inline atom ${JSON.stringify(node.type.name)} has no tracked-run disposition`);
|
|
31
|
+
return disposition;
|
|
32
|
+
};
|
|
33
|
+
/** Whether an editor node can own an insertion/deletion mark as one run carrier. */
|
|
34
|
+
const canCarryTrackedRunMark = (node) => {
|
|
35
|
+
const disposition = trackedRunInlineAtomDisposition(node);
|
|
36
|
+
return disposition === "carry" || disposition === "field-carrier" || disposition === "text-carrier" || disposition === "page-break-carrier";
|
|
37
|
+
};
|
|
38
|
+
//#endregion
|
|
39
|
+
export { TRACKED_RUN_INLINE_ATOM_DISPOSITIONS, canCarryTrackedRunMark, trackedRunInlineAtomDisposition };
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { findBodyEmptyRuns, findBodyPmSpans } from "../../layout-bridge/dom/findBodyPmSpans.js";
|
|
2
|
+
import { createTextStreamRange, descendantTextNodes, totalTextLength } from "../../layout-bridge/dom/textStreamDom.js";
|
|
1
3
|
import { findVerticalScrollParent } from "../../utils/findVerticalScrollParent.js";
|
|
2
4
|
import { TextSelection } from "prosemirror-state";
|
|
3
5
|
//#region src/prosemirror/utils/visualLineNavigation.ts
|
|
@@ -33,28 +35,21 @@ function scrollIntoViewIfNeeded(el) {
|
|
|
33
35
|
}
|
|
34
36
|
/** @internal */
|
|
35
37
|
function getCaretClientX(container, pmPos) {
|
|
36
|
-
const
|
|
37
|
-
for (const span of Array.from(spans)) {
|
|
38
|
-
const spanEl = span;
|
|
38
|
+
for (const spanEl of findBodyPmSpans(container)) {
|
|
39
39
|
const pmStart = Number(spanEl.dataset["pmStart"]);
|
|
40
40
|
const pmEnd = Number(spanEl.dataset["pmEnd"]);
|
|
41
41
|
if (spanEl.classList.contains("layout-run-tab")) {
|
|
42
42
|
if (pmPos >= pmStart && pmPos < pmEnd) return spanEl.getBoundingClientRect().left;
|
|
43
43
|
continue;
|
|
44
44
|
}
|
|
45
|
-
if (pmPos >= pmStart && pmPos <= pmEnd
|
|
46
|
-
const
|
|
47
|
-
const charIndex = Math.min(pmPos - pmStart,
|
|
48
|
-
const
|
|
49
|
-
if (
|
|
50
|
-
const range = ownerDoc.createRange();
|
|
51
|
-
range.setStart(textNode, charIndex);
|
|
52
|
-
range.setEnd(textNode, charIndex);
|
|
53
|
-
return range.getBoundingClientRect().left;
|
|
45
|
+
if (pmPos >= pmStart && pmPos <= pmEnd) {
|
|
46
|
+
const textNodes = descendantTextNodes(spanEl);
|
|
47
|
+
const charIndex = Math.min(pmPos - pmStart, totalTextLength(textNodes));
|
|
48
|
+
const range = createTextStreamRange(spanEl, charIndex, charIndex);
|
|
49
|
+
if (range) return range.getBoundingClientRect().left;
|
|
54
50
|
}
|
|
55
51
|
}
|
|
56
|
-
const
|
|
57
|
-
for (const emptyRun of Array.from(emptyRuns)) {
|
|
52
|
+
for (const emptyRun of findBodyEmptyRuns(container)) {
|
|
58
53
|
const paragraph = emptyRun.closest(".layout-paragraph");
|
|
59
54
|
if (!paragraph) continue;
|
|
60
55
|
const pmStart = Number(paragraph.dataset["pmStart"]);
|
|
@@ -91,6 +86,13 @@ function findLineElementAtPosition(container, pmPos) {
|
|
|
91
86
|
/** @internal */
|
|
92
87
|
function findPositionOnLineAtClientX(lineEl, clientX) {
|
|
93
88
|
const spans = lineEl.querySelectorAll("span[data-pm-start][data-pm-end]");
|
|
89
|
+
const emptyRun = lineEl.querySelector(".layout-empty-run");
|
|
90
|
+
if (emptyRun) {
|
|
91
|
+
const emptyRunStart = emptyRun.dataset["pmStart"];
|
|
92
|
+
if (emptyRunStart !== void 0) return Number(emptyRunStart);
|
|
93
|
+
const paragraphStart = emptyRun.closest(".layout-paragraph")?.dataset["pmStart"];
|
|
94
|
+
return paragraphStart === void 0 ? null : Number(paragraphStart) + 1;
|
|
95
|
+
}
|
|
94
96
|
if (spans.length === 0) {
|
|
95
97
|
const paragraph = lineEl.closest(".layout-paragraph");
|
|
96
98
|
if (paragraph?.dataset["pmStart"]) return Number(paragraph.dataset["pmStart"]) + 1;
|
|
@@ -106,29 +108,23 @@ function findPositionOnLineAtClientX(lineEl, clientX) {
|
|
|
106
108
|
continue;
|
|
107
109
|
}
|
|
108
110
|
if (clientX >= rect.left && clientX <= rect.right) {
|
|
109
|
-
const
|
|
110
|
-
if (
|
|
111
|
-
const text = textNode;
|
|
112
|
-
const ownerDoc = spanEl.ownerDocument;
|
|
113
|
-
if (!ownerDoc) return pmStart;
|
|
111
|
+
const textLength = totalTextLength(descendantTextNodes(spanEl));
|
|
112
|
+
if (textLength === 0) return pmStart;
|
|
114
113
|
let lo = 0;
|
|
115
|
-
let hi =
|
|
114
|
+
let hi = textLength;
|
|
116
115
|
while (lo < hi) {
|
|
117
116
|
const mid = Math.floor((lo + hi) / 2);
|
|
118
|
-
const r =
|
|
119
|
-
r
|
|
120
|
-
r.setEnd(text, mid);
|
|
117
|
+
const r = createTextStreamRange(spanEl, mid, mid);
|
|
118
|
+
if (!r) return pmStart;
|
|
121
119
|
if (clientX < r.getBoundingClientRect().left) hi = mid;
|
|
122
120
|
else lo = mid + 1;
|
|
123
121
|
}
|
|
124
|
-
if (lo > 0 && lo <=
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const leftX =
|
|
129
|
-
|
|
130
|
-
r.setEnd(text, Math.min(lo, text.length));
|
|
131
|
-
const rightX = r.getBoundingClientRect().left;
|
|
122
|
+
if (lo > 0 && lo <= textLength) {
|
|
123
|
+
const left = createTextStreamRange(spanEl, lo - 1, lo - 1);
|
|
124
|
+
const right = createTextStreamRange(spanEl, Math.min(lo, textLength), Math.min(lo, textLength));
|
|
125
|
+
if (!left || !right) return pmStart;
|
|
126
|
+
const leftX = left.getBoundingClientRect().left;
|
|
127
|
+
const rightX = right.getBoundingClientRect().left;
|
|
132
128
|
if (Math.abs(clientX - leftX) < Math.abs(clientX - rightX)) return pmStart + (lo - 1);
|
|
133
129
|
}
|
|
134
130
|
return pmStart + Math.min(lo, pmEnd - pmStart);
|