@stll/folio-core 0.7.0 → 0.9.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 +39 -0
- package/dist/ai-edits/apply.js +18 -4
- package/dist/ai-edits/blockRange.d.ts +13 -2
- package/dist/ai-edits/blockRange.js +23 -2
- package/dist/ai-edits/headless.d.ts +31 -4
- package/dist/ai-edits/headless.js +148 -35
- package/dist/ai-edits/index.d.ts +6 -4
- package/dist/ai-edits/index.js +4 -1
- package/dist/ai-edits/scoped-reading.d.ts +9 -0
- package/dist/ai-edits/scoped-reading.js +60 -0
- package/dist/ai-edits/snapshot.js +53 -7
- package/dist/ai-edits/types.d.ts +46 -3
- package/dist/compat/eigenpal.d.ts +8 -3
- package/dist/compat/eigenpal.js +7 -2
- package/dist/controller/fontReadiness.d.ts +29 -0
- package/dist/controller/fontReadiness.js +139 -0
- package/dist/controller/latestRequestGate.d.ts +13 -0
- package/dist/controller/latestRequestGate.js +16 -0
- package/dist/controller/layoutPipeline.js +88 -10
- package/dist/document-operations.d.ts +10 -3
- package/dist/document-operations.js +29 -14
- package/dist/docx/blockContentParser.js +53 -10
- package/dist/docx/commentParser.js +1 -1
- package/dist/docx/compatibility.d.ts +30 -2
- package/dist/docx/compatibility.js +118 -39
- package/dist/docx/conformance.d.ts +6 -0
- package/dist/docx/conformance.js +18 -0
- package/dist/docx/encryption/agileDecryption.js +1 -1
- package/dist/docx/encryption/encryptionInfo.js +1 -1
- package/dist/docx/encryption/openEncryptedDocx.js +1 -1
- package/dist/docx/ensureParaIds.d.ts +29 -0
- package/dist/docx/ensureParaIds.js +423 -0
- package/dist/docx/fontTableParser.d.ts +6 -0
- package/dist/docx/fontTableParser.js +72 -0
- package/dist/docx/groupDrawingParser.js +7 -2
- package/dist/docx/headerFooterParser.js +1 -1
- package/dist/docx/normalizeBaseDirection.js +1 -1
- package/dist/docx/numberingParser.js +2 -0
- package/dist/docx/paragraphParser.js +21 -1
- package/dist/docx/paragraphTextBoxEnrichment.js +141 -2
- package/dist/docx/parser.d.ts +1 -1
- package/dist/docx/parser.js +14 -9
- package/dist/docx/rezip.js +70 -5
- package/dist/docx/runConsolidator.js +4 -0
- package/dist/docx/runParser.js +19 -1
- package/dist/docx/selectiveSave.js +3 -3
- package/dist/docx/selectiveXmlPatch.d.ts +10 -1
- package/dist/docx/selectiveXmlPatch.js +1 -1
- package/dist/docx/serializer/fontTableSerializer.d.ts +6 -0
- package/dist/docx/serializer/fontTableSerializer.js +26 -0
- package/dist/docx/serializer/headerFooterSerializer.js +1 -1
- package/dist/docx/serializer/paragraphSerializer.js +8 -0
- package/dist/docx/serializer/runSerializer.js +14 -2
- package/dist/docx/serializer/settingsSerializer.d.ts +6 -0
- package/dist/docx/serializer/settingsSerializer.js +16 -0
- package/dist/docx/serializer/stylesSerializer.d.ts +6 -0
- package/dist/docx/serializer/stylesSerializer.js +56 -0
- package/dist/docx/serializer/tableSerializer.js +29 -26
- package/dist/docx/serializer/themeSerializer.d.ts +6 -0
- package/dist/docx/serializer/themeSerializer.js +36 -0
- package/dist/docx/settingsParser.js +46 -0
- package/dist/docx/styleParser.js +26 -1
- package/dist/docx/tableParser.js +19 -1
- package/dist/docx/textBoxParser.js +6 -1
- package/dist/docx/vmlImageParser.js +146 -1
- package/dist/i18n/messages/catalogs.gen.d.ts +5916 -5916
- package/dist/i18n/messages/catalogs.gen.js +5910 -5910
- package/dist/index.d.ts +8 -3
- package/dist/index.js +7 -2
- package/dist/layout-bridge/convert/footnoteLayout.d.ts +3 -0
- package/dist/layout-bridge/convert/footnoteLayout.js +3 -1
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +3 -0
- package/dist/layout-bridge/convert/headerFooterLayout.js +22 -3
- package/dist/layout-bridge/convert/paragraphFrames.d.ts +7 -0
- package/dist/layout-bridge/convert/paragraphFrames.js +136 -0
- package/dist/layout-bridge/convert/toFlowBlocks.d.ts +14 -2
- package/dist/layout-bridge/convert/toFlowBlocks.js +93 -17
- package/dist/layout-bridge/engine/hitTest.js +2 -1
- package/dist/layout-bridge/engine/measuring/index.d.ts +2 -1
- package/dist/layout-bridge/engine/measuring/index.js +2 -1
- package/dist/layout-bridge/engine/selectionRects.js +2 -1
- package/dist/layout-engine/headerFooterRefs.d.ts +7 -0
- package/dist/layout-engine/headerFooterRefs.js +40 -0
- package/dist/layout-engine/index.d.ts +3 -2
- package/dist/layout-engine/index.js +68 -106
- package/dist/layout-engine/measure/cache.js +11 -3
- package/dist/layout-engine/measure/font-metrics.worker.js +1 -0
- package/dist/layout-engine/measure/index.d.ts +2 -1
- package/dist/layout-engine/measure/index.js +2 -1
- package/dist/layout-engine/measure/lineBreakProvider.d.ts +33 -0
- package/dist/layout-engine/measure/lineBreakProvider.js +252 -0
- package/dist/layout-engine/measure/lineBreaks.d.ts +7 -2
- package/dist/layout-engine/measure/lineBreaks.js +11 -18
- package/dist/layout-engine/measure/listMarkerWidth.d.ts +4 -1
- package/dist/layout-engine/measure/listMarkerWidth.js +33 -8
- package/dist/layout-engine/measure/measureBlocks.d.ts +4 -2
- package/dist/layout-engine/measure/measureBlocks.js +138 -86
- package/dist/layout-engine/measure/measureContainer.js +32 -9
- package/dist/layout-engine/measure/measureHelpers.js +5 -2
- package/dist/layout-engine/measure/measureParagraph.js +346 -74
- package/dist/layout-engine/measure/measureTypes.d.ts +2 -1
- package/dist/layout-engine/measure/measureWorker.d.ts +2 -2
- package/dist/layout-engine/measure/measureWorker.js +8 -19
- package/dist/layout-engine/measure/measureWorkerProtocol.d.ts +3 -14
- package/dist/layout-engine/measure/tableCellFloating.d.ts +10 -3
- package/dist/layout-engine/measure/tableCellFloating.js +37 -29
- package/dist/layout-engine/measure/tableCellFlow.d.ts +27 -0
- package/dist/layout-engine/measure/tableCellFlow.js +73 -0
- package/dist/layout-engine/measure/tableCellGrid.d.ts +15 -0
- package/dist/layout-engine/measure/tableCellGrid.js +62 -0
- package/dist/layout-engine/measure/textBoxParagraphLayout.d.ts +18 -0
- package/dist/layout-engine/measure/textBoxParagraphLayout.js +32 -0
- package/dist/layout-engine/measure/textMeasurementPolicy.d.ts +18 -0
- package/dist/layout-engine/measure/textMeasurementPolicy.js +24 -0
- package/dist/layout-engine/paginator.d.ts +2 -1
- package/dist/layout-engine/paginator.js +7 -6
- package/dist/layout-engine/paragraphFrame.d.ts +22 -0
- package/dist/layout-engine/paragraphFrame.js +17 -0
- package/dist/layout-engine/paragraphSequence.d.ts +7 -0
- package/dist/layout-engine/paragraphSequence.js +25 -0
- package/dist/layout-engine/paragraphSpacing.d.ts +17 -0
- package/dist/layout-engine/paragraphSpacing.js +30 -0
- package/dist/layout-engine/renderedBreakReconciliation.d.ts +63 -0
- package/dist/layout-engine/renderedBreakReconciliation.js +86 -0
- package/dist/layout-engine/tableRowBreak.d.ts +5 -2
- package/dist/layout-engine/tableRowBreak.js +62 -29
- package/dist/layout-engine/types.d.ts +54 -12
- package/dist/layout-engine/types.js +15 -2
- package/dist/layout-painter/anchoredImagePosition.d.ts +23 -0
- package/dist/layout-painter/anchoredImagePosition.js +95 -0
- package/dist/layout-painter/borderStroke.d.ts +23 -0
- package/dist/layout-painter/borderStroke.js +39 -0
- package/dist/layout-painter/renderImage.d.ts +5 -4
- package/dist/layout-painter/renderImage.js +18 -4
- package/dist/layout-painter/renderPage.d.ts +2 -27
- package/dist/layout-painter/renderPage.js +15 -101
- package/dist/layout-painter/renderParagraph.js +45 -26
- package/dist/layout-painter/renderTable.d.ts +2 -0
- package/dist/layout-painter/renderTable.js +257 -47
- package/dist/layout-painter/renderTextBox.js +17 -7
- package/dist/managers/DocumentLoaderManager.d.ts +1 -1
- package/dist/managers/DocumentLoaderManager.js +2 -2
- package/dist/paged-layout/sectionBlockWidths.d.ts +3 -0
- package/dist/paged-layout/sectionBlockWidths.js +9 -0
- package/dist/paged-layout/sectionGeometry.js +1 -1
- package/dist/prosemirror/attrs/index.d.ts +4 -2
- package/dist/prosemirror/attrs/index.js +32 -2
- package/dist/prosemirror/commands/propertyChangeScope.js +1 -1
- package/dist/prosemirror/conversion/fromProseDoc.js +35 -18
- package/dist/prosemirror/conversion/toProseDoc.js +73 -37
- package/dist/prosemirror/extensions/StarterKit.js +2 -0
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +8 -2
- package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +1 -1
- package/dist/prosemirror/extensions/features/ListExtension.js +2 -0
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +68 -16
- package/dist/prosemirror/extensions/marks/FootnoteRefExtension.js +1 -0
- package/dist/prosemirror/extensions/marks/HighlightExtension.js +1 -1
- package/dist/prosemirror/extensions/marks/LanguageExtension.d.ts +7 -0
- package/dist/prosemirror/extensions/marks/LanguageExtension.js +30 -0
- package/dist/prosemirror/extensions/marks/RunShadingExtension.js +1 -1
- package/dist/prosemirror/extensions/marks/TextColorExtension.js +1 -1
- package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +1 -1
- package/dist/prosemirror/extensions/marks/markUtils.js +12 -0
- package/dist/prosemirror/extensions/nodes/ImageExtension.js +2 -1
- package/dist/prosemirror/extensions/nodes/TableExtension.js +4 -2
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.d.ts +2 -1
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +7 -0
- package/dist/prosemirror/schema/index.d.ts +2 -2
- package/dist/prosemirror/schema/marks.d.ts +6 -1
- package/dist/prosemirror/schema/nodes.d.ts +16 -12
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +2 -0
- package/dist/prosemirror/utils/tabCalculator.d.ts +3 -1
- package/dist/prosemirror/utils/tabCalculator.js +12 -10
- package/dist/prosemirror/validation.js +4 -1
- package/dist/redline.js +13 -3
- package/dist/server.d.ts +9 -4
- package/dist/server.js +7 -2
- package/dist/style-sets/extract.d.ts +35 -0
- package/dist/style-sets/extract.js +123 -0
- package/dist/style-sets/stellaStyle.d.ts +13 -0
- package/dist/style-sets/stellaStyle.js +516 -0
- package/dist/style-sets/types.d.ts +31 -0
- package/dist/style-sets/types.js +5 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/utils/createDocument.d.ts +12 -2
- package/dist/utils/createDocument.js +55 -36
- package/dist/utils/fontResolver.js +6 -6
- package/dist/utils/formatToStyle.js +1 -1
- package/dist/utils/hexId.d.ts +8 -1
- package/dist/utils/hexId.js +11 -3
- package/dist/utils/paragraphFormattingMerge.d.ts +14 -3
- package/dist/utils/paragraphFormattingMerge.js +14 -4
- package/package.json +5 -1
|
@@ -22,12 +22,28 @@ const createFolioAIEditSnapshot = (doc) => {
|
|
|
22
22
|
const draftBlocks = [];
|
|
23
23
|
const hashCounts = /* @__PURE__ */ new Map();
|
|
24
24
|
const usedBlockIds = /* @__PURE__ */ new Set();
|
|
25
|
+
const emptyAnchorState = {
|
|
26
|
+
candidate: null,
|
|
27
|
+
textblockCount: 0
|
|
28
|
+
};
|
|
25
29
|
let blockIndex = 0;
|
|
26
|
-
doc.descendants((node, pos) => {
|
|
30
|
+
doc.descendants((node, pos, parent) => {
|
|
27
31
|
if (!node.isTextblock) return;
|
|
28
32
|
const { text } = buildCleanBlockText(node, pos);
|
|
29
33
|
const normalizedText = normalizeFolioAIBlockText(text);
|
|
30
|
-
if (normalizedText.length === 0)
|
|
34
|
+
if (normalizedText.length === 0) {
|
|
35
|
+
if (parent?.type !== doc.type) return;
|
|
36
|
+
emptyAnchorState.textblockCount++;
|
|
37
|
+
if (emptyAnchorState.candidate === null) {
|
|
38
|
+
const paraIdAttr = node.attrs["paraId"];
|
|
39
|
+
emptyAnchorState.candidate = {
|
|
40
|
+
from: pos,
|
|
41
|
+
to: pos + node.nodeSize,
|
|
42
|
+
paraId: typeof paraIdAttr === "string" && paraIdAttr.length > 0 ? paraIdAttr : null
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
31
47
|
const textHash = hashFolioAIBlockText(normalizedText);
|
|
32
48
|
hashCounts.set(textHash, (hashCounts.get(textHash) ?? 0) + 1);
|
|
33
49
|
blockIndex++;
|
|
@@ -38,7 +54,8 @@ const createFolioAIEditSnapshot = (doc) => {
|
|
|
38
54
|
taken: usedBlockIds
|
|
39
55
|
});
|
|
40
56
|
usedBlockIds.add(id);
|
|
41
|
-
const
|
|
57
|
+
const headingLevel = getHeadingLevel(node);
|
|
58
|
+
const kind = getBlockKind(node, headingLevel);
|
|
42
59
|
const displayLabel = getDisplayLabel(node);
|
|
43
60
|
const styleId = getStyleId(node);
|
|
44
61
|
const previewRuns = getPreviewRuns(node);
|
|
@@ -47,6 +64,7 @@ const createFolioAIEditSnapshot = (doc) => {
|
|
|
47
64
|
id,
|
|
48
65
|
kind,
|
|
49
66
|
text,
|
|
67
|
+
...headingLevel !== void 0 && { headingLevel },
|
|
50
68
|
...displayLabel !== void 0 && { displayLabel },
|
|
51
69
|
...styleId !== void 0 && { styleId },
|
|
52
70
|
...previewRuns !== void 0 && { previewRuns }
|
|
@@ -70,19 +88,47 @@ const createFolioAIEditSnapshot = (doc) => {
|
|
|
70
88
|
hashOccurrenceCount: hashCounts.get(draft.anchor.textHash) ?? 0
|
|
71
89
|
};
|
|
72
90
|
}
|
|
73
|
-
|
|
91
|
+
const emptyAnchorCandidate = emptyAnchorState.candidate;
|
|
92
|
+
if (blocks.length > 0 || emptyAnchorCandidate === null) return {
|
|
74
93
|
blocks,
|
|
75
94
|
anchors
|
|
76
95
|
};
|
|
96
|
+
const emptyDocumentAnchorId = deriveBlockId({
|
|
97
|
+
paraId: emptyAnchorCandidate.paraId,
|
|
98
|
+
index: 1,
|
|
99
|
+
taken: usedBlockIds
|
|
100
|
+
});
|
|
101
|
+
const normalizedText = "";
|
|
102
|
+
anchors[emptyDocumentAnchorId] = {
|
|
103
|
+
id: emptyDocumentAnchorId,
|
|
104
|
+
from: emptyAnchorCandidate.from,
|
|
105
|
+
to: emptyAnchorCandidate.to,
|
|
106
|
+
text: "",
|
|
107
|
+
normalizedText,
|
|
108
|
+
textHash: hashFolioAIBlockText(normalizedText),
|
|
109
|
+
hashOccurrenceCount: emptyAnchorState.textblockCount
|
|
110
|
+
};
|
|
111
|
+
return {
|
|
112
|
+
blocks,
|
|
113
|
+
anchors,
|
|
114
|
+
emptyDocumentAnchorId
|
|
115
|
+
};
|
|
77
116
|
};
|
|
78
|
-
const getBlockKind = (node) => {
|
|
117
|
+
const getBlockKind = (node, headingLevel) => {
|
|
79
118
|
const listMarker = node.attrs["listMarker"];
|
|
80
119
|
const numPr = node.attrs["numPr"];
|
|
81
120
|
if (typeof listMarker === "string" && listMarker.trim().length > 0 || numPr !== void 0 && numPr !== null) return "listItem";
|
|
82
|
-
|
|
83
|
-
if (typeof outlineLevel === "number" && outlineLevel >= 0) return "heading";
|
|
121
|
+
if (headingLevel !== void 0) return "heading";
|
|
84
122
|
return "paragraph";
|
|
85
123
|
};
|
|
124
|
+
const getHeadingLevel = (node) => {
|
|
125
|
+
const outlineLevel = node.attrs["outlineLevel"];
|
|
126
|
+
if (typeof outlineLevel === "number" && Number.isInteger(outlineLevel) && outlineLevel >= 0 && outlineLevel <= 8) return outlineLevel + 1;
|
|
127
|
+
const styleId = node.attrs["styleId"];
|
|
128
|
+
if (typeof styleId !== "string") return;
|
|
129
|
+
const level = /^heading(?<level>[1-9])$/iu.exec(styleId)?.groups?.["level"];
|
|
130
|
+
return level === void 0 ? void 0 : Number.parseInt(level, 10);
|
|
131
|
+
};
|
|
86
132
|
const getDisplayLabel = (node) => {
|
|
87
133
|
const listMarker = node.attrs["listMarker"];
|
|
88
134
|
if (typeof listMarker === "string" && listMarker.trim().length > 0) return listMarker.trim();
|
package/dist/ai-edits/types.d.ts
CHANGED
|
@@ -13,14 +13,16 @@ type FolioAIBlockPreviewRun = {
|
|
|
13
13
|
type FolioAIBlock = {
|
|
14
14
|
id: string;
|
|
15
15
|
kind: FolioAIBlockKind;
|
|
16
|
-
text: string;
|
|
16
|
+
text: string; /** One-based heading depth when the block has outline semantics. */
|
|
17
|
+
headingLevel?: number;
|
|
17
18
|
displayLabel?: string;
|
|
18
19
|
styleId?: string;
|
|
19
20
|
previewRuns?: FolioAIBlockPreviewRun[];
|
|
20
21
|
};
|
|
21
22
|
type FolioAIEditSnapshot = {
|
|
22
23
|
blocks: FolioAIBlock[];
|
|
23
|
-
anchors: Record<string, FolioAIBlockAnchor>;
|
|
24
|
+
anchors: Record<string, FolioAIBlockAnchor>; /** Hidden empty paragraph used to anchor insertions when `blocks` is empty. */
|
|
25
|
+
emptyDocumentAnchorId?: string;
|
|
24
26
|
};
|
|
25
27
|
type FolioAIBlockAnchor = {
|
|
26
28
|
id: string;
|
|
@@ -61,6 +63,47 @@ type FolioAITextRangeHandle = {
|
|
|
61
63
|
endOffset: number;
|
|
62
64
|
selectedTextHash: string;
|
|
63
65
|
};
|
|
66
|
+
/**
|
|
67
|
+
* Stable handle for the logical document section introduced by one heading.
|
|
68
|
+
* The section runs until the next heading at the same or a higher level.
|
|
69
|
+
* `headingTextHash` makes a renamed heading fail stale instead of silently
|
|
70
|
+
* resolving to content whose meaning may have changed.
|
|
71
|
+
*/
|
|
72
|
+
type FolioDocumentSectionHandle = {
|
|
73
|
+
type: "headingSection";
|
|
74
|
+
story: "main";
|
|
75
|
+
headingBlockId: string;
|
|
76
|
+
headingTextHash: string; /** One-based depth used to detect structural section-boundary changes. */
|
|
77
|
+
headingLevel: number;
|
|
78
|
+
};
|
|
79
|
+
type FolioDocumentOutlineEntry = {
|
|
80
|
+
handle: FolioDocumentSectionHandle;
|
|
81
|
+
headingBlockId: string;
|
|
82
|
+
text: string; /** One-based heading depth. */
|
|
83
|
+
level: number;
|
|
84
|
+
parentHandle?: FolioDocumentSectionHandle;
|
|
85
|
+
};
|
|
86
|
+
type FolioDocumentOutline = {
|
|
87
|
+
sections: FolioDocumentOutlineEntry[];
|
|
88
|
+
};
|
|
89
|
+
type FolioDocumentSection = {
|
|
90
|
+
handle: FolioDocumentSectionHandle;
|
|
91
|
+
heading: FolioDocumentOutlineEntry; /** Heading block followed by every block in its logical section. */
|
|
92
|
+
blocks: FolioAIBlock[];
|
|
93
|
+
};
|
|
94
|
+
type FolioDocumentSectionReadResult = {
|
|
95
|
+
status: "found";
|
|
96
|
+
section: FolioDocumentSection;
|
|
97
|
+
} | {
|
|
98
|
+
status: "missing";
|
|
99
|
+
} | {
|
|
100
|
+
status: "stale";
|
|
101
|
+
};
|
|
102
|
+
type FolioDocumentNavigationTarget = {
|
|
103
|
+
type: "block";
|
|
104
|
+
story: "main";
|
|
105
|
+
blockId: string;
|
|
106
|
+
} | FolioAITextRangeHandle;
|
|
64
107
|
type FolioAIInlineFormatting = {
|
|
65
108
|
bold?: boolean;
|
|
66
109
|
italic?: boolean;
|
|
@@ -192,4 +235,4 @@ type FolioAIEditApplyResult = {
|
|
|
192
235
|
skipped: FolioAIEditSkippedOperation[];
|
|
193
236
|
};
|
|
194
237
|
//#endregion
|
|
195
|
-
export { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAIInlineFormatting, FolioAISignatureParty, FolioAITextRangeHandle };
|
|
238
|
+
export { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAIInlineFormatting, FolioAISignatureParty, FolioAITextRangeHandle, FolioDocumentNavigationTarget, FolioDocumentOutline, FolioDocumentOutlineEntry, FolioDocumentSection, FolioDocumentSectionHandle, FolioDocumentSectionReadResult };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAISignatureParty } from "../ai-edits/types.js";
|
|
2
2
|
import { applyFolioAIEditOperations } from "../ai-edits/apply.js";
|
|
3
3
|
import { document_d_exports } from "../types/document.js";
|
|
4
|
-
import { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationStatus, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "../document-operations.js";
|
|
4
|
+
import { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "../document-operations.js";
|
|
5
5
|
import { createFolioAIEditSnapshot, hashFolioAIBlockText, normalizeFolioAIBlockText } from "../ai-edits/snapshot.js";
|
|
6
6
|
import { DeriveBlockIdInput, FolioBlockId, deriveBlockId, getFolioParaIdFromBlockId, isFolioBlockId, isSequentialFolioBlockId } from "../types/block-id.js";
|
|
7
7
|
import { WordDiffSegment, diffWordSegments } from "../ai-edits/word-diff.js";
|
|
@@ -9,9 +9,12 @@ import { AIBarStatus, AIChatMode, AICitation, AICitationSource, AIGenerateInput,
|
|
|
9
9
|
import { ApplyResult, applySuggestions } from "../ai-suggestions/apply.js";
|
|
10
10
|
import { ResolvedAnchor, isSuggestionStale, resolveSuggestionAnchor } from "../ai-suggestions/conflict.js";
|
|
11
11
|
import { PositionalText, buildPositionalText } from "../ai-suggestions/text-positions.js";
|
|
12
|
+
import { DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DocumentPreset, DocumentStyleSet } from "../style-sets/types.js";
|
|
12
13
|
import { CreateEmptyDocumentOptions, createEmptyDocument } from "../utils/createDocument.js";
|
|
14
|
+
import { DocumentStyleCatalog, DocumentStyleCatalogEntry, ExtractDocumentStyleSetOptions, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, inspectDocumentStyles, inspectDocumentStylesFromDocx } from "../style-sets/extract.js";
|
|
15
|
+
import { STELLA_STYLE_SET_NAME, createStellaStyleDocumentPreset, createStellaStyleSet } from "../style-sets/stellaStyle.js";
|
|
13
16
|
import { createDocx } from "../docx/rezip.js";
|
|
14
|
-
import { DocxCompatibility } from "../docx/compatibility.js";
|
|
17
|
+
import { DocxCompatibility, DocxCompatibilityContext, DocxCompatibilityIssue, DocxCompatibilityLocation, DocxCompatibilityPart, FolioDocxCompatibilityHost, FolioDocxCompatibilityProfile, InspectDocxCompatibilityOptions, inspectDocxCompatibility } from "../docx/compatibility.js";
|
|
15
18
|
import { setAISuggestionsMeta, setFocusedSuggestionMeta } from "../prosemirror/plugins/aiSuggestionDecorations.js";
|
|
16
19
|
import { scrollFolioPositionIntoView } from "../paged-layout/scrollToPmPosition.js";
|
|
17
20
|
import { getFolioCaretViewportRect, getFolioSelectionViewportRect } from "../paged-layout/selectionViewportRect.js";
|
|
@@ -26,5 +29,7 @@ import { fromMarkdown } from "../markdown/fromMarkdown.js";
|
|
|
26
29
|
import { toMarkdown, toMarkdownResult } from "../markdown/index.js";
|
|
27
30
|
import { EmbeddedFont, EmbeddedFontParts, extractEmbeddedFonts, getEmbeddedFontFaces } from "../fonts/embeddedFonts.js";
|
|
28
31
|
import { getGoogleFontsEnabled, setGoogleFontsEnabled } from "../utils/fontResolver.js";
|
|
32
|
+
import { DOCX_CONFORMANCE_CLASSES } from "../index.js";
|
|
29
33
|
type Document = document_d_exports.Document;
|
|
30
|
-
|
|
34
|
+
type DocxConformanceClass = document_d_exports.DocxConformanceClass;
|
|
35
|
+
export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyResult, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAISignatureParty, type FolioBlockId, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidFolioDocumentOperationBatchError, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
package/dist/compat/eigenpal.js
CHANGED
|
@@ -3,14 +3,18 @@ import { createFolioAIEditSnapshot, hashFolioAIBlockText, normalizeFolioAIBlockT
|
|
|
3
3
|
import { diffWordSegments } from "../ai-edits/word-diff.js";
|
|
4
4
|
import { applyFolioAIEditOperations } from "../ai-edits/apply.js";
|
|
5
5
|
import { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "../document-operations.js";
|
|
6
|
+
import { DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION } from "../style-sets/types.js";
|
|
6
7
|
import { createEmptyDocument } from "../utils/createDocument.js";
|
|
8
|
+
import { extractDocumentStyleSet, extractDocumentStyleSetFromDocx, inspectDocumentStyles, inspectDocumentStylesFromDocx } from "../style-sets/extract.js";
|
|
9
|
+
import { STELLA_STYLE_SET_NAME, createStellaStyleDocumentPreset, createStellaStyleSet } from "../style-sets/stellaStyle.js";
|
|
7
10
|
import { createDocx } from "../docx/rezip.js";
|
|
11
|
+
import { inspectDocxCompatibility } from "../docx/compatibility.js";
|
|
8
12
|
import { DEFAULT_AI_SUGGESTION_PRESETS } from "../ai-suggestions/types.js";
|
|
9
13
|
import { buildPositionalText } from "../ai-suggestions/text-positions.js";
|
|
10
14
|
import { isSuggestionStale, resolveSuggestionAnchor } from "../ai-suggestions/conflict.js";
|
|
11
15
|
import { applySuggestions } from "../ai-suggestions/apply.js";
|
|
12
|
-
import { setAISuggestionsMeta, setFocusedSuggestionMeta } from "../prosemirror/plugins/aiSuggestionDecorations.js";
|
|
13
16
|
import { getGoogleFontsEnabled, setGoogleFontsEnabled } from "../utils/fontResolver.js";
|
|
17
|
+
import { setAISuggestionsMeta, setFocusedSuggestionMeta } from "../prosemirror/plugins/aiSuggestionDecorations.js";
|
|
14
18
|
import { scrollFolioPositionIntoView } from "../paged-layout/scrollToPmPosition.js";
|
|
15
19
|
import { getFolioCaretViewportRect, getFolioSelectionViewportRect } from "../paged-layout/selectionViewportRect.js";
|
|
16
20
|
import { createAICitationDecorationsPlugin, setAICitationsMeta, setActiveCitationMeta } from "../prosemirror/plugins/aiCitationDecorations.js";
|
|
@@ -22,4 +26,5 @@ import { DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, acceptAutocompleteSuggestion, acc
|
|
|
22
26
|
import { fromMarkdown } from "../markdown/fromMarkdown.js";
|
|
23
27
|
import { toMarkdown, toMarkdownResult } from "../markdown/index.js";
|
|
24
28
|
import { extractEmbeddedFonts, getEmbeddedFontFaces } from "../fonts/embeddedFonts.js";
|
|
25
|
-
|
|
29
|
+
import { DOCX_CONFORMANCE_CLASSES } from "../index.js";
|
|
30
|
+
export { DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, InvalidFolioDocumentOperationBatchError, STELLA_STYLE_SET_NAME, UnsupportedFolioDocumentOperationVersionError, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
import { EditorState } from "prosemirror-state";
|
|
3
|
+
|
|
4
|
+
//#region src/controller/fontReadiness.d.ts
|
|
5
|
+
declare function getDocumentFontSet(): FontFaceSet | null;
|
|
6
|
+
declare function documentFontsAreLoaded(): boolean;
|
|
7
|
+
declare const LAYOUT_FONT_DESCRIPTORS: readonly [{
|
|
8
|
+
readonly style: "normal";
|
|
9
|
+
readonly weight: 400;
|
|
10
|
+
}, {
|
|
11
|
+
readonly style: "italic";
|
|
12
|
+
readonly weight: 400;
|
|
13
|
+
}, {
|
|
14
|
+
readonly style: "normal";
|
|
15
|
+
readonly weight: 700;
|
|
16
|
+
}, {
|
|
17
|
+
readonly style: "italic";
|
|
18
|
+
readonly weight: 700;
|
|
19
|
+
}];
|
|
20
|
+
type LayoutFontFace = {
|
|
21
|
+
family: string;
|
|
22
|
+
style: (typeof LAYOUT_FONT_DESCRIPTORS)[number]["style"];
|
|
23
|
+
weight: (typeof LAYOUT_FONT_DESCRIPTORS)[number]["weight"];
|
|
24
|
+
};
|
|
25
|
+
declare function waitForInitialLayoutFonts(documentModel: document_d_exports.Document | null, pmDoc: EditorState["doc"]): Promise<boolean>;
|
|
26
|
+
declare function collectInitialLayoutFontFamilies(documentModel: document_d_exports.Document | null, pmDoc: EditorState["doc"]): Set<string>;
|
|
27
|
+
declare function collectInitialLayoutFontFaces(documentModel: document_d_exports.Document | null, pmDoc: EditorState["doc"]): LayoutFontFace[];
|
|
28
|
+
//#endregion
|
|
29
|
+
export { LayoutFontFace, collectInitialLayoutFontFaces, collectInitialLayoutFontFamilies, documentFontsAreLoaded, getDocumentFontSet, waitForInitialLayoutFonts };
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { expectFontFamilyMarkAttrs } from "../prosemirror/attrs/index.js";
|
|
2
|
+
//#region src/controller/fontReadiness.ts
|
|
3
|
+
function getDocumentFontSet() {
|
|
4
|
+
if (typeof document === "undefined" || !("fonts" in document)) return null;
|
|
5
|
+
return document.fonts;
|
|
6
|
+
}
|
|
7
|
+
function documentFontsAreLoaded() {
|
|
8
|
+
const fontSet = getDocumentFontSet();
|
|
9
|
+
return !fontSet || fontSet.status === "loaded";
|
|
10
|
+
}
|
|
11
|
+
const INITIAL_LAYOUT_FONT_TIMEOUT_MS = 2e3;
|
|
12
|
+
const DEFAULT_LAYOUT_FONT_FAMILY = "Calibri";
|
|
13
|
+
const OFFICE_FONT_FAMILY_MAP = {
|
|
14
|
+
Arial: "Arimo",
|
|
15
|
+
Calibri: "Carlito",
|
|
16
|
+
Cambria: "Caladea",
|
|
17
|
+
"Times New Roman": "Tinos",
|
|
18
|
+
"Courier New": "Cousine"
|
|
19
|
+
};
|
|
20
|
+
const CSS_GENERIC_FONT_FAMILIES = /* @__PURE__ */ new Set([
|
|
21
|
+
"serif",
|
|
22
|
+
"sans-serif",
|
|
23
|
+
"monospace",
|
|
24
|
+
"cursive",
|
|
25
|
+
"fantasy",
|
|
26
|
+
"system-ui"
|
|
27
|
+
]);
|
|
28
|
+
const REGULAR_LAYOUT_FONT_DESCRIPTOR = [
|
|
29
|
+
{
|
|
30
|
+
style: "normal",
|
|
31
|
+
weight: 400
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
style: "italic",
|
|
35
|
+
weight: 400
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
style: "normal",
|
|
39
|
+
weight: 700
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
style: "italic",
|
|
43
|
+
weight: 700
|
|
44
|
+
}
|
|
45
|
+
][0];
|
|
46
|
+
function waitForInitialLayoutFonts(documentModel, pmDoc) {
|
|
47
|
+
const fontSet = getDocumentFontSet();
|
|
48
|
+
if (!fontSet) return Promise.resolve(true);
|
|
49
|
+
const loadChecks = [];
|
|
50
|
+
for (const face of collectInitialLayoutFontFaces(documentModel, pmDoc)) loadChecks.push(`${face.style} ${face.weight} 16px "${escapeCssFontFamily(face.family)}"`);
|
|
51
|
+
const loadFonts = Promise.allSettled(loadChecks.map((check) => fontSet.load(check))).then(() => fontSet.ready).then(() => true);
|
|
52
|
+
return Promise.race([loadFonts, new Promise((resolve) => {
|
|
53
|
+
globalThis.setTimeout(() => resolve(false), INITIAL_LAYOUT_FONT_TIMEOUT_MS);
|
|
54
|
+
})]);
|
|
55
|
+
}
|
|
56
|
+
function collectInitialLayoutFontFamilies(documentModel, pmDoc) {
|
|
57
|
+
return new Set(collectInitialLayoutFontFaces(documentModel, pmDoc).map(({ family }) => family));
|
|
58
|
+
}
|
|
59
|
+
function collectInitialLayoutFontFaces(documentModel, pmDoc) {
|
|
60
|
+
const faces = /* @__PURE__ */ new Map();
|
|
61
|
+
addLayoutFontFamilyFace(faces, DEFAULT_LAYOUT_FONT_FAMILY, REGULAR_LAYOUT_FONT_DESCRIPTOR);
|
|
62
|
+
for (const family of documentModel?.requiredFonts ?? []) addLayoutFontFamilyFace(faces, family, REGULAR_LAYOUT_FONT_DESCRIPTOR);
|
|
63
|
+
addLayoutFontFamilyFace(faces, documentModel?.package.theme?.fontScheme?.majorFont?.latin, REGULAR_LAYOUT_FONT_DESCRIPTOR);
|
|
64
|
+
addLayoutFontFamilyFace(faces, documentModel?.package.theme?.fontScheme?.minorFont?.latin, REGULAR_LAYOUT_FONT_DESCRIPTOR);
|
|
65
|
+
addTextFormattingFontFaces(faces, documentModel?.package.styles?.docDefaults?.rPr);
|
|
66
|
+
for (const style of documentModel?.package.styles?.styles ?? []) addTextFormattingFontFaces(faces, style.rPr);
|
|
67
|
+
collectProseMirrorFontFaces(faces, pmDoc, void 0);
|
|
68
|
+
return Array.from(faces.values());
|
|
69
|
+
}
|
|
70
|
+
function addTextFormattingFontFaces(faces, formatting) {
|
|
71
|
+
addLayoutFontFamilyFace(faces, formatting?.fontFamily, layoutDescriptorFromFormatting(formatting));
|
|
72
|
+
}
|
|
73
|
+
function collectProseMirrorFontFaces(faces, node, inheritedTextFormatting) {
|
|
74
|
+
const paragraphDefaults = readParagraphDefaultTextFormatting(node);
|
|
75
|
+
const textFormatting = paragraphDefaults ?? inheritedTextFormatting;
|
|
76
|
+
if (paragraphDefaults) addTextFormattingFontFaces(faces, paragraphDefaults);
|
|
77
|
+
if (node.attrs["listMarkerFontFamily"]) addLayoutFontFamilyFace(faces, node.attrs["listMarkerFontFamily"], REGULAR_LAYOUT_FONT_DESCRIPTOR);
|
|
78
|
+
if (node.isText) {
|
|
79
|
+
const descriptor = layoutDescriptorFromFormattingAndMarks(textFormatting, node.marks);
|
|
80
|
+
addLayoutFontFamilyFace(faces, readFontFamilyMarkAttrs(node.marks) ?? textFormatting?.fontFamily ?? DEFAULT_LAYOUT_FONT_FAMILY, descriptor);
|
|
81
|
+
}
|
|
82
|
+
node.forEach((child) => {
|
|
83
|
+
collectProseMirrorFontFaces(faces, child, textFormatting);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function readParagraphDefaultTextFormatting(node) {
|
|
87
|
+
const value = node.attrs["defaultTextFormatting"];
|
|
88
|
+
if (!value || typeof value !== "object") return;
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
function readFontFamilyMarkAttrs(marks) {
|
|
92
|
+
for (const mark of marks) if (mark.type.name === "fontFamily") return expectFontFamilyMarkAttrs(mark);
|
|
93
|
+
}
|
|
94
|
+
function layoutDescriptorFromFormatting(formatting) {
|
|
95
|
+
return {
|
|
96
|
+
style: formatting?.italic ? "italic" : "normal",
|
|
97
|
+
weight: formatting?.bold ? 700 : 400
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function layoutDescriptorFromFormattingAndMarks(formatting, marks) {
|
|
101
|
+
let bold = formatting?.bold === true;
|
|
102
|
+
let italic = formatting?.italic === true;
|
|
103
|
+
for (const mark of marks) {
|
|
104
|
+
if (mark.type.name === "bold") bold = true;
|
|
105
|
+
if (mark.type.name === "italic") italic = true;
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
style: italic ? "italic" : "normal",
|
|
109
|
+
weight: bold ? 700 : 400
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function addLayoutFontFamilyFace(faces, value, descriptor) {
|
|
113
|
+
if (typeof value === "string") {
|
|
114
|
+
addLayoutFontFamilyNameFace(faces, value, descriptor);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (!value || typeof value !== "object") return;
|
|
118
|
+
const fontFamily = value;
|
|
119
|
+
addLayoutFontFamilyFace(faces, fontFamily.ascii, descriptor);
|
|
120
|
+
addLayoutFontFamilyFace(faces, fontFamily.hAnsi, descriptor);
|
|
121
|
+
}
|
|
122
|
+
function addLayoutFontFamilyNameFace(faces, family, descriptor) {
|
|
123
|
+
const normalized = family.trim();
|
|
124
|
+
if (!normalized || CSS_GENERIC_FONT_FAMILIES.has(normalized)) return;
|
|
125
|
+
addLayoutFontFace(faces, normalized, descriptor);
|
|
126
|
+
const mappedFamily = OFFICE_FONT_FAMILY_MAP[normalized];
|
|
127
|
+
if (mappedFamily) addLayoutFontFace(faces, mappedFamily, descriptor);
|
|
128
|
+
}
|
|
129
|
+
function addLayoutFontFace(faces, family, descriptor) {
|
|
130
|
+
faces.set(`${family}|${descriptor.style}|${descriptor.weight}`, {
|
|
131
|
+
family,
|
|
132
|
+
...descriptor
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
function escapeCssFontFamily(family) {
|
|
136
|
+
return family.replace(/\\/gu, "\\\\").replace(/"/gu, "\\\"");
|
|
137
|
+
}
|
|
138
|
+
//#endregion
|
|
139
|
+
export { collectInitialLayoutFontFaces, collectInitialLayoutFontFamilies, documentFontsAreLoaded, getDocumentFontSet, waitForInitialLayoutFonts };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/controller/latestRequestGate.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Coordinates async work where only the most recently started request may
|
|
4
|
+
* commit a result. Each guard closes over an opaque identity, so callers
|
|
5
|
+
* cannot accidentally make an older request current again.
|
|
6
|
+
*/
|
|
7
|
+
type LatestRequestGate = {
|
|
8
|
+
/** Start a request and return a guard that remains true while it is latest. */begin: () => () => boolean; /** Supersede the current request without starting another one. */
|
|
9
|
+
invalidate: () => void;
|
|
10
|
+
};
|
|
11
|
+
declare const createLatestRequestGate: () => LatestRequestGate;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { LatestRequestGate, createLatestRequestGate };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/controller/latestRequestGate.ts
|
|
2
|
+
const createLatestRequestGate = () => {
|
|
3
|
+
let current = Symbol();
|
|
4
|
+
return {
|
|
5
|
+
begin: () => {
|
|
6
|
+
const request = Symbol();
|
|
7
|
+
current = request;
|
|
8
|
+
return () => current === request;
|
|
9
|
+
},
|
|
10
|
+
invalidate: () => {
|
|
11
|
+
current = Symbol();
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
export { createLatestRequestGate };
|
|
@@ -19,15 +19,42 @@ import { tryBuildIncrementalMeasures } from "../paged-layout/incrementalMeasure.
|
|
|
19
19
|
import { computePerBlockMeasureInputs } from "../paged-layout/sectionBlockWidths.js";
|
|
20
20
|
import { getDocumentWatermark } from "../watermark/index.js";
|
|
21
21
|
//#region src/controller/layoutPipeline.ts
|
|
22
|
-
function
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
22
|
+
function bodyMarginsClearHeaderFooter({ authoredMargins, preparedHeader, preparedFooter }) {
|
|
23
|
+
const headerBottom = preparedHeader ? (authoredMargins.header ?? 0) + (preparedHeader.marginPushBottom ?? preparedHeader.height) : authoredMargins.top;
|
|
24
|
+
const footerClearance = preparedFooter ? (authoredMargins.footer ?? 0) + (preparedFooter.marginPushBottom ?? preparedFooter.height) : authoredMargins.bottom;
|
|
25
|
+
const top = Math.max(authoredMargins.top, headerBottom);
|
|
26
|
+
const bottom = Math.max(authoredMargins.bottom, footerClearance);
|
|
27
|
+
if (top === authoredMargins.top && bottom === authoredMargins.bottom) return authoredMargins;
|
|
26
28
|
return {
|
|
27
29
|
...authoredMargins,
|
|
28
|
-
top
|
|
30
|
+
top,
|
|
31
|
+
bottom
|
|
29
32
|
};
|
|
30
33
|
}
|
|
34
|
+
function bodyBlocksClearSectionHeaderFooter(blocks, { authoredMargins, sectionHeaderFooterRefs, headerContentByRId, footerContentByRId }) {
|
|
35
|
+
if (!sectionHeaderFooterRefs || !headerContentByRId && !footerContentByRId) return blocks;
|
|
36
|
+
let sectionIndex = 0;
|
|
37
|
+
let currentAuthoredMargins = authoredMargins;
|
|
38
|
+
let changed = false;
|
|
39
|
+
const nextBlocks = blocks.map((block) => {
|
|
40
|
+
if (block.kind !== "sectionBreak") return block;
|
|
41
|
+
currentAuthoredMargins = block.margins ?? currentAuthoredMargins;
|
|
42
|
+
const refs = sectionHeaderFooterRefs[sectionIndex];
|
|
43
|
+
sectionIndex += 1;
|
|
44
|
+
const effectiveMargins = bodyMarginsClearHeaderFooter({
|
|
45
|
+
authoredMargins: currentAuthoredMargins,
|
|
46
|
+
preparedHeader: refs?.headerDefault ? headerContentByRId?.get(refs.headerDefault) : void 0,
|
|
47
|
+
preparedFooter: refs?.footerDefault ? footerContentByRId?.get(refs.footerDefault) : void 0
|
|
48
|
+
});
|
|
49
|
+
if (effectiveMargins === currentAuthoredMargins && block.margins === currentAuthoredMargins) return block;
|
|
50
|
+
changed = true;
|
|
51
|
+
return {
|
|
52
|
+
...block,
|
|
53
|
+
margins: effectiveMargins
|
|
54
|
+
};
|
|
55
|
+
});
|
|
56
|
+
return changed ? nextBlocks : blocks;
|
|
57
|
+
}
|
|
31
58
|
function runLayoutPipeline(deps, state, options = {}) {
|
|
32
59
|
const { contentWidth, columns, pageSize, margins, pageGap, syncCoordinator, headerContent, footerContent, firstPageHeaderContent, firstPageFooterContent, headerContentRId, footerContentRId, firstPageHeaderContentRId, firstPageFooterContentRId, sectionHeaderFooterRefs, theme: _theme, sectionProperties, document, defaultTabStop, mirrorMargins, styles, layout, hfPMs, painter, pagesContainer, session, renderHfFromContentOrPm, renderHeaderFooterContentByRId, documentFontsAreLoaded, buildFootnoteRenderItems, describeInvalidHighlightMarks, emptyTemplatePreviewEntries: EMPTY_TEMPLATE_PREVIEW_ENTRIES } = deps;
|
|
33
60
|
let outcome = {};
|
|
@@ -46,6 +73,13 @@ function runLayoutPipeline(deps, state, options = {}) {
|
|
|
46
73
|
const flowOpts = { pageContentHeight: pageSize.h - margins.top - margins.bottom };
|
|
47
74
|
if (_theme !== void 0) flowOpts.theme = _theme;
|
|
48
75
|
if (defaultTabStop !== void 0) flowOpts.defaultTabStopTwips = defaultTabStop;
|
|
76
|
+
if (document?.package.settings?.lineBreakRules) flowOpts.lineBreakRules = document.package.settings.lineBreakRules;
|
|
77
|
+
const documentSettings = document?.package.settings;
|
|
78
|
+
if (documentSettings?.autoHyphenation === true) flowOpts.automaticHyphenation = {
|
|
79
|
+
enabled: true,
|
|
80
|
+
...documentSettings.doNotHyphenateCaps !== void 0 ? { doNotHyphenateCaps: documentSettings.doNotHyphenateCaps } : {},
|
|
81
|
+
...documentSettings.consecutiveHyphenLimit !== void 0 ? { consecutiveLineLimit: documentSettings.consecutiveHyphenLimit } : {}
|
|
82
|
+
};
|
|
49
83
|
let newBlocks = toFlowBlocks(state.doc, flowOpts);
|
|
50
84
|
const previewState = templatePreviewValuesKey.getState(state);
|
|
51
85
|
const previewEntries = previewState?.entries ?? EMPTY_TEMPLATE_PREVIEW_ENTRIES;
|
|
@@ -90,7 +124,9 @@ function runLayoutPipeline(deps, state, options = {}) {
|
|
|
90
124
|
...styles ? { styles } : {},
|
|
91
125
|
..._theme !== void 0 ? { theme: _theme } : {},
|
|
92
126
|
measureBlocks: hfMeasureBlocks,
|
|
93
|
-
...defaultTabStop !== void 0 ? { defaultTabStopTwips: defaultTabStop } : {}
|
|
127
|
+
...defaultTabStop !== void 0 ? { defaultTabStopTwips: defaultTabStop } : {},
|
|
128
|
+
...flowOpts.lineBreakRules ? { lineBreakRules: flowOpts.lineBreakRules } : {},
|
|
129
|
+
...flowOpts.automaticHyphenation ? { automaticHyphenation: flowOpts.automaticHyphenation } : {}
|
|
94
130
|
};
|
|
95
131
|
};
|
|
96
132
|
const hfOptions = buildHfOptions(hfPageCountEstimate);
|
|
@@ -101,7 +137,28 @@ function runLayoutPipeline(deps, state, options = {}) {
|
|
|
101
137
|
let firstPageFooterForRender = hasTitlePg ? renderHfFromContentOrPm(firstPageFooterContent, firstPageFooterContentRId, hfPMs, contentWidth, hfMetricsFooter, hfOptions) : void 0;
|
|
102
138
|
let headerContentByRId = renderHeaderFooterContentByRId(document?.package.headers, hfPMs, contentWidth, hfMetricsHeader, hfOptions);
|
|
103
139
|
let footerContentByRId = renderHeaderFooterContentByRId(document?.package.footers, hfPMs, contentWidth, hfMetricsFooter, hfOptions);
|
|
104
|
-
const
|
|
140
|
+
const sectionPropertiesForMargins = document?.package.document.sections?.map((section) => section.properties) ?? (sectionProperties ? [sectionProperties] : []);
|
|
141
|
+
const sectionEvenPageMargins = sectionHeaderFooterRefs?.map((refs, index) => {
|
|
142
|
+
if (refs.evenAndOddHeaders !== true) return;
|
|
143
|
+
const properties = sectionPropertiesForMargins[index];
|
|
144
|
+
return bodyMarginsClearHeaderFooter({
|
|
145
|
+
authoredMargins: properties ? getMargins(properties) : margins,
|
|
146
|
+
preparedHeader: refs.headerEven ? headerContentByRId?.get(refs.headerEven) : void 0,
|
|
147
|
+
preparedFooter: refs.footerEven ? footerContentByRId?.get(refs.footerEven) : void 0
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
newBlocks = bodyBlocksClearSectionHeaderFooter(newBlocks, {
|
|
151
|
+
authoredMargins: margins,
|
|
152
|
+
sectionHeaderFooterRefs,
|
|
153
|
+
headerContentByRId,
|
|
154
|
+
footerContentByRId
|
|
155
|
+
});
|
|
156
|
+
outcome.blocks = newBlocks;
|
|
157
|
+
const initialBodyMargins = bodyMarginsClearHeaderFooter({
|
|
158
|
+
authoredMargins: margins,
|
|
159
|
+
preparedHeader: headerContentForRender,
|
|
160
|
+
preparedFooter: footerContentForRender
|
|
161
|
+
});
|
|
105
162
|
recordPhaseDuration("header-footer", phaseStartedAt);
|
|
106
163
|
phaseStartedAt = performance.now();
|
|
107
164
|
const bodyLayoutConfig = {
|
|
@@ -114,9 +171,17 @@ function runLayoutPipeline(deps, state, options = {}) {
|
|
|
114
171
|
let finalHeaderForLayout = headerContentForRender;
|
|
115
172
|
if (finalHeaderRId) finalHeaderForLayout = headerContentByRId?.get(finalHeaderRId);
|
|
116
173
|
else if (sectionHeaderFooterRefs !== void 0) finalHeaderForLayout = void 0;
|
|
174
|
+
const finalFooterRId = sectionHeaderFooterRefs?.at(-1)?.footerDefault;
|
|
175
|
+
let finalFooterForLayout = footerContentForRender;
|
|
176
|
+
if (finalFooterRId) finalFooterForLayout = footerContentByRId?.get(finalFooterRId);
|
|
177
|
+
else if (sectionHeaderFooterRefs !== void 0) finalFooterForLayout = void 0;
|
|
117
178
|
const finalLayoutConfig = finalSectionProperties ? {
|
|
118
179
|
pageSize: getPageSize(finalSectionProperties),
|
|
119
|
-
margins:
|
|
180
|
+
margins: bodyMarginsClearHeaderFooter({
|
|
181
|
+
authoredMargins: getMargins(finalSectionProperties),
|
|
182
|
+
preparedHeader: finalHeaderForLayout,
|
|
183
|
+
preparedFooter: finalFooterForLayout
|
|
184
|
+
})
|
|
120
185
|
} : bodyLayoutConfig;
|
|
121
186
|
const finalColumns = getColumns(finalSectionProperties);
|
|
122
187
|
if (finalColumns !== void 0) finalLayoutConfig.columns = finalColumns;
|
|
@@ -137,7 +202,10 @@ function runLayoutPipeline(deps, state, options = {}) {
|
|
|
137
202
|
measureBlock: measureSingleBlockWithoutFloatingZones
|
|
138
203
|
}) : null;
|
|
139
204
|
let newMeasures = incrementalResult?.measures ?? measureBlocks(newBlocks, blockWidths, blockMeasureInputs.marginTops, {
|
|
205
|
+
pageWidth: blockMeasureInputs.pageWidths,
|
|
140
206
|
pageHeight: blockMeasureInputs.pageHeights,
|
|
207
|
+
marginLeft: blockMeasureInputs.marginLefts,
|
|
208
|
+
marginRight: blockMeasureInputs.marginRights,
|
|
141
209
|
marginBottom: blockMeasureInputs.marginBottoms
|
|
142
210
|
});
|
|
143
211
|
pendingArtifacts = {
|
|
@@ -151,7 +219,7 @@ function runLayoutPipeline(deps, state, options = {}) {
|
|
|
151
219
|
let newLayout;
|
|
152
220
|
let pageFootnoteMap = /* @__PURE__ */ new Map();
|
|
153
221
|
let footnoteContentMap = /* @__PURE__ */ new Map();
|
|
154
|
-
const bodyBreakType =
|
|
222
|
+
const bodyBreakType = finalSectionProperties?.sectionStart;
|
|
155
223
|
const buildLayoutOpts = () => {
|
|
156
224
|
const nextLayoutOpts = {
|
|
157
225
|
pageSize,
|
|
@@ -159,7 +227,11 @@ function runLayoutPipeline(deps, state, options = {}) {
|
|
|
159
227
|
pageGap,
|
|
160
228
|
mirrorMargins
|
|
161
229
|
};
|
|
162
|
-
if (hasTitlePg) nextLayoutOpts.firstPageMargins =
|
|
230
|
+
if (hasTitlePg) nextLayoutOpts.firstPageMargins = bodyMarginsClearHeaderFooter({
|
|
231
|
+
authoredMargins: margins,
|
|
232
|
+
preparedHeader: firstPageHeaderForRender,
|
|
233
|
+
preparedFooter: firstPageFooterForRender
|
|
234
|
+
});
|
|
163
235
|
if (finalSectionProperties) {
|
|
164
236
|
nextLayoutOpts.finalPageSize = finalLayoutConfig.pageSize;
|
|
165
237
|
nextLayoutOpts.finalMargins = finalLayoutConfig.margins;
|
|
@@ -171,6 +243,7 @@ function runLayoutPipeline(deps, state, options = {}) {
|
|
|
171
243
|
if (columns !== void 0) nextLayoutOpts.columns = columns;
|
|
172
244
|
if (bodyBreakType !== void 0) nextLayoutOpts.bodyBreakType = bodyBreakType;
|
|
173
245
|
if (sectionHeaderFooterRefs !== void 0) nextLayoutOpts.sectionHeaderFooterRefs = sectionHeaderFooterRefs;
|
|
246
|
+
if (sectionEvenPageMargins !== void 0) nextLayoutOpts.sectionEvenPageMargins = sectionEvenPageMargins;
|
|
174
247
|
return nextLayoutOpts;
|
|
175
248
|
};
|
|
176
249
|
const layoutOpts = buildLayoutOpts();
|
|
@@ -181,6 +254,8 @@ function runLayoutPipeline(deps, state, options = {}) {
|
|
|
181
254
|
if (styles) footnoteOptions.styles = styles;
|
|
182
255
|
if (_theme !== void 0) footnoteOptions.theme = _theme;
|
|
183
256
|
if (defaultTabStop !== void 0) footnoteOptions.defaultTabStopTwips = defaultTabStop;
|
|
257
|
+
if (flowOpts.lineBreakRules) footnoteOptions.lineBreakRules = flowOpts.lineBreakRules;
|
|
258
|
+
if (flowOpts.automaticHyphenation) footnoteOptions.automaticHyphenation = flowOpts.automaticHyphenation;
|
|
184
259
|
return footnoteOptions;
|
|
185
260
|
})());
|
|
186
261
|
const footnoteHeightById = /* @__PURE__ */ new Map();
|
|
@@ -237,7 +312,10 @@ function runLayoutPipeline(deps, state, options = {}) {
|
|
|
237
312
|
previousFieldValues = values;
|
|
238
313
|
stabilizedFieldValues = values;
|
|
239
314
|
newMeasures = measureBlocks(newBlocks, blockWidths, blockMeasureInputs.marginTops, {
|
|
315
|
+
pageWidth: blockMeasureInputs.pageWidths,
|
|
240
316
|
pageHeight: blockMeasureInputs.pageHeights,
|
|
317
|
+
marginLeft: blockMeasureInputs.marginLefts,
|
|
318
|
+
marginRight: blockMeasureInputs.marginRights,
|
|
241
319
|
marginBottom: blockMeasureInputs.marginBottoms
|
|
242
320
|
}, values);
|
|
243
321
|
relayoutWithCurrentMeasures(layoutOptsUsed);
|