@stll/folio-core 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-edits/apply.d.ts +3 -9
- package/dist/ai-edits/apply.js +94 -14
- package/dist/ai-edits/blockRange.d.ts +33 -0
- package/dist/ai-edits/blockRange.js +58 -0
- package/dist/ai-edits/headless.d.ts +33 -4
- package/dist/ai-edits/headless.js +83 -15
- package/dist/ai-edits/index.d.ts +5 -3
- package/dist/ai-edits/index.js +3 -2
- package/dist/ai-edits/snapshot.d.ts +14 -2
- package/dist/ai-edits/snapshot.js +12 -1
- package/dist/ai-edits/types.d.ts +42 -3
- package/dist/compat/eigenpal.d.ts +3 -2
- package/dist/compat/eigenpal.js +6 -5
- package/dist/controller/layoutPipeline.d.ts +1 -0
- package/dist/controller/layoutPipeline.js +35 -137
- package/dist/controller/layoutScheduler.d.ts +2 -1
- package/dist/controller/layoutScheduler.js +6 -0
- package/dist/document-operations.d.ts +122 -0
- package/dist/document-operations.js +575 -0
- package/dist/docx/blockContentParser.js +17 -7
- package/dist/docx/encryption/agileDecryption.js +2 -1
- package/dist/docx/encryption/compoundFile.js +4 -2
- package/dist/docx/footnoteParser.d.ts +1 -17
- package/dist/docx/footnoteParser.js +1 -27
- package/dist/docx/groupDrawingParser.d.ts +8 -0
- package/dist/docx/groupDrawingParser.js +131 -0
- package/dist/docx/numberingParser.d.ts +3 -1
- package/dist/docx/numberingParser.js +8 -2
- package/dist/docx/paragraphParser.js +9 -3
- package/dist/docx/runParser.js +8 -1
- package/dist/docx/selectiveXmlPatch.js +4 -10
- package/dist/docx/serializer/numberingSerializer.js +3 -1
- package/dist/docx/settingsParser.d.ts +6 -3
- package/dist/docx/settingsParser.js +2 -0
- package/dist/docx/xmlParser.js +11 -4
- package/dist/index.d.ts +3 -2
- package/dist/index.js +6 -5
- package/dist/layout-bridge/convert/footnoteLayout.d.ts +37 -1
- package/dist/layout-bridge/convert/footnoteLayout.js +138 -14
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +5 -7
- package/dist/layout-bridge/convert/headerFooterLayout.js +5 -7
- package/dist/layout-bridge/convert/toFlowBlocks.js +56 -19
- package/dist/layout-engine/index.d.ts +6 -5
- package/dist/layout-engine/index.js +89 -26
- package/dist/layout-engine/keep-together.d.ts +13 -8
- package/dist/layout-engine/keep-together.js +40 -25
- package/dist/layout-engine/layoutInstrumentation.d.ts +11 -1
- package/dist/layout-engine/layoutInstrumentation.js +10 -1
- package/dist/layout-engine/measure/measureBlocks.js +28 -18
- package/dist/layout-engine/measure/measureParagraph.js +61 -15
- package/dist/layout-engine/paginator.d.ts +2 -1
- package/dist/layout-engine/paginator.js +9 -3
- package/dist/layout-engine/textBoxGroup.d.ts +7 -0
- package/dist/layout-engine/textBoxGroup.js +8 -0
- package/dist/layout-engine/types.d.ts +30 -9
- package/dist/layout-engine/types.js +20 -2
- package/dist/layout-painter/renderPage.d.ts +15 -1
- package/dist/layout-painter/renderPage.js +27 -11
- package/dist/layout-painter/renderParagraph.js +18 -8
- package/dist/layout-painter/renderTable.js +10 -7
- package/dist/managers/DocumentLoaderManager.js +12 -5
- package/dist/managers/TableSelectionManager.js +1 -1
- package/dist/model.js +1 -1
- package/dist/paged-layout/pageText.d.ts +14 -0
- package/dist/paged-layout/pageText.js +21 -0
- package/dist/prosemirror/attrs/index.js +2 -0
- package/dist/prosemirror/commands/comments.js +75 -5
- package/dist/prosemirror/commands/hyperlink.js +4 -2
- package/dist/prosemirror/commands/image.js +2 -1
- package/dist/prosemirror/commands/index.js +1 -1
- package/dist/prosemirror/commands/propertyChangeScope.d.ts +68 -0
- package/dist/prosemirror/commands/propertyChangeScope.js +242 -0
- package/dist/prosemirror/conversion/fromProseDoc.js +14 -3
- package/dist/prosemirror/conversion/toProseDoc.js +29 -8
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +2 -0
- package/dist/prosemirror/extensions/features/ListExtension.js +6 -0
- package/dist/prosemirror/extensions/nodes/TableExtension.js +10 -11
- package/dist/prosemirror/findReplaceSelection.js +2 -1
- package/dist/prosemirror/index.js +1 -1
- package/dist/prosemirror/insertOperations.js +1 -1
- package/dist/prosemirror/schema/nodes.d.ts +10 -5
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +1 -0
- package/dist/prosemirror/utils/tabCalculator.js +4 -2
- package/dist/redline.d.ts +20 -0
- package/dist/redline.js +127 -0
- package/dist/server.d.ts +7 -3
- package/dist/server.js +6 -2
- package/dist/symbols.d.ts +35 -0
- package/dist/symbols.js +512 -0
- package/dist/utils/clipboard.js +3 -3
- package/dist/utils/fontLoader.js +3 -0
- package/dist/utils/fontResolver.js +48 -1
- package/dist/utils/zoom.d.ts +21 -0
- package/dist/utils/zoom.js +21 -0
- package/dist/version-comparison.d.ts +92 -0
- package/dist/version-comparison.js +436 -0
- package/package.json +3 -3
- package/dist/paged-layout/headerFooterMargins.d.ts +0 -75
- package/dist/paged-layout/headerFooterMargins.js +0 -122
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stll/folio-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Headless, framework-neutral core of folio: the OOXML (.docx) parser, document model, ProseMirror integration, and page-layout engine. No React.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"document-model",
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"build": "rm -rf dist && tsdown",
|
|
102
102
|
"prepack": "bun run build",
|
|
103
103
|
"pack:dry-run": "bun pm pack --dry-run",
|
|
104
|
-
"typecheck": "
|
|
104
|
+
"typecheck": "bun ../../scripts/tsc-native.ts --noEmit -p tsconfig.build.json",
|
|
105
105
|
"test": "bun test src",
|
|
106
106
|
"test:property": "bun test $(grep -rlF 'fc.assert' src --include='*.test.ts')",
|
|
107
107
|
"perf": "bun scripts/profile-editor.ts"
|
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
"prosemirror-transform": "^1.12.0",
|
|
127
127
|
"prosemirror-view": "^1.41.8",
|
|
128
128
|
"utif2": "^4.1.0",
|
|
129
|
-
"valibot": "1.4.
|
|
129
|
+
"valibot": "1.4.2",
|
|
130
130
|
"y-prosemirror": "^1.3.7",
|
|
131
131
|
"yjs": "^13.6.31"
|
|
132
132
|
},
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { HeaderFooterContent, PageMargins, SectionBreakBlock } from "../layout-engine/types.js";
|
|
2
|
-
//#region src/paged-layout/headerFooterMargins.d.ts
|
|
3
|
-
type EffectiveHeaderFooterMarginsInput = {
|
|
4
|
-
margins: PageMargins;
|
|
5
|
-
headerContent?: HeaderFooterContent | undefined;
|
|
6
|
-
footerContent?: HeaderFooterContent | undefined;
|
|
7
|
-
firstPageHeaderContent?: HeaderFooterContent | undefined;
|
|
8
|
-
firstPageFooterContent?: HeaderFooterContent | undefined;
|
|
9
|
-
pageSize?: {
|
|
10
|
-
w: number;
|
|
11
|
-
h: number;
|
|
12
|
-
} | undefined;
|
|
13
|
-
warn?: ((message: string) => void) | undefined;
|
|
14
|
-
};
|
|
15
|
-
/**
|
|
16
|
-
* A function that extends a `PageMargins` to clear the HF overflow computed
|
|
17
|
-
* from a given set of header/footer content. Returned by
|
|
18
|
-
* `computeHeaderFooterMarginExtender` and applied at every margins site:
|
|
19
|
-
* the body fallback, `finalMargins`, and per-section `sectionBreak.margins`.
|
|
20
|
-
*
|
|
21
|
-
* Eigenpal #400 — pre-PR the extension only applied to the body fallback,
|
|
22
|
-
* so a section break carrying its own `sb.margins` from `<w:sectPr>`
|
|
23
|
-
* silently overrode the extension and the footer rendered on top of body
|
|
24
|
-
* text.
|
|
25
|
-
*/
|
|
26
|
-
type PageMarginsExtender = (margins: PageMargins) => PageMargins;
|
|
27
|
-
declare function computeHeaderFooterMarginExtender(input: Omit<EffectiveHeaderFooterMarginsInput, "margins">): PageMarginsExtender;
|
|
28
|
-
/**
|
|
29
|
-
* Like `computeHeaderFooterMarginExtender` but also accounts for the
|
|
30
|
-
* first-page header/footer content. Apply this only to the margins used
|
|
31
|
-
* for page 1 of a `<w:titlePg/>`-enabled section.
|
|
32
|
-
*/
|
|
33
|
-
declare function computeFirstPageHeaderFooterMarginExtender(input: Omit<EffectiveHeaderFooterMarginsInput, "margins">): PageMarginsExtender;
|
|
34
|
-
declare function computeEffectiveHeaderFooterMargins({
|
|
35
|
-
margins,
|
|
36
|
-
headerContent,
|
|
37
|
-
footerContent,
|
|
38
|
-
firstPageHeaderContent,
|
|
39
|
-
firstPageFooterContent,
|
|
40
|
-
pageSize,
|
|
41
|
-
warn
|
|
42
|
-
}: EffectiveHeaderFooterMarginsInput): PageMargins;
|
|
43
|
-
/** Rendered header/footer content shared by every extender on a page. */
|
|
44
|
-
type HeaderFooterExtenderContent = Omit<EffectiveHeaderFooterMarginsInput, "margins" | "pageSize" | "warn">;
|
|
45
|
-
type ExtendSectionBreakMarginsInput = {
|
|
46
|
-
content: HeaderFooterExtenderContent;
|
|
47
|
-
sectionContent?: HeaderFooterExtenderContent[] | undefined; /** Body page size and effective margins — the inheritance seed. */
|
|
48
|
-
bodyPageSize: {
|
|
49
|
-
w: number;
|
|
50
|
-
h: number;
|
|
51
|
-
};
|
|
52
|
-
bodyMargins: PageMargins;
|
|
53
|
-
warn?: ((message: string) => void) | undefined;
|
|
54
|
-
};
|
|
55
|
-
/**
|
|
56
|
-
* Extend every section break's margins to clear the same header/footer
|
|
57
|
-
* overflow the body margins do (eigenpal #400), so an overflowing footer
|
|
58
|
-
* never re-overlaps body text on a later section.
|
|
59
|
-
*
|
|
60
|
-
* The walk mirrors `collectSectionConfigs`: a break that omits its own
|
|
61
|
-
* `pageSize` or `margins` inherits the previous section's. Each break's
|
|
62
|
-
* authored-or-inherited margins are extended against the section's *own*
|
|
63
|
-
* resolved page height, so a taller page never keeps a smaller page's
|
|
64
|
-
* clamped reservation (and vice versa). Materializes `margins` on every
|
|
65
|
-
* non-inheriting break in place.
|
|
66
|
-
*/
|
|
67
|
-
declare function extendSectionBreakMargins(sectionBreaks: SectionBreakBlock[], {
|
|
68
|
-
content,
|
|
69
|
-
sectionContent,
|
|
70
|
-
bodyPageSize,
|
|
71
|
-
bodyMargins,
|
|
72
|
-
warn
|
|
73
|
-
}: ExtendSectionBreakMarginsInput): void;
|
|
74
|
-
//#endregion
|
|
75
|
-
export { HeaderFooterExtenderContent, PageMarginsExtender, computeEffectiveHeaderFooterMargins, computeFirstPageHeaderFooterMarginExtender, computeHeaderFooterMarginExtender, extendSectionBreakMargins };
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
//#region src/paged-layout/headerFooterMargins.ts
|
|
2
|
-
/**
|
|
3
|
-
* Floor on the body content area, in pixels. Header/footer overflow can
|
|
4
|
-
* never shrink the content band below this, so a degenerate document
|
|
5
|
-
* (a header taller than the page) still renders some body text.
|
|
6
|
-
*/
|
|
7
|
-
const MIN_CONTENT_HEIGHT_PX = 24;
|
|
8
|
-
function headerHeight(content) {
|
|
9
|
-
if (!content) return 0;
|
|
10
|
-
return content.marginPushBottom ?? content.visualBottom ?? content.height;
|
|
11
|
-
}
|
|
12
|
-
function footerHeight(content) {
|
|
13
|
-
if (!content) return 0;
|
|
14
|
-
const bottom = content.marginPushBottom ?? content.visualBottom ?? content.height;
|
|
15
|
-
const top = content.marginPushTop ?? content.visualTop ?? 0;
|
|
16
|
-
return Math.max(bottom - top, content.height);
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Build a function that, applied to any `PageMargins`, extends `top`/`bottom`
|
|
20
|
-
* to clear the same header/footer content the body's effective margins do.
|
|
21
|
-
* Returns the identity function when no extension is needed.
|
|
22
|
-
*
|
|
23
|
-
* Header/footer distances are taken from the *given* margins (the source
|
|
24
|
-
* paragraph's section margins), not the body's, so each section's authored
|
|
25
|
-
* `w:header`/`w:footer` distances are honored.
|
|
26
|
-
*/
|
|
27
|
-
/**
|
|
28
|
-
* Build an extender that pushes body margins clear of HF content.
|
|
29
|
-
*
|
|
30
|
-
* `mode === "default"` ignores `firstPageHeaderContent` /
|
|
31
|
-
* `firstPageFooterContent`. The first-page H/F only renders on page 1 of
|
|
32
|
-
* a `<w:titlePg/>`-enabled section, so margins for pages 2+ within the
|
|
33
|
-
* same section must NOT be extended for first-page overflow — extending
|
|
34
|
-
* them would push body content down on every page even though only page
|
|
35
|
-
* 1 actually carries the overflowing header. This produced visible
|
|
36
|
-
* regressions on NVCA-style first-page-header docs, where pages 2+
|
|
37
|
-
* inherited page 1's title-page header reservation.
|
|
38
|
-
*
|
|
39
|
-
* `mode === "firstPage"` uses the larger of the default and first-page
|
|
40
|
-
* H/F heights — applied only to the first-page margins of a titlePg
|
|
41
|
-
* section.
|
|
42
|
-
*/
|
|
43
|
-
function buildExtender({ headerContent, footerContent, firstPageHeaderContent, firstPageFooterContent, pageSize, warn, mode }) {
|
|
44
|
-
const headerContentHeight = mode === "firstPage" ? Math.max(headerHeight(headerContent), headerHeight(firstPageHeaderContent)) : headerHeight(headerContent);
|
|
45
|
-
const footerContentHeight = mode === "firstPage" ? Math.max(footerHeight(footerContent), footerHeight(firstPageFooterContent)) : footerHeight(footerContent);
|
|
46
|
-
return (margins) => {
|
|
47
|
-
const headerDistance = margins.header ?? 48;
|
|
48
|
-
const footerDistance = margins.footer ?? 48;
|
|
49
|
-
const availableHeaderSpace = margins.top - headerDistance;
|
|
50
|
-
const availableFooterSpace = margins.bottom - footerDistance;
|
|
51
|
-
const maxMargins = pageSize ? Math.max(0, pageSize.h - MIN_CONTENT_HEIGHT_PX) : void 0;
|
|
52
|
-
const fitsContent = headerContentHeight <= availableHeaderSpace && footerContentHeight <= availableFooterSpace;
|
|
53
|
-
const fitsPage = maxMargins === void 0 || margins.top + margins.bottom <= maxMargins;
|
|
54
|
-
if (fitsContent && fitsPage) return margins;
|
|
55
|
-
const out = { ...margins };
|
|
56
|
-
if (headerContentHeight > availableHeaderSpace) out.top = Math.max(margins.top, headerDistance + headerContentHeight);
|
|
57
|
-
if (footerContentHeight > availableFooterSpace) out.bottom = Math.max(margins.bottom, footerDistance + footerContentHeight);
|
|
58
|
-
if (pageSize && maxMargins !== void 0 && out.top + out.bottom > maxMargins) {
|
|
59
|
-
if (warn) warn(`header/footer content exceeds page height; clamping margins to preserve a content area. pageHeight=${Math.round(pageSize.h)} top=${Math.round(out.top)} bottom=${Math.round(out.bottom)}`);
|
|
60
|
-
out.bottom = Math.max(0, Math.min(out.bottom, maxMargins - out.top));
|
|
61
|
-
if (out.top + out.bottom > maxMargins) out.top = Math.max(0, maxMargins - out.bottom);
|
|
62
|
-
}
|
|
63
|
-
return out;
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
function computeHeaderFooterMarginExtender(input) {
|
|
67
|
-
return buildExtender({
|
|
68
|
-
...input,
|
|
69
|
-
mode: "default"
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Like `computeHeaderFooterMarginExtender` but also accounts for the
|
|
74
|
-
* first-page header/footer content. Apply this only to the margins used
|
|
75
|
-
* for page 1 of a `<w:titlePg/>`-enabled section.
|
|
76
|
-
*/
|
|
77
|
-
function computeFirstPageHeaderFooterMarginExtender(input) {
|
|
78
|
-
return buildExtender({
|
|
79
|
-
...input,
|
|
80
|
-
mode: "firstPage"
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
function computeEffectiveHeaderFooterMargins({ margins, headerContent, footerContent, firstPageHeaderContent, firstPageFooterContent, pageSize, warn }) {
|
|
84
|
-
return computeHeaderFooterMarginExtender({
|
|
85
|
-
headerContent,
|
|
86
|
-
footerContent,
|
|
87
|
-
firstPageHeaderContent,
|
|
88
|
-
firstPageFooterContent,
|
|
89
|
-
pageSize,
|
|
90
|
-
warn
|
|
91
|
-
})(margins);
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Extend every section break's margins to clear the same header/footer
|
|
95
|
-
* overflow the body margins do (eigenpal #400), so an overflowing footer
|
|
96
|
-
* never re-overlaps body text on a later section.
|
|
97
|
-
*
|
|
98
|
-
* The walk mirrors `collectSectionConfigs`: a break that omits its own
|
|
99
|
-
* `pageSize` or `margins` inherits the previous section's. Each break's
|
|
100
|
-
* authored-or-inherited margins are extended against the section's *own*
|
|
101
|
-
* resolved page height, so a taller page never keeps a smaller page's
|
|
102
|
-
* clamped reservation (and vice versa). Materializes `margins` on every
|
|
103
|
-
* non-inheriting break in place.
|
|
104
|
-
*/
|
|
105
|
-
function extendSectionBreakMargins(sectionBreaks, { content, sectionContent, bodyPageSize, bodyMargins, warn }) {
|
|
106
|
-
let pageSize = bodyPageSize;
|
|
107
|
-
let margins = bodyMargins;
|
|
108
|
-
for (let index = 0; index < sectionBreaks.length; index++) {
|
|
109
|
-
const sb = sectionBreaks[index];
|
|
110
|
-
if (!sb) continue;
|
|
111
|
-
if (!sb.pageSize && !sb.margins) continue;
|
|
112
|
-
pageSize = sb.pageSize ?? pageSize;
|
|
113
|
-
margins = computeHeaderFooterMarginExtender({
|
|
114
|
-
...sectionContent?.[index + 1] ?? content,
|
|
115
|
-
pageSize,
|
|
116
|
-
warn
|
|
117
|
-
})(sb.margins ?? margins);
|
|
118
|
-
sb.margins = margins;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
//#endregion
|
|
122
|
-
export { computeEffectiveHeaderFooterMargins, computeFirstPageHeaderFooterMarginExtender, computeHeaderFooterMarginExtender, extendSectionBreakMargins };
|