@stll/folio-core 0.36.0 → 0.37.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -1
- package/dist/ai-edits/apply.js +689 -367
- 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 +133 -71
- 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 +99 -19
- 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 +60 -57
- 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 +41 -5
- 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 +201 -569
- package/dist/compare/scenario.d.ts +2 -2
- package/dist/compare/types.d.ts +3 -3
- package/dist/compare/verification.d.ts +2 -2
- package/dist/compare/verification.js +25 -8
- package/dist/compat/eigenpal.d.ts +5 -3
- package/dist/compat/eigenpal.js +3 -2
- package/dist/controller/headerFooterEditorManager.js +14 -6
- 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 -6
- package/dist/document-operations.js +121 -26
- package/dist/docx/blockContentParser.js +6 -27
- package/dist/docx/ensureParaIds.js +9 -4
- package/dist/docx/numberingParser.d.ts +3 -1
- package/dist/docx/numberingParser.js +4 -1
- package/dist/docx/paragraphParser.js +7 -6
- 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/runParser.js +4 -2
- package/dist/docx/serializer/paragraphSerializer.js +2 -0
- package/dist/docx/serializer/runSerializer.js +5 -3
- package/dist/docx/serializer/trackedChangeAttributes.d.ts +3 -1
- package/dist/docx/serializer/trackedChangeAttributes.js +11 -1
- package/dist/docx/server/build.d.ts +1 -1
- 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 +176 -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 +48 -5
- package/dist/layout-bridge/convert/toFlowBlocks.d.ts +4 -0
- package/dist/layout-bridge/convert/toFlowBlocks.js +379 -75
- 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/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 +113 -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 +167 -59
- 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 +7 -5
- package/dist/prosemirror/commands/propertyChangeScope.js +27 -18
- package/dist/prosemirror/conversion/fromProseDoc.d.ts +7 -2
- package/dist/prosemirror/conversion/fromProseDoc.js +809 -209
- package/dist/prosemirror/conversion/runShadingMark.js +2 -2
- package/dist/prosemirror/conversion/toProseDoc.d.ts +26 -1
- package/dist/prosemirror/conversion/toProseDoc.js +416 -283
- package/dist/prosemirror/extensions/StarterKit.js +4 -0
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +12 -8
- package/dist/prosemirror/extensions/features/ListExtension.js +95 -123
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +1 -1
- 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/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/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 +8 -10
- 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 +82 -9
- package/dist/prosemirror/schema/marks.js +73 -1
- package/dist/prosemirror/schema/nodes.d.ts +18 -5
- package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +14 -2
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +44 -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/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/version-comparison.d.ts +38 -44
- package/dist/version-comparison.js +270 -401
- package/package.json +3 -2
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//#region src/internal/pageBreakRunPartition.ts
|
|
2
|
+
/** Partition ordered runs with one monotonic cursor; each run is consumed once and peeked once. */
|
|
3
|
+
const partitionRunsAtPageBreaks = (runs, pageBreaks) => {
|
|
4
|
+
const partitions = [];
|
|
5
|
+
let nextRunIndex = 0;
|
|
6
|
+
for (const pageBreak of pageBreaks) {
|
|
7
|
+
const before = [];
|
|
8
|
+
while (nextRunIndex < runs.length) {
|
|
9
|
+
const run = runs[nextRunIndex];
|
|
10
|
+
if (!run) break;
|
|
11
|
+
if (run.pmEnd !== void 0 && run.pmEnd <= pageBreak.pmStart) {
|
|
12
|
+
before.push(run);
|
|
13
|
+
nextRunIndex += 1;
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
if (run.pmStart !== void 0 && run.pmStart >= pageBreak.pmEnd) break;
|
|
17
|
+
return {
|
|
18
|
+
type: "overlap",
|
|
19
|
+
pageBreak,
|
|
20
|
+
run
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
partitions.push({
|
|
24
|
+
before,
|
|
25
|
+
pageBreak
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
type: "partitioned",
|
|
30
|
+
partitions,
|
|
31
|
+
remaining: runs.slice(nextRunIndex)
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
//#endregion
|
|
35
|
+
export { partitionRunsAtPageBreaks };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
//#region src/internal/pageBreakRunSourceDescendantIndex.d.ts
|
|
3
|
+
type PageBreakRunSourceDescendantIndex = {
|
|
4
|
+
containsPageBreakRun: (content: readonly document_d_exports.BlockContent[]) => boolean;
|
|
5
|
+
paragraphFeatures: (paragraph: document_d_exports.Paragraph) => PageBreakRunSourceParagraphFeatures;
|
|
6
|
+
};
|
|
7
|
+
type PageBreakRunSourceParagraphFeatures = {
|
|
8
|
+
hasPageBreakRun: boolean;
|
|
9
|
+
hasTextBoxShape: boolean;
|
|
10
|
+
pageBreakSharesTextBoxShape: boolean;
|
|
11
|
+
};
|
|
12
|
+
/** Index authored page-break descendants once for one source conversion. */
|
|
13
|
+
declare const buildPageBreakRunSourceDescendantIndex: (rootContent: readonly document_d_exports.BlockContent[]) => PageBreakRunSourceDescendantIndex;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { PageBreakRunSourceDescendantIndex, PageBreakRunSourceParagraphFeatures, buildPageBreakRunSourceDescendantIndex };
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { panic } from "better-result";
|
|
2
|
+
//#region src/internal/pageBreakRunSourceDescendantIndex.ts
|
|
3
|
+
const SOURCE_FLAGS = {
|
|
4
|
+
containsPageBreak: 1,
|
|
5
|
+
paragraphPageBreak: 2,
|
|
6
|
+
paragraphTextBoxShape: 4,
|
|
7
|
+
pageBreakSharesTextBoxShape: 8
|
|
8
|
+
};
|
|
9
|
+
const hasFlag = (flags, flag) => (flags & flag) !== 0;
|
|
10
|
+
/** Index authored page-break descendants once for one source conversion. */
|
|
11
|
+
const buildPageBreakRunSourceDescendantIndex = (rootContent) => {
|
|
12
|
+
const flagsByObject = /* @__PURE__ */ new WeakMap();
|
|
13
|
+
const inspectObject = (node, inspectChildren) => {
|
|
14
|
+
const cached = flagsByObject.get(node);
|
|
15
|
+
if (cached !== void 0) return cached;
|
|
16
|
+
flagsByObject.set(node, 0);
|
|
17
|
+
const flags = inspectChildren();
|
|
18
|
+
flagsByObject.set(node, flags);
|
|
19
|
+
return flags;
|
|
20
|
+
};
|
|
21
|
+
const inspectMany = (items, inspect) => {
|
|
22
|
+
let flags = 0;
|
|
23
|
+
for (const item of items) flags |= inspect(item);
|
|
24
|
+
return flags;
|
|
25
|
+
};
|
|
26
|
+
const inspectRunContent = (content) => inspectObject(content, () => {
|
|
27
|
+
switch (content.type) {
|
|
28
|
+
case "break": return content.breakType === "page" ? SOURCE_FLAGS.containsPageBreak | SOURCE_FLAGS.paragraphPageBreak : 0;
|
|
29
|
+
case "shape": {
|
|
30
|
+
const { textBody } = content.shape;
|
|
31
|
+
if (!textBody) return 0;
|
|
32
|
+
return inspectBlocks(textBody.content) & SOURCE_FLAGS.containsPageBreak | SOURCE_FLAGS.paragraphTextBoxShape;
|
|
33
|
+
}
|
|
34
|
+
case "drawing":
|
|
35
|
+
case "endnoteRef":
|
|
36
|
+
case "fieldChar":
|
|
37
|
+
case "footnoteRef":
|
|
38
|
+
case "instrText":
|
|
39
|
+
case "noBreakHyphen":
|
|
40
|
+
case "renderedPageBreak":
|
|
41
|
+
case "softHyphen":
|
|
42
|
+
case "symbol":
|
|
43
|
+
case "tab":
|
|
44
|
+
case "text": return 0;
|
|
45
|
+
default: return content;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
const inspectRun = (run) => inspectObject(run, () => {
|
|
49
|
+
const flags = inspectMany(run.content, inspectRunContent);
|
|
50
|
+
if (hasFlag(flags, SOURCE_FLAGS.paragraphPageBreak) && hasFlag(flags, SOURCE_FLAGS.paragraphTextBoxShape)) return flags | SOURCE_FLAGS.pageBreakSharesTextBoxShape;
|
|
51
|
+
return flags;
|
|
52
|
+
});
|
|
53
|
+
const inspectParagraphContent = (content) => {
|
|
54
|
+
if (content.type === "run") return inspectRun(content);
|
|
55
|
+
return inspectObject(content, () => {
|
|
56
|
+
switch (content.type) {
|
|
57
|
+
case "hyperlink": return inspectMany(content.children, inspectParagraphContent);
|
|
58
|
+
case "insertion":
|
|
59
|
+
case "deletion":
|
|
60
|
+
case "moveFrom":
|
|
61
|
+
case "moveTo":
|
|
62
|
+
case "inlineSdt": return inspectMany(content.content, inspectParagraphContent);
|
|
63
|
+
case "simpleField": {
|
|
64
|
+
const fieldResultFlags = inspectMany(content.content, inspectParagraphContent);
|
|
65
|
+
if (hasFlag(fieldResultFlags, SOURCE_FLAGS.paragraphPageBreak) && hasFlag(fieldResultFlags, SOURCE_FLAGS.paragraphTextBoxShape)) return fieldResultFlags | SOURCE_FLAGS.pageBreakSharesTextBoxShape;
|
|
66
|
+
return fieldResultFlags;
|
|
67
|
+
}
|
|
68
|
+
case "complexField": {
|
|
69
|
+
const fieldCodeFlags = inspectMany(content.fieldCode, inspectRun);
|
|
70
|
+
const fieldResultFlags = inspectMany(content.fieldResult, inspectRun);
|
|
71
|
+
const fieldFlags = fieldCodeFlags | fieldResultFlags;
|
|
72
|
+
if (hasFlag(fieldResultFlags, SOURCE_FLAGS.paragraphPageBreak) && hasFlag(fieldResultFlags, SOURCE_FLAGS.paragraphTextBoxShape)) return fieldFlags | SOURCE_FLAGS.pageBreakSharesTextBoxShape;
|
|
73
|
+
return fieldFlags;
|
|
74
|
+
}
|
|
75
|
+
case "bookmarkStart":
|
|
76
|
+
case "bookmarkEnd":
|
|
77
|
+
case "commentRangeStart":
|
|
78
|
+
case "commentRangeEnd":
|
|
79
|
+
case "commentReference":
|
|
80
|
+
case "moveFromRangeStart":
|
|
81
|
+
case "moveFromRangeEnd":
|
|
82
|
+
case "moveToRangeStart":
|
|
83
|
+
case "moveToRangeEnd":
|
|
84
|
+
case "mathEquation": return 0;
|
|
85
|
+
default: return content;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
const inspectTableCell = (cell) => inspectObject(cell, () => inspectBlocks(cell.content));
|
|
90
|
+
const inspectTableRow = (row) => inspectObject(row, () => inspectMany(row.cells, inspectTableCell));
|
|
91
|
+
const inspectBlock = (block) => inspectObject(block, () => {
|
|
92
|
+
switch (block.type) {
|
|
93
|
+
case "paragraph": return inspectMany(block.content, inspectParagraphContent);
|
|
94
|
+
case "table": return inspectMany(block.rows, inspectTableRow);
|
|
95
|
+
case "blockSdt": return inspectBlocks(block.content);
|
|
96
|
+
default: return block;
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
function inspectBlocks(content) {
|
|
100
|
+
const cached = flagsByObject.get(content);
|
|
101
|
+
if (cached !== void 0) return cached;
|
|
102
|
+
flagsByObject.set(content, 0);
|
|
103
|
+
const flags = inspectMany(content, inspectBlock);
|
|
104
|
+
flagsByObject.set(content, flags);
|
|
105
|
+
return flags;
|
|
106
|
+
}
|
|
107
|
+
inspectBlocks(rootContent);
|
|
108
|
+
return {
|
|
109
|
+
containsPageBreakRun: (content) => {
|
|
110
|
+
const flags = flagsByObject.get(content);
|
|
111
|
+
if (flags === void 0) panic("Page-break source ownership was queried outside its conversion index");
|
|
112
|
+
return hasFlag(flags, SOURCE_FLAGS.containsPageBreak);
|
|
113
|
+
},
|
|
114
|
+
paragraphFeatures: (paragraph) => {
|
|
115
|
+
const flags = flagsByObject.get(paragraph);
|
|
116
|
+
if (flags === void 0) panic("Page-break paragraph ownership was queried outside its conversion index");
|
|
117
|
+
return {
|
|
118
|
+
hasPageBreakRun: hasFlag(flags, SOURCE_FLAGS.paragraphPageBreak),
|
|
119
|
+
hasTextBoxShape: hasFlag(flags, SOURCE_FLAGS.paragraphTextBoxShape),
|
|
120
|
+
pageBreakSharesTextBoxShape: hasFlag(flags, SOURCE_FLAGS.pageBreakSharesTextBoxShape)
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
//#endregion
|
|
126
|
+
export { buildPageBreakRunSourceDescendantIndex };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
//#region src/internal/sectionEndpointResolution.d.ts
|
|
3
|
+
type RemovedSectionReference = {
|
|
4
|
+
part: "header" | "footer";
|
|
5
|
+
type: document_d_exports.HeaderFooterType;
|
|
6
|
+
relationshipId: string;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Exact resolution evidence produced when tracked-change resolution removes
|
|
10
|
+
* section endpoints. The tracker binds this count transition to exact endpoint
|
|
11
|
+
* fingerprints; removed references bind the only relationship losses that the
|
|
12
|
+
* same resolution may legitimately cause during package serialization.
|
|
13
|
+
*/
|
|
14
|
+
type TrackedSectionEndpointRemoval = {
|
|
15
|
+
type: "tracked-section-endpoint-removal";
|
|
16
|
+
sourceParagraphEndpointCount: number;
|
|
17
|
+
expectedParagraphEndpointCount: number;
|
|
18
|
+
sourceEndpointFingerprint: string;
|
|
19
|
+
expectedEndpointFingerprint: string;
|
|
20
|
+
removedReferences: readonly RemovedSectionReference[];
|
|
21
|
+
};
|
|
22
|
+
type WithTrackedSectionEndpointRemovalOptions<T> = {
|
|
23
|
+
document: document_d_exports.Document;
|
|
24
|
+
resolution: TrackedSectionEndpointRemoval;
|
|
25
|
+
repack: () => Promise<T>;
|
|
26
|
+
};
|
|
27
|
+
/** Run one repack with an exact authorization that no public save API accepts. */
|
|
28
|
+
declare const withTrackedSectionEndpointRemoval: <T>({ document, resolution, repack }: WithTrackedSectionEndpointRemovalOptions<T>) => Promise<T>;
|
|
29
|
+
/** @internal Consume the active authorization once for the exact document object. */
|
|
30
|
+
declare const consumeTrackedSectionEndpointRemoval: (document: document_d_exports.Document) => TrackedSectionEndpointRemoval | null;
|
|
31
|
+
//#endregion
|
|
32
|
+
export { RemovedSectionReference, TrackedSectionEndpointRemoval, consumeTrackedSectionEndpointRemoval, withTrackedSectionEndpointRemoval };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { panic } from "better-result";
|
|
2
|
+
//#region src/internal/sectionEndpointResolution.ts
|
|
3
|
+
const activeSectionEndpointRepacks = /* @__PURE__ */ new WeakMap();
|
|
4
|
+
const snapshotAuthorization = (authorization) => {
|
|
5
|
+
const removedReferences = Object.freeze(authorization.removedReferences.map((reference) => Object.freeze({ ...reference })));
|
|
6
|
+
return Object.freeze({
|
|
7
|
+
...authorization,
|
|
8
|
+
removedReferences
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
/** Run one repack with an exact authorization that no public save API accepts. */
|
|
12
|
+
const withTrackedSectionEndpointRemoval = async ({ document, resolution, repack }) => {
|
|
13
|
+
if (activeSectionEndpointRepacks.has(document)) panic("A tracked section-endpoint repack is already active for this document");
|
|
14
|
+
const snapshot = snapshotAuthorization(resolution);
|
|
15
|
+
activeSectionEndpointRepacks.set(document, {
|
|
16
|
+
status: "available",
|
|
17
|
+
authorization: snapshot
|
|
18
|
+
});
|
|
19
|
+
try {
|
|
20
|
+
const result = await repack();
|
|
21
|
+
if (activeSectionEndpointRepacks.get(document)?.status !== "consumed") panic("Tracked section-endpoint repack did not consume its authorization");
|
|
22
|
+
return result;
|
|
23
|
+
} finally {
|
|
24
|
+
activeSectionEndpointRepacks.delete(document);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
/** @internal Consume the active authorization once for the exact document object. */
|
|
28
|
+
const consumeTrackedSectionEndpointRemoval = (document) => {
|
|
29
|
+
const active = activeSectionEndpointRepacks.get(document);
|
|
30
|
+
if (!active || active.status === "consumed") return null;
|
|
31
|
+
activeSectionEndpointRepacks.set(document, {
|
|
32
|
+
status: "consumed",
|
|
33
|
+
authorization: active.authorization
|
|
34
|
+
});
|
|
35
|
+
return active.authorization;
|
|
36
|
+
};
|
|
37
|
+
//#endregion
|
|
38
|
+
export { consumeTrackedSectionEndpointRemoval, withTrackedSectionEndpointRemoval };
|
|
@@ -197,6 +197,7 @@ function convertFootnoteToContent(footnote, displayNumber, contentWidth, options
|
|
|
197
197
|
if (options.theme !== void 0) proseOptions.theme = options.theme;
|
|
198
198
|
const pmDoc = footnoteToProseDoc(footnote.content, proseOptions);
|
|
199
199
|
const flowOptions = {};
|
|
200
|
+
if (options.styles) flowOptions.styles = options.styles;
|
|
200
201
|
if (options.theme !== void 0) flowOptions.theme = options.theme;
|
|
201
202
|
if (options.fontAlternates !== void 0) flowOptions.fontAlternates = options.fontAlternates;
|
|
202
203
|
if (options.defaultTabStopTwips !== void 0) flowOptions.defaultTabStopTwips = options.defaultTabStopTwips;
|
|
@@ -79,9 +79,21 @@ declare function convertHeaderFooterToContent(headerFooter: document_d_exports.H
|
|
|
79
79
|
*
|
|
80
80
|
* The pmDoc is expected to be a body-shaped PM doc (the result of
|
|
81
81
|
* `headerFooterToProseDoc` at mount, plus any user edits applied since).
|
|
82
|
-
* Theme
|
|
83
|
-
*
|
|
82
|
+
* Theme and styles are threaded again because effective character-style
|
|
83
|
+
* toggles cannot all be represented by the flattened ProseMirror marks.
|
|
84
84
|
*/
|
|
85
|
-
declare function convertHeaderFooterPmDocToContent(pmDoc: Node | null | undefined, contentWidth: number, metrics: HeaderFooterMetrics, options:
|
|
85
|
+
declare function convertHeaderFooterPmDocToContent(pmDoc: Node | null | undefined, contentWidth: number, metrics: HeaderFooterMetrics, options: ConvertHeaderFooterOptions): HeaderFooterContent | undefined;
|
|
86
|
+
/**
|
|
87
|
+
* A paragraph-relative wrapping image that spans the whole story width leaves
|
|
88
|
+
* no side on which following content can flow. Retain the host paragraph's
|
|
89
|
+
* line box and reserve the complete anchored extent after it.
|
|
90
|
+
*/
|
|
91
|
+
type ReserveHeaderFooterFullWidthWrapBandsOptions = {
|
|
92
|
+
blocks: FlowBlock[];
|
|
93
|
+
measures: Measure[];
|
|
94
|
+
contentWidth: number;
|
|
95
|
+
metrics: HeaderFooterMetrics;
|
|
96
|
+
};
|
|
97
|
+
declare function reserveHeaderFooterFullWidthWrapBands({ blocks, measures, contentWidth, metrics }: ReserveHeaderFooterFullWidthWrapBandsOptions): Measure[];
|
|
86
98
|
//#endregion
|
|
87
|
-
export { ConvertHeaderFooterOptions, HeaderFooterMetrics, calculateHeaderFooterBodyTopClearance, calculateHeaderFooterMarginPushBounds, calculateHeaderFooterVisualBounds, convertHeaderFooterPmDocToContent, convertHeaderFooterToContent, normalizeHeaderFooterMeasureBlocks, resolveHeaderFooterPositionedVisualTop, resolveHeaderFooterVisualTop };
|
|
99
|
+
export { ConvertHeaderFooterOptions, HeaderFooterMetrics, calculateHeaderFooterBodyTopClearance, calculateHeaderFooterMarginPushBounds, calculateHeaderFooterVisualBounds, convertHeaderFooterPmDocToContent, convertHeaderFooterToContent, normalizeHeaderFooterMeasureBlocks, reserveHeaderFooterFullWidthWrapBands, resolveHeaderFooterPositionedVisualTop, resolveHeaderFooterVisualTop };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { cloneParagraphWithPropertySource } from "../../docx/paragraphPropertySource.js";
|
|
2
|
-
import { isFloatingImageRun, isFloatingTextBoxBlock } from "../../layout-engine/types.js";
|
|
2
|
+
import { isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun } from "../../layout-engine/types.js";
|
|
3
3
|
import { headerFooterToProseDoc } from "../../prosemirror/conversion/toProseDoc.js";
|
|
4
4
|
import { emuToPixels } from "../../utils/units.js";
|
|
5
5
|
import { toFlowBlocks } from "./toFlowBlocks.js";
|
|
@@ -342,6 +342,7 @@ function convertHeaderFooterToContent(headerFooter, contentWidth, metrics, optio
|
|
|
342
342
|
if (options.theme !== void 0) proseDocOptions.theme = options.theme;
|
|
343
343
|
const pmDoc = headerFooter.watermarkBlockIndex === void 0 ? headerFooterToProseDoc(headerFooter.content, proseDocOptions) : headerFooterToProseDocWithDetachedWatermarkHost(headerFooter, proseDocOptions);
|
|
344
344
|
const flowOptions = {};
|
|
345
|
+
if (options.styles) flowOptions.styles = options.styles;
|
|
345
346
|
if (options.theme !== void 0) flowOptions.theme = options.theme;
|
|
346
347
|
if (options.fontAlternates !== void 0) flowOptions.fontAlternates = options.fontAlternates;
|
|
347
348
|
if (options.defaultTabStopTwips !== void 0) flowOptions.defaultTabStopTwips = options.defaultTabStopTwips;
|
|
@@ -359,12 +360,13 @@ function convertHeaderFooterToContent(headerFooter, contentWidth, metrics, optio
|
|
|
359
360
|
*
|
|
360
361
|
* The pmDoc is expected to be a body-shaped PM doc (the result of
|
|
361
362
|
* `headerFooterToProseDoc` at mount, plus any user edits applied since).
|
|
362
|
-
* Theme
|
|
363
|
-
*
|
|
363
|
+
* Theme and styles are threaded again because effective character-style
|
|
364
|
+
* toggles cannot all be represented by the flattened ProseMirror marks.
|
|
364
365
|
*/
|
|
365
366
|
function convertHeaderFooterPmDocToContent(pmDoc, contentWidth, metrics, options) {
|
|
366
367
|
if (!pmDoc || pmDoc.content.size === 0) return;
|
|
367
368
|
const flowOptions = {};
|
|
369
|
+
if (options.styles) flowOptions.styles = options.styles;
|
|
368
370
|
if (options.theme !== void 0) flowOptions.theme = options.theme;
|
|
369
371
|
if (options.fontAlternates !== void 0) flowOptions.fontAlternates = options.fontAlternates;
|
|
370
372
|
if (options.defaultTabStopTwips !== void 0) flowOptions.defaultTabStopTwips = options.defaultTabStopTwips;
|
|
@@ -374,10 +376,51 @@ function convertHeaderFooterPmDocToContent(pmDoc, contentWidth, metrics, options
|
|
|
374
376
|
if (options.automaticHyphenation) flowOptions.automaticHyphenation = options.automaticHyphenation;
|
|
375
377
|
return finalizeHeaderFooterContent(toFlowBlocks(pmDoc, flowOptions), contentWidth, metrics, options);
|
|
376
378
|
}
|
|
379
|
+
function horizontalImageLeft({ run, contentWidth, metrics }) {
|
|
380
|
+
const horizontal = run.position?.horizontal;
|
|
381
|
+
if (horizontal?.posOffset !== void 0) return (horizontal.relativeTo === "page" ? -metrics.margins.left : 0) + emuToPixels(horizontal.posOffset);
|
|
382
|
+
const alignment = getPositionAlignment(horizontal);
|
|
383
|
+
const frameWidth = horizontal?.relativeTo === "page" ? metrics.pageSize.w : contentWidth;
|
|
384
|
+
const frameLeft = horizontal?.relativeTo === "page" ? -metrics.margins.left : 0;
|
|
385
|
+
if (alignment === "center") return frameLeft + (frameWidth - run.width) / 2;
|
|
386
|
+
if (alignment === "right" || alignment === "outside") return frameLeft + frameWidth - run.width;
|
|
387
|
+
return frameLeft;
|
|
388
|
+
}
|
|
389
|
+
function reserveHeaderFooterFullWidthWrapBands({ blocks, measures, contentWidth, metrics }) {
|
|
390
|
+
return measures.map((measure, index) => {
|
|
391
|
+
const block = blocks[index];
|
|
392
|
+
if (block?.kind !== "paragraph" || measure.kind !== "paragraph") return measure;
|
|
393
|
+
let reservedHeight = 0;
|
|
394
|
+
for (const run of block.runs) {
|
|
395
|
+
if (run.kind !== "image" || !isTextWrappingFloatingImageRun(run)) continue;
|
|
396
|
+
const relativeTo = run.position?.vertical?.relativeTo;
|
|
397
|
+
if (relativeTo !== void 0 && relativeTo !== "paragraph" && relativeTo !== "line") continue;
|
|
398
|
+
const distLeft = run.distLeft ?? 0;
|
|
399
|
+
const left = horizontalImageLeft({
|
|
400
|
+
run,
|
|
401
|
+
contentWidth,
|
|
402
|
+
metrics
|
|
403
|
+
}) - distLeft;
|
|
404
|
+
const right = left + run.width + distLeft + (run.distRight ?? 0);
|
|
405
|
+
if (left > 0 || right < contentWidth) continue;
|
|
406
|
+
const offset = emuToPixels(run.position?.vertical?.posOffset ?? 0);
|
|
407
|
+
reservedHeight = Math.max(reservedHeight, Math.max(0, offset) + run.height + (run.distBottom ?? 0));
|
|
408
|
+
}
|
|
409
|
+
return reservedHeight > 0 ? {
|
|
410
|
+
...measure,
|
|
411
|
+
totalHeight: measure.totalHeight + reservedHeight
|
|
412
|
+
} : measure;
|
|
413
|
+
});
|
|
414
|
+
}
|
|
377
415
|
function finalizeHeaderFooterContent(blocks, contentWidth, metrics, options) {
|
|
378
416
|
if (blocks.length === 0) return;
|
|
379
417
|
const blocksForMeasure = normalizeHeaderFooterMeasureBlocks(blocks, metrics.section);
|
|
380
|
-
const measures =
|
|
418
|
+
const measures = reserveHeaderFooterFullWidthWrapBands({
|
|
419
|
+
blocks,
|
|
420
|
+
measures: options.measureBlocks(blocksForMeasure, contentWidth),
|
|
421
|
+
contentWidth,
|
|
422
|
+
metrics
|
|
423
|
+
});
|
|
381
424
|
let flowHeight = 0;
|
|
382
425
|
for (let i = 0; i < measures.length; i++) {
|
|
383
426
|
const m = measures[i];
|
|
@@ -532,4 +575,4 @@ function serializeRunFmt(run) {
|
|
|
532
575
|
return JSON.stringify(out);
|
|
533
576
|
}
|
|
534
577
|
//#endregion
|
|
535
|
-
export { calculateHeaderFooterBodyTopClearance, calculateHeaderFooterMarginPushBounds, calculateHeaderFooterVisualBounds, convertHeaderFooterPmDocToContent, convertHeaderFooterToContent, normalizeHeaderFooterMeasureBlocks, resolveHeaderFooterPositionedVisualTop, resolveHeaderFooterVisualTop };
|
|
578
|
+
export { calculateHeaderFooterBodyTopClearance, calculateHeaderFooterMarginPushBounds, calculateHeaderFooterVisualBounds, convertHeaderFooterPmDocToContent, convertHeaderFooterToContent, normalizeHeaderFooterMeasureBlocks, reserveHeaderFooterFullWidthWrapBands, resolveHeaderFooterPositionedVisualTop, resolveHeaderFooterVisualTop };
|
|
@@ -14,10 +14,14 @@ type ToFlowBlocksOptions = {
|
|
|
14
14
|
defaultSize?: number;
|
|
15
15
|
/** Theme for resolving theme colors. */
|
|
16
16
|
theme?: document_d_exports.Theme | null;
|
|
17
|
+
/** Document styles used to resolve character-style toggles without per-run copies. */
|
|
18
|
+
styles?: document_d_exports.StyleDefinitions;
|
|
17
19
|
/** Document-scoped OOXML primary-font to `w:altName` lookup. */
|
|
18
20
|
fontAlternates?: FontAlternates;
|
|
19
21
|
/** Page content height in pixels (pageHeight - marginTop - marginBottom). Images taller than this are scaled down to fit. */
|
|
20
22
|
pageContentHeight?: number;
|
|
23
|
+
/** Whether a trailing page break moves its paragraph mark to the next page. */
|
|
24
|
+
splitPageBreakAndParagraphMark?: boolean;
|
|
21
25
|
/** Shared list counters for nested containers. */
|
|
22
26
|
listCounters?: Map<number, number[]>;
|
|
23
27
|
/** Latest concrete counters by abstract numbering definition. */
|