@ai-matrx/office 0.0.0 → 0.2.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/CHANGELOG.md +21 -0
- package/README.md +27 -1
- package/dist/core-page-setup-apply.cjs +121 -0
- package/dist/core-page-setup-apply.cjs.map +1 -0
- package/dist/core-page-setup-apply.d.cts +21 -0
- package/dist/core-page-setup-apply.d.ts +21 -0
- package/dist/core-page-setup-apply.js +100 -0
- package/dist/core-page-setup-apply.js.map +1 -0
- package/dist/core.cjs +487 -0
- package/dist/core.cjs.map +1 -0
- package/dist/core.d.cts +397 -0
- package/dist/core.d.ts +397 -0
- package/dist/core.js +454 -0
- package/dist/core.js.map +1 -0
- package/dist/document-page-style-BFLrgdLI.d.cts +109 -0
- package/dist/document-page-style-BFLrgdLI.d.ts +109 -0
- package/dist/univer-history.cjs +61 -0
- package/dist/univer-history.cjs.map +1 -0
- package/dist/univer-history.d.cts +32 -0
- package/dist/univer-history.d.ts +32 -0
- package/dist/univer-history.js +40 -0
- package/dist/univer-history.js.map +1 -0
- package/dist/univer.cjs +333 -0
- package/dist/univer.cjs.map +1 -0
- package/dist/univer.d.cts +320 -0
- package/dist/univer.d.ts +320 -0
- package/dist/univer.js +317 -0
- package/dist/univer.js.map +1 -0
- package/package.json +130 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
W1-G2a1. The Univer glue shared by Sheets and Docs moves in from matrx-frontend `lib/univer`.
|
|
6
|
+
|
|
7
|
+
- New `./univer` entry (client; loads `@univerjs/*`): `disposeUniverInstance`, `identifyUniverUser`, `isSnapshotMutation` / `isWorkbookSnapshotMutation`, `matrxImagePorts` + `resolveExportImage` + `uploadImportedImage`, `openEditorContent` (`registerOpenEditorContent`, `showSavedSnapshot`, `swapContentGuarded`), `registerMissingUniverIcons`, `registerUniverFacadeDependencies`, `routeUniverNotificationsToApp`, `resolveUniverCanvasColor`, `univerImageStore`, `useUniverDarkModeSync`. A transitional entry: it goes internal again when the two editors move into their sections.
|
|
8
|
+
- New `./univer/history` entry (pure): the `document-history` / `workbook-history` tab keys, `readHistoryTab`, `documentHistoryToggleInput`, `workbookHistoryToggleInput`. The two canvas-kind registrations stay in the host app (they lazy-load the views, so no import cycle).
|
|
9
|
+
- New host ports: `configureUniverHost({ toast, getSignedInUser, files, notifyUploadError, useThemeMode })`. Univer glue throws naming the port if an editor mounts before the host configured them.
|
|
10
|
+
|
|
11
|
+
### Consumer action
|
|
12
|
+
|
|
13
|
+
Call `configureUniverHost(...)` once at start-up, before a workbook or document editor mounts. Replace `@/lib/univer/*` imports with `@ai-matrx/office/univer`, and `@/lib/univer/historyKinds` with `@ai-matrx/office/univer/history`.
|
|
14
|
+
|
|
15
|
+
## 0.1.0
|
|
16
|
+
|
|
17
|
+
First release (W1-G1a). `/core`: editor menu model, ribbon model, Google parity rows, document page style, `PageSetup`, product hosts, Office row types. `/core/page-setup-apply`: Univer page-setup commands.
|
|
18
|
+
|
|
19
|
+
### Consumer action
|
|
20
|
+
|
|
21
|
+
Call `configureOfficeHosts(map)` at start-up before using `officeHref`. Register Coming-soon rows and the announcer through `@ai-matrx/kit/coming-soon`.
|
package/README.md
CHANGED
|
@@ -1,3 +1,29 @@
|
|
|
1
1
|
# @ai-matrx/office
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The AI Matrx Office layer. One package, many sections: the editors' shared model today (`/core`),
|
|
4
|
+
Sheets, Docs and the other products as they land. Importing one section never loads another.
|
|
5
|
+
|
|
6
|
+
```ts
|
|
7
|
+
import { configureOfficeHosts, officeHref, flattenMenus, resolveRibbon } from "@ai-matrx/office/core";
|
|
8
|
+
|
|
9
|
+
configureOfficeHosts({
|
|
10
|
+
sheets: "https://sheets.aimatrx.com", docs: "https://docs.aimatrx.com", slides: "https://slides.aimatrx.com",
|
|
11
|
+
bases: "https://bases.aimatrx.com", boards: "https://boards.aimatrx.com", pdf: "https://pdf.aimatrx.com",
|
|
12
|
+
});
|
|
13
|
+
officeHref("docs", "<id>"); // https://docs.aimatrx.com/f/<id>
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Sections
|
|
17
|
+
|
|
18
|
+
| Import | What it is |
|
|
19
|
+
|---|---|
|
|
20
|
+
| `@ai-matrx/office/core` | Pure model. Editor menu model (`EditorMenu`, `EditorToolbarItem`, search, shortcuts), the Microsoft ribbon model (`resolveRibbon`, `ribbonCoverage`), the shared Google parity rows (`soon`, `googleExtensionsMenu`, `googleHelpHead`) and their ribbon homes, document page style and Page setup values, `PageSetup`, product hosts (`configureOfficeHosts`, `officeHref`), and the workbook/document row types. No window access at import. |
|
|
21
|
+
| `@ai-matrx/office/core/page-setup-apply` | `applyPageSetup` / `readPageSetup` against a Univer facade. Its own entry because it alone needs the Univer runtime. |
|
|
22
|
+
|
|
23
|
+
## Host setup
|
|
24
|
+
|
|
25
|
+
Call `configureOfficeHosts` once at start-up with each product's origin (production `*.aimatrx.com`,
|
|
26
|
+
development `*.localhost:5190`). Coming-soon rows announce through `@ai-matrx/kit/coming-soon`: the app
|
|
27
|
+
registers its rows and announcer there.
|
|
28
|
+
|
|
29
|
+
React is a peer (the inlined glyphs are JSX). No icon library, no stylesheet in this section.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/core/page-setup-apply.ts
|
|
21
|
+
var page_setup_apply_exports = {};
|
|
22
|
+
__export(page_setup_apply_exports, {
|
|
23
|
+
PAGE_SETUP_COMMAND: () => PAGE_SETUP_COMMAND,
|
|
24
|
+
applyPageSetup: () => applyPageSetup,
|
|
25
|
+
readPageSetup: () => readPageSetup
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(page_setup_apply_exports);
|
|
28
|
+
var import_core = require("@univerjs/core");
|
|
29
|
+
|
|
30
|
+
// src/core/document-page-style.ts
|
|
31
|
+
var TRADITIONAL = 1;
|
|
32
|
+
var MODERN = 2;
|
|
33
|
+
var PORTRAIT = 0;
|
|
34
|
+
var LANDSCAPE = 1;
|
|
35
|
+
var PX_PER_INCH = 96;
|
|
36
|
+
var PAPER_SIZES = {
|
|
37
|
+
Letter: { width: 816, height: 1056, label: "Letter (8.5 x 11 in)" },
|
|
38
|
+
Legal: { width: 816, height: 1344, label: "Legal (8.5 x 14 in)" },
|
|
39
|
+
Tabloid: { width: 1056, height: 1632, label: "Tabloid (11 x 17 in)" },
|
|
40
|
+
Executive: { width: 696, height: 1008, label: "Executive (7.25 x 10.5 in)" },
|
|
41
|
+
Statement: { width: 528, height: 816, label: "Statement (5.5 x 8.5 in)" },
|
|
42
|
+
A3: { width: 1123, height: 1587, label: "A3 (11.69 x 16.54 in)" },
|
|
43
|
+
A4: { width: 794, height: 1124, label: "A4 (8.27 x 11.69 in)" },
|
|
44
|
+
A5: { width: 559, height: 794, label: "A5 (5.83 x 8.27 in)" }
|
|
45
|
+
};
|
|
46
|
+
var DEFAULT_DOCUMENT_PAGE_STYLE = {
|
|
47
|
+
pageSize: { width: 816, height: 1056 },
|
|
48
|
+
documentFlavor: TRADITIONAL,
|
|
49
|
+
pageOrient: PORTRAIT,
|
|
50
|
+
marginTop: PX_PER_INCH,
|
|
51
|
+
marginBottom: PX_PER_INCH,
|
|
52
|
+
marginLeft: PX_PER_INCH,
|
|
53
|
+
marginRight: PX_PER_INCH,
|
|
54
|
+
// Univer applies no paragraph spacing to a paginated page by itself; without this every paragraph
|
|
55
|
+
// runs into the next (Google Docs' own default: 1.15 lines, 10px after).
|
|
56
|
+
defaultParagraphStyle: { spaceAbove: { v: 0 }, spaceBelow: { v: 10 }, lineSpacing: 1.15 }
|
|
57
|
+
};
|
|
58
|
+
var PAGE_COLORS = ["#ffffff", "#fff8e7", "#f3f3f3", "#e8f0fe", "#e6f4ea", "#fef7e0"];
|
|
59
|
+
var DEFAULT_PAGE_COLOR = PAGE_COLORS[0];
|
|
60
|
+
var PAGE_COLOR_KEY = "matrxPageColor";
|
|
61
|
+
var round2 = (n) => Math.round(n * 100) / 100;
|
|
62
|
+
function pageSetupFromStyle(style) {
|
|
63
|
+
const landscape = style?.pageOrient === LANDSCAPE;
|
|
64
|
+
const w = style?.pageSize?.width ?? DEFAULT_DOCUMENT_PAGE_STYLE.pageSize.width;
|
|
65
|
+
const h = style?.pageSize?.height ?? DEFAULT_DOCUMENT_PAGE_STYLE.pageSize.height;
|
|
66
|
+
const [pw, ph] = landscape ? [h, w] : [w, h];
|
|
67
|
+
const paper = Object.keys(PAPER_SIZES).find(
|
|
68
|
+
(k) => Math.abs(PAPER_SIZES[k].width - pw) <= 1 && Math.abs(PAPER_SIZES[k].height - ph) <= 1
|
|
69
|
+
) ?? "Letter";
|
|
70
|
+
const inch = (v) => round2((v ?? PX_PER_INCH) / PX_PER_INCH);
|
|
71
|
+
const color = style?.[PAGE_COLOR_KEY];
|
|
72
|
+
return {
|
|
73
|
+
pageless: style?.documentFlavor === MODERN,
|
|
74
|
+
orientation: landscape ? "landscape" : "portrait",
|
|
75
|
+
paper,
|
|
76
|
+
marginTop: inch(style?.marginTop),
|
|
77
|
+
marginBottom: inch(style?.marginBottom),
|
|
78
|
+
marginLeft: inch(style?.marginLeft),
|
|
79
|
+
marginRight: inch(style?.marginRight),
|
|
80
|
+
pageColor: typeof color === "string" && color ? color : DEFAULT_PAGE_COLOR
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function pageSetupCommandParams(v) {
|
|
84
|
+
const base = PAPER_SIZES[v.paper];
|
|
85
|
+
const landscape = v.orientation === "landscape";
|
|
86
|
+
return {
|
|
87
|
+
documentFlavor: v.pageless ? MODERN : TRADITIONAL,
|
|
88
|
+
pageOrient: landscape ? LANDSCAPE : PORTRAIT,
|
|
89
|
+
pageSize: landscape ? { width: base.height, height: base.width } : { width: base.width, height: base.height },
|
|
90
|
+
marginTop: Math.round(v.marginTop * PX_PER_INCH),
|
|
91
|
+
marginBottom: Math.round(v.marginBottom * PX_PER_INCH),
|
|
92
|
+
marginLeft: Math.round(v.marginLeft * PX_PER_INCH),
|
|
93
|
+
marginRight: Math.round(v.marginRight * PX_PER_INCH)
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// src/core/page-setup-apply.ts
|
|
98
|
+
var PAGE_SETUP_COMMAND = "docs.command.page-setup";
|
|
99
|
+
var RICH_TEXT_EDITING_MUTATION = "doc.mutation.rich-text-editing";
|
|
100
|
+
function readPageSetup(api) {
|
|
101
|
+
const style = api?.getActiveDocument?.()?.getDocumentDataModel?.()?.getSnapshot().documentStyle;
|
|
102
|
+
return pageSetupFromStyle(style);
|
|
103
|
+
}
|
|
104
|
+
async function writePageColor(api, color) {
|
|
105
|
+
const doc = api.getActiveDocument?.();
|
|
106
|
+
if (!doc) return;
|
|
107
|
+
const style = doc.getDocumentDataModel?.()?.getSnapshot().documentStyle ?? {};
|
|
108
|
+
const old = style[PAGE_COLOR_KEY];
|
|
109
|
+
if (old === color || old === void 0 && color === "#ffffff") return;
|
|
110
|
+
const jsonX = import_core.JSONX.getInstance();
|
|
111
|
+
const path = ["documentStyle", PAGE_COLOR_KEY];
|
|
112
|
+
const action = old === void 0 ? jsonX.insertOp(path, color) : jsonX.replaceOp(path, old, color);
|
|
113
|
+
if (!action) return;
|
|
114
|
+
await api.executeCommand(RICH_TEXT_EDITING_MUTATION, { unitId: doc.getId(), actions: action, textRanges: void 0 });
|
|
115
|
+
}
|
|
116
|
+
async function applyPageSetup(api, values) {
|
|
117
|
+
const ok = await api.executeCommand(PAGE_SETUP_COMMAND, pageSetupCommandParams(values));
|
|
118
|
+
if (ok === false) throw new Error("The editor did not accept the page settings. Nothing was changed.");
|
|
119
|
+
await writePageColor(api, values.pageColor);
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=core-page-setup-apply.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/page-setup-apply.ts","../src/core/document-page-style.ts"],"sourcesContent":["/**\n * Applies File → Page setup to the open document through Univer's own commands, so the change is\n * one undoable edit that travels with the snapshot (and so is saved, synced and reloaded like text).\n */\nimport { JSONX } from \"@univerjs/core\";\n\nimport {\n PAGE_COLOR_KEY,\n pageSetupCommandParams,\n pageSetupFromStyle,\n type PageSetupValues,\n} from \"./document-page-style\";\n\n/** The slice of the Univer facade this needs. Structural on purpose. */\nexport interface PageSetupApiLike {\n executeCommand(id: string, params?: object): Promise<unknown> | unknown;\n getActiveDocument?(): {\n getId(): string;\n getDocumentDataModel?(): { getSnapshot(): { documentStyle?: Record<string, unknown> } } | null;\n } | null;\n}\n\nexport const PAGE_SETUP_COMMAND = \"docs.command.page-setup\";\nconst RICH_TEXT_EDITING_MUTATION = \"doc.mutation.rich-text-editing\";\n\n/** The open document's current page settings, in the dialog's terms. */\nexport function readPageSetup(api: PageSetupApiLike | null | undefined): PageSetupValues {\n const style = api?.getActiveDocument?.()?.getDocumentDataModel?.()?.getSnapshot().documentStyle;\n return pageSetupFromStyle(style as Parameters<typeof pageSetupFromStyle>[0]);\n}\n\n/** Write the paper colour onto the document style (a plain key Univer carries and saves with the snapshot). */\nasync function writePageColor(api: PageSetupApiLike, color: string): Promise<void> {\n const doc = api.getActiveDocument?.();\n if (!doc) return;\n const style = doc.getDocumentDataModel?.()?.getSnapshot().documentStyle ?? {};\n const old = style[PAGE_COLOR_KEY];\n if (old === color || (old === undefined && color === \"#ffffff\")) return;\n const jsonX = JSONX.getInstance();\n const path = [\"documentStyle\", PAGE_COLOR_KEY];\n const action = old === undefined ? jsonX.insertOp(path, color) : jsonX.replaceOp(path, old, color);\n if (!action) return;\n await api.executeCommand(RICH_TEXT_EDITING_MUTATION, { unitId: doc.getId(), actions: action, textRanges: undefined });\n}\n\nexport async function applyPageSetup(api: PageSetupApiLike, values: PageSetupValues): Promise<void> {\n const ok = await api.executeCommand(PAGE_SETUP_COMMAND, pageSetupCommandParams(values));\n if (ok === false) throw new Error(\"The editor did not accept the page settings. Nothing was changed.\");\n await writePageColor(api, values.pageColor);\n}\n","/**\n * The ONE page geometry every Matrx cloud document is laid out with.\n *\n * Univer lays a document out inside `documentStyle.pageSize`. With no pageSize\n * the docs renderer has no page box at all: text never wraps (it runs off the\n * right edge) and the vertical extent is unbounded, so the docs viewport\n * reports nothing to scroll — the wheel is swallowed and the page sits frozen\n * at the top. Every writer of a Univer snapshot MUST stamp this style.\n *\n * Consumers: `DocumentEditor` (new empty doc), `markdown-to-univer-doc`\n * (markdown import), and `sanitizeUniverDocSnapshot` (recovery for snapshots\n * that reached storage without it — notably `origin='agent'` writes).\n */\nimport type { DocumentFlavor, IDocumentData, PageOrientType } from \"@univerjs/core\";\n\n// Univer's enum values, written out: this file is read by tests and the markdown importer, which must not\n// pull Univer's runtime in just for four numbers (guarded by the page-style test).\nconst TRADITIONAL = 1 as DocumentFlavor;\nconst MODERN = 2 as DocumentFlavor;\nconst PORTRAIT = 0 as PageOrientType;\nconst LANDSCAPE = 1 as PageOrientType;\n\ntype DocumentStyle = NonNullable<IDocumentData[\"documentStyle\"]>;\n\n/** Univer lays documents out in 96-dpi CSS pixels: one inch is 96 units. */\nexport const PX_PER_INCH = 96;\n\n/** Paper sizes the Page setup dialog offers, in 96-dpi pixels, portrait (width x height). */\nexport const PAPER_SIZES = {\n Letter: { width: 816, height: 1056, label: \"Letter (8.5 x 11 in)\" },\n Legal: { width: 816, height: 1344, label: \"Legal (8.5 x 14 in)\" },\n Tabloid: { width: 1056, height: 1632, label: \"Tabloid (11 x 17 in)\" },\n Executive: { width: 696, height: 1008, label: \"Executive (7.25 x 10.5 in)\" },\n Statement: { width: 528, height: 816, label: \"Statement (5.5 x 8.5 in)\" },\n A3: { width: 1123, height: 1587, label: \"A3 (11.69 x 16.54 in)\" },\n A4: { width: 794, height: 1124, label: \"A4 (8.27 x 11.69 in)\" },\n A5: { width: 559, height: 794, label: \"A5 (5.83 x 8.27 in)\" },\n} as const;\nexport type PaperSizeName = keyof typeof PAPER_SIZES;\n\n/** A real page, like Google Docs: Letter, one-inch margins (624px of text), paginated. */\nexport const DEFAULT_DOCUMENT_PAGE_STYLE: DocumentStyle = {\n pageSize: { width: 816, height: 1056 },\n documentFlavor: TRADITIONAL,\n pageOrient: PORTRAIT,\n marginTop: PX_PER_INCH,\n marginBottom: PX_PER_INCH,\n marginLeft: PX_PER_INCH,\n marginRight: PX_PER_INCH,\n // Univer applies no paragraph spacing to a paginated page by itself; without this every paragraph\n // runs into the next (Google Docs' own default: 1.15 lines, 10px after).\n defaultParagraphStyle: { spaceAbove: { v: 0 }, spaceBelow: { v: 10 }, lineSpacing: 1.15 },\n};\n\n/** Fresh copy — Univer mutates the style it is handed. */\nexport function defaultDocumentPageStyle(): DocumentStyle {\n return {\n ...DEFAULT_DOCUMENT_PAGE_STYLE,\n pageSize: { ...DEFAULT_DOCUMENT_PAGE_STYLE.pageSize! },\n defaultParagraphStyle: { ...DEFAULT_DOCUMENT_PAGE_STYLE.defaultParagraphStyle! },\n };\n}\n\n/**\n * The squeezed geometry every document was stamped with until 2026-10-15: A4 at 72 dpi (595 x 842)\n * with 90/72 margins, in Univer's pageless flavour, so the text column was ~415px with no paper.\n * Pageless was never offered then, so this exact shape is always the old default, never a choice.\n */\nexport function isLegacySqueezedPageStyle(style: DocumentStyle | undefined): boolean {\n const size = style?.pageSize;\n return (\n !!size &&\n size.width === 595 &&\n size.height === 842 &&\n style?.marginLeft === 90 &&\n style?.marginRight === 90 &&\n style?.marginTop === 72 &&\n style?.marginBottom === 72\n );\n}\n\n/** What the Page setup dialog edits. Margins are in inches, like Google's. */\nexport interface PageSetupValues {\n pageless: boolean;\n orientation: \"portrait\" | \"landscape\";\n paper: PaperSizeName;\n marginTop: number;\n marginBottom: number;\n marginLeft: number;\n marginRight: number;\n /** Paper colour, hex. Always a light colour so the black ink stays readable. */\n pageColor: string;\n}\n\nexport const PAGE_COLORS = [\"#ffffff\", \"#fff8e7\", \"#f3f3f3\", \"#e8f0fe\", \"#e6f4ea\", \"#fef7e0\"] as const;\nexport const DEFAULT_PAGE_COLOR = PAGE_COLORS[0];\n/** Key on `documentStyle` carrying the paper colour (Univer paints it from the host's surface theme). */\nexport const PAGE_COLOR_KEY = \"matrxPageColor\";\n\nconst round2 = (n: number) => Math.round(n * 100) / 100;\n\n/** The dialog's values, read from a document's style (missing parts fall back to the default page). */\nexport function pageSetupFromStyle(style: DocumentStyle | undefined): PageSetupValues {\n const landscape = style?.pageOrient === LANDSCAPE;\n const w = style?.pageSize?.width ?? DEFAULT_DOCUMENT_PAGE_STYLE.pageSize!.width!;\n const h = style?.pageSize?.height ?? DEFAULT_DOCUMENT_PAGE_STYLE.pageSize!.height!;\n const [pw, ph] = landscape ? [h, w] : [w, h];\n const paper =\n (Object.keys(PAPER_SIZES) as PaperSizeName[]).find(\n (k) => Math.abs(PAPER_SIZES[k].width - pw) <= 1 && Math.abs(PAPER_SIZES[k].height - ph) <= 1,\n ) ?? \"Letter\";\n const inch = (v: number | undefined) => round2((v ?? PX_PER_INCH) / PX_PER_INCH);\n const color = (style as Record<string, unknown> | undefined)?.[PAGE_COLOR_KEY];\n return {\n pageless: style?.documentFlavor === MODERN,\n orientation: landscape ? \"landscape\" : \"portrait\",\n paper,\n marginTop: inch(style?.marginTop),\n marginBottom: inch(style?.marginBottom),\n marginLeft: inch(style?.marginLeft),\n marginRight: inch(style?.marginRight),\n pageColor: typeof color === \"string\" && color ? color : DEFAULT_PAGE_COLOR,\n };\n}\n\n/** Params for Univer's `docs.command.page-setup` (pageSize is the as-printed size: swapped when landscape). */\nexport function pageSetupCommandParams(v: PageSetupValues) {\n const base = PAPER_SIZES[v.paper];\n const landscape = v.orientation === \"landscape\";\n return {\n documentFlavor: v.pageless ? MODERN : TRADITIONAL,\n pageOrient: landscape ? LANDSCAPE : PORTRAIT,\n pageSize: landscape ? { width: base.height, height: base.width } : { width: base.width, height: base.height },\n marginTop: Math.round(v.marginTop * PX_PER_INCH),\n marginBottom: Math.round(v.marginBottom * PX_PER_INCH),\n marginLeft: Math.round(v.marginLeft * PX_PER_INCH),\n marginRight: Math.round(v.marginRight * PX_PER_INCH),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,kBAAsB;;;ACatB,IAAM,cAAc;AACpB,IAAM,SAAS;AACf,IAAM,WAAW;AACjB,IAAM,YAAY;AAKX,IAAM,cAAc;AAGpB,IAAM,cAAc;AAAA,EACzB,QAAQ,EAAE,OAAO,KAAK,QAAQ,MAAM,OAAO,uBAAuB;AAAA,EAClE,OAAO,EAAE,OAAO,KAAK,QAAQ,MAAM,OAAO,sBAAsB;AAAA,EAChE,SAAS,EAAE,OAAO,MAAM,QAAQ,MAAM,OAAO,uBAAuB;AAAA,EACpE,WAAW,EAAE,OAAO,KAAK,QAAQ,MAAM,OAAO,6BAA6B;AAAA,EAC3E,WAAW,EAAE,OAAO,KAAK,QAAQ,KAAK,OAAO,2BAA2B;AAAA,EACxE,IAAI,EAAE,OAAO,MAAM,QAAQ,MAAM,OAAO,wBAAwB;AAAA,EAChE,IAAI,EAAE,OAAO,KAAK,QAAQ,MAAM,OAAO,uBAAuB;AAAA,EAC9D,IAAI,EAAE,OAAO,KAAK,QAAQ,KAAK,OAAO,sBAAsB;AAC9D;AAIO,IAAM,8BAA6C;AAAA,EACxD,UAAU,EAAE,OAAO,KAAK,QAAQ,KAAK;AAAA,EACrC,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,aAAa;AAAA;AAAA;AAAA,EAGb,uBAAuB,EAAE,YAAY,EAAE,GAAG,EAAE,GAAG,YAAY,EAAE,GAAG,GAAG,GAAG,aAAa,KAAK;AAC1F;AA0CO,IAAM,cAAc,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AACrF,IAAM,qBAAqB,YAAY,CAAC;AAExC,IAAM,iBAAiB;AAE9B,IAAM,SAAS,CAAC,MAAc,KAAK,MAAM,IAAI,GAAG,IAAI;AAG7C,SAAS,mBAAmB,OAAmD;AACpF,QAAM,YAAY,OAAO,eAAe;AACxC,QAAM,IAAI,OAAO,UAAU,SAAS,4BAA4B,SAAU;AAC1E,QAAM,IAAI,OAAO,UAAU,UAAU,4BAA4B,SAAU;AAC3E,QAAM,CAAC,IAAI,EAAE,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;AAC3C,QAAM,QACH,OAAO,KAAK,WAAW,EAAsB;AAAA,IAC5C,CAAC,MAAM,KAAK,IAAI,YAAY,CAAC,EAAE,QAAQ,EAAE,KAAK,KAAK,KAAK,IAAI,YAAY,CAAC,EAAE,SAAS,EAAE,KAAK;AAAA,EAC7F,KAAK;AACP,QAAM,OAAO,CAAC,MAA0B,QAAQ,KAAK,eAAe,WAAW;AAC/E,QAAM,QAAS,QAAgD,cAAc;AAC7E,SAAO;AAAA,IACL,UAAU,OAAO,mBAAmB;AAAA,IACpC,aAAa,YAAY,cAAc;AAAA,IACvC;AAAA,IACA,WAAW,KAAK,OAAO,SAAS;AAAA,IAChC,cAAc,KAAK,OAAO,YAAY;AAAA,IACtC,YAAY,KAAK,OAAO,UAAU;AAAA,IAClC,aAAa,KAAK,OAAO,WAAW;AAAA,IACpC,WAAW,OAAO,UAAU,YAAY,QAAQ,QAAQ;AAAA,EAC1D;AACF;AAGO,SAAS,uBAAuB,GAAoB;AACzD,QAAM,OAAO,YAAY,EAAE,KAAK;AAChC,QAAM,YAAY,EAAE,gBAAgB;AACpC,SAAO;AAAA,IACL,gBAAgB,EAAE,WAAW,SAAS;AAAA,IACtC,YAAY,YAAY,YAAY;AAAA,IACpC,UAAU,YAAY,EAAE,OAAO,KAAK,QAAQ,QAAQ,KAAK,MAAM,IAAI,EAAE,OAAO,KAAK,OAAO,QAAQ,KAAK,OAAO;AAAA,IAC5G,WAAW,KAAK,MAAM,EAAE,YAAY,WAAW;AAAA,IAC/C,cAAc,KAAK,MAAM,EAAE,eAAe,WAAW;AAAA,IACrD,YAAY,KAAK,MAAM,EAAE,aAAa,WAAW;AAAA,IACjD,aAAa,KAAK,MAAM,EAAE,cAAc,WAAW;AAAA,EACrD;AACF;;;ADpHO,IAAM,qBAAqB;AAClC,IAAM,6BAA6B;AAG5B,SAAS,cAAc,KAA2D;AACvF,QAAM,QAAQ,KAAK,oBAAoB,GAAG,uBAAuB,GAAG,YAAY,EAAE;AAClF,SAAO,mBAAmB,KAAiD;AAC7E;AAGA,eAAe,eAAe,KAAuB,OAA8B;AACjF,QAAM,MAAM,IAAI,oBAAoB;AACpC,MAAI,CAAC,IAAK;AACV,QAAM,QAAQ,IAAI,uBAAuB,GAAG,YAAY,EAAE,iBAAiB,CAAC;AAC5E,QAAM,MAAM,MAAM,cAAc;AAChC,MAAI,QAAQ,SAAU,QAAQ,UAAa,UAAU,UAAY;AACjE,QAAM,QAAQ,kBAAM,YAAY;AAChC,QAAM,OAAO,CAAC,iBAAiB,cAAc;AAC7C,QAAM,SAAS,QAAQ,SAAY,MAAM,SAAS,MAAM,KAAK,IAAI,MAAM,UAAU,MAAM,KAAK,KAAK;AACjG,MAAI,CAAC,OAAQ;AACb,QAAM,IAAI,eAAe,4BAA4B,EAAE,QAAQ,IAAI,MAAM,GAAG,SAAS,QAAQ,YAAY,OAAU,CAAC;AACtH;AAEA,eAAsB,eAAe,KAAuB,QAAwC;AAClG,QAAM,KAAK,MAAM,IAAI,eAAe,oBAAoB,uBAAuB,MAAM,CAAC;AACtF,MAAI,OAAO,MAAO,OAAM,IAAI,MAAM,mEAAmE;AACrG,QAAM,eAAe,KAAK,OAAO,SAAS;AAC5C;","names":[]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { e as PageSetupValues } from './document-page-style-BFLrgdLI.cjs';
|
|
2
|
+
import '@univerjs/core';
|
|
3
|
+
|
|
4
|
+
/** The slice of the Univer facade this needs. Structural on purpose. */
|
|
5
|
+
interface PageSetupApiLike {
|
|
6
|
+
executeCommand(id: string, params?: object): Promise<unknown> | unknown;
|
|
7
|
+
getActiveDocument?(): {
|
|
8
|
+
getId(): string;
|
|
9
|
+
getDocumentDataModel?(): {
|
|
10
|
+
getSnapshot(): {
|
|
11
|
+
documentStyle?: Record<string, unknown>;
|
|
12
|
+
};
|
|
13
|
+
} | null;
|
|
14
|
+
} | null;
|
|
15
|
+
}
|
|
16
|
+
declare const PAGE_SETUP_COMMAND = "docs.command.page-setup";
|
|
17
|
+
/** The open document's current page settings, in the dialog's terms. */
|
|
18
|
+
declare function readPageSetup(api: PageSetupApiLike | null | undefined): PageSetupValues;
|
|
19
|
+
declare function applyPageSetup(api: PageSetupApiLike, values: PageSetupValues): Promise<void>;
|
|
20
|
+
|
|
21
|
+
export { PAGE_SETUP_COMMAND, type PageSetupApiLike, applyPageSetup, readPageSetup };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { e as PageSetupValues } from './document-page-style-BFLrgdLI.js';
|
|
2
|
+
import '@univerjs/core';
|
|
3
|
+
|
|
4
|
+
/** The slice of the Univer facade this needs. Structural on purpose. */
|
|
5
|
+
interface PageSetupApiLike {
|
|
6
|
+
executeCommand(id: string, params?: object): Promise<unknown> | unknown;
|
|
7
|
+
getActiveDocument?(): {
|
|
8
|
+
getId(): string;
|
|
9
|
+
getDocumentDataModel?(): {
|
|
10
|
+
getSnapshot(): {
|
|
11
|
+
documentStyle?: Record<string, unknown>;
|
|
12
|
+
};
|
|
13
|
+
} | null;
|
|
14
|
+
} | null;
|
|
15
|
+
}
|
|
16
|
+
declare const PAGE_SETUP_COMMAND = "docs.command.page-setup";
|
|
17
|
+
/** The open document's current page settings, in the dialog's terms. */
|
|
18
|
+
declare function readPageSetup(api: PageSetupApiLike | null | undefined): PageSetupValues;
|
|
19
|
+
declare function applyPageSetup(api: PageSetupApiLike, values: PageSetupValues): Promise<void>;
|
|
20
|
+
|
|
21
|
+
export { PAGE_SETUP_COMMAND, type PageSetupApiLike, applyPageSetup, readPageSetup };
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// src/core/page-setup-apply.ts
|
|
2
|
+
import { JSONX } from "@univerjs/core";
|
|
3
|
+
|
|
4
|
+
// src/core/document-page-style.ts
|
|
5
|
+
var TRADITIONAL = 1;
|
|
6
|
+
var MODERN = 2;
|
|
7
|
+
var PORTRAIT = 0;
|
|
8
|
+
var LANDSCAPE = 1;
|
|
9
|
+
var PX_PER_INCH = 96;
|
|
10
|
+
var PAPER_SIZES = {
|
|
11
|
+
Letter: { width: 816, height: 1056, label: "Letter (8.5 x 11 in)" },
|
|
12
|
+
Legal: { width: 816, height: 1344, label: "Legal (8.5 x 14 in)" },
|
|
13
|
+
Tabloid: { width: 1056, height: 1632, label: "Tabloid (11 x 17 in)" },
|
|
14
|
+
Executive: { width: 696, height: 1008, label: "Executive (7.25 x 10.5 in)" },
|
|
15
|
+
Statement: { width: 528, height: 816, label: "Statement (5.5 x 8.5 in)" },
|
|
16
|
+
A3: { width: 1123, height: 1587, label: "A3 (11.69 x 16.54 in)" },
|
|
17
|
+
A4: { width: 794, height: 1124, label: "A4 (8.27 x 11.69 in)" },
|
|
18
|
+
A5: { width: 559, height: 794, label: "A5 (5.83 x 8.27 in)" }
|
|
19
|
+
};
|
|
20
|
+
var DEFAULT_DOCUMENT_PAGE_STYLE = {
|
|
21
|
+
pageSize: { width: 816, height: 1056 },
|
|
22
|
+
documentFlavor: TRADITIONAL,
|
|
23
|
+
pageOrient: PORTRAIT,
|
|
24
|
+
marginTop: PX_PER_INCH,
|
|
25
|
+
marginBottom: PX_PER_INCH,
|
|
26
|
+
marginLeft: PX_PER_INCH,
|
|
27
|
+
marginRight: PX_PER_INCH,
|
|
28
|
+
// Univer applies no paragraph spacing to a paginated page by itself; without this every paragraph
|
|
29
|
+
// runs into the next (Google Docs' own default: 1.15 lines, 10px after).
|
|
30
|
+
defaultParagraphStyle: { spaceAbove: { v: 0 }, spaceBelow: { v: 10 }, lineSpacing: 1.15 }
|
|
31
|
+
};
|
|
32
|
+
var PAGE_COLORS = ["#ffffff", "#fff8e7", "#f3f3f3", "#e8f0fe", "#e6f4ea", "#fef7e0"];
|
|
33
|
+
var DEFAULT_PAGE_COLOR = PAGE_COLORS[0];
|
|
34
|
+
var PAGE_COLOR_KEY = "matrxPageColor";
|
|
35
|
+
var round2 = (n) => Math.round(n * 100) / 100;
|
|
36
|
+
function pageSetupFromStyle(style) {
|
|
37
|
+
const landscape = style?.pageOrient === LANDSCAPE;
|
|
38
|
+
const w = style?.pageSize?.width ?? DEFAULT_DOCUMENT_PAGE_STYLE.pageSize.width;
|
|
39
|
+
const h = style?.pageSize?.height ?? DEFAULT_DOCUMENT_PAGE_STYLE.pageSize.height;
|
|
40
|
+
const [pw, ph] = landscape ? [h, w] : [w, h];
|
|
41
|
+
const paper = Object.keys(PAPER_SIZES).find(
|
|
42
|
+
(k) => Math.abs(PAPER_SIZES[k].width - pw) <= 1 && Math.abs(PAPER_SIZES[k].height - ph) <= 1
|
|
43
|
+
) ?? "Letter";
|
|
44
|
+
const inch = (v) => round2((v ?? PX_PER_INCH) / PX_PER_INCH);
|
|
45
|
+
const color = style?.[PAGE_COLOR_KEY];
|
|
46
|
+
return {
|
|
47
|
+
pageless: style?.documentFlavor === MODERN,
|
|
48
|
+
orientation: landscape ? "landscape" : "portrait",
|
|
49
|
+
paper,
|
|
50
|
+
marginTop: inch(style?.marginTop),
|
|
51
|
+
marginBottom: inch(style?.marginBottom),
|
|
52
|
+
marginLeft: inch(style?.marginLeft),
|
|
53
|
+
marginRight: inch(style?.marginRight),
|
|
54
|
+
pageColor: typeof color === "string" && color ? color : DEFAULT_PAGE_COLOR
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function pageSetupCommandParams(v) {
|
|
58
|
+
const base = PAPER_SIZES[v.paper];
|
|
59
|
+
const landscape = v.orientation === "landscape";
|
|
60
|
+
return {
|
|
61
|
+
documentFlavor: v.pageless ? MODERN : TRADITIONAL,
|
|
62
|
+
pageOrient: landscape ? LANDSCAPE : PORTRAIT,
|
|
63
|
+
pageSize: landscape ? { width: base.height, height: base.width } : { width: base.width, height: base.height },
|
|
64
|
+
marginTop: Math.round(v.marginTop * PX_PER_INCH),
|
|
65
|
+
marginBottom: Math.round(v.marginBottom * PX_PER_INCH),
|
|
66
|
+
marginLeft: Math.round(v.marginLeft * PX_PER_INCH),
|
|
67
|
+
marginRight: Math.round(v.marginRight * PX_PER_INCH)
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// src/core/page-setup-apply.ts
|
|
72
|
+
var PAGE_SETUP_COMMAND = "docs.command.page-setup";
|
|
73
|
+
var RICH_TEXT_EDITING_MUTATION = "doc.mutation.rich-text-editing";
|
|
74
|
+
function readPageSetup(api) {
|
|
75
|
+
const style = api?.getActiveDocument?.()?.getDocumentDataModel?.()?.getSnapshot().documentStyle;
|
|
76
|
+
return pageSetupFromStyle(style);
|
|
77
|
+
}
|
|
78
|
+
async function writePageColor(api, color) {
|
|
79
|
+
const doc = api.getActiveDocument?.();
|
|
80
|
+
if (!doc) return;
|
|
81
|
+
const style = doc.getDocumentDataModel?.()?.getSnapshot().documentStyle ?? {};
|
|
82
|
+
const old = style[PAGE_COLOR_KEY];
|
|
83
|
+
if (old === color || old === void 0 && color === "#ffffff") return;
|
|
84
|
+
const jsonX = JSONX.getInstance();
|
|
85
|
+
const path = ["documentStyle", PAGE_COLOR_KEY];
|
|
86
|
+
const action = old === void 0 ? jsonX.insertOp(path, color) : jsonX.replaceOp(path, old, color);
|
|
87
|
+
if (!action) return;
|
|
88
|
+
await api.executeCommand(RICH_TEXT_EDITING_MUTATION, { unitId: doc.getId(), actions: action, textRanges: void 0 });
|
|
89
|
+
}
|
|
90
|
+
async function applyPageSetup(api, values) {
|
|
91
|
+
const ok = await api.executeCommand(PAGE_SETUP_COMMAND, pageSetupCommandParams(values));
|
|
92
|
+
if (ok === false) throw new Error("The editor did not accept the page settings. Nothing was changed.");
|
|
93
|
+
await writePageColor(api, values.pageColor);
|
|
94
|
+
}
|
|
95
|
+
export {
|
|
96
|
+
PAGE_SETUP_COMMAND,
|
|
97
|
+
applyPageSetup,
|
|
98
|
+
readPageSetup
|
|
99
|
+
};
|
|
100
|
+
//# sourceMappingURL=core-page-setup-apply.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/page-setup-apply.ts","../src/core/document-page-style.ts"],"sourcesContent":["/**\n * Applies File → Page setup to the open document through Univer's own commands, so the change is\n * one undoable edit that travels with the snapshot (and so is saved, synced and reloaded like text).\n */\nimport { JSONX } from \"@univerjs/core\";\n\nimport {\n PAGE_COLOR_KEY,\n pageSetupCommandParams,\n pageSetupFromStyle,\n type PageSetupValues,\n} from \"./document-page-style\";\n\n/** The slice of the Univer facade this needs. Structural on purpose. */\nexport interface PageSetupApiLike {\n executeCommand(id: string, params?: object): Promise<unknown> | unknown;\n getActiveDocument?(): {\n getId(): string;\n getDocumentDataModel?(): { getSnapshot(): { documentStyle?: Record<string, unknown> } } | null;\n } | null;\n}\n\nexport const PAGE_SETUP_COMMAND = \"docs.command.page-setup\";\nconst RICH_TEXT_EDITING_MUTATION = \"doc.mutation.rich-text-editing\";\n\n/** The open document's current page settings, in the dialog's terms. */\nexport function readPageSetup(api: PageSetupApiLike | null | undefined): PageSetupValues {\n const style = api?.getActiveDocument?.()?.getDocumentDataModel?.()?.getSnapshot().documentStyle;\n return pageSetupFromStyle(style as Parameters<typeof pageSetupFromStyle>[0]);\n}\n\n/** Write the paper colour onto the document style (a plain key Univer carries and saves with the snapshot). */\nasync function writePageColor(api: PageSetupApiLike, color: string): Promise<void> {\n const doc = api.getActiveDocument?.();\n if (!doc) return;\n const style = doc.getDocumentDataModel?.()?.getSnapshot().documentStyle ?? {};\n const old = style[PAGE_COLOR_KEY];\n if (old === color || (old === undefined && color === \"#ffffff\")) return;\n const jsonX = JSONX.getInstance();\n const path = [\"documentStyle\", PAGE_COLOR_KEY];\n const action = old === undefined ? jsonX.insertOp(path, color) : jsonX.replaceOp(path, old, color);\n if (!action) return;\n await api.executeCommand(RICH_TEXT_EDITING_MUTATION, { unitId: doc.getId(), actions: action, textRanges: undefined });\n}\n\nexport async function applyPageSetup(api: PageSetupApiLike, values: PageSetupValues): Promise<void> {\n const ok = await api.executeCommand(PAGE_SETUP_COMMAND, pageSetupCommandParams(values));\n if (ok === false) throw new Error(\"The editor did not accept the page settings. Nothing was changed.\");\n await writePageColor(api, values.pageColor);\n}\n","/**\n * The ONE page geometry every Matrx cloud document is laid out with.\n *\n * Univer lays a document out inside `documentStyle.pageSize`. With no pageSize\n * the docs renderer has no page box at all: text never wraps (it runs off the\n * right edge) and the vertical extent is unbounded, so the docs viewport\n * reports nothing to scroll — the wheel is swallowed and the page sits frozen\n * at the top. Every writer of a Univer snapshot MUST stamp this style.\n *\n * Consumers: `DocumentEditor` (new empty doc), `markdown-to-univer-doc`\n * (markdown import), and `sanitizeUniverDocSnapshot` (recovery for snapshots\n * that reached storage without it — notably `origin='agent'` writes).\n */\nimport type { DocumentFlavor, IDocumentData, PageOrientType } from \"@univerjs/core\";\n\n// Univer's enum values, written out: this file is read by tests and the markdown importer, which must not\n// pull Univer's runtime in just for four numbers (guarded by the page-style test).\nconst TRADITIONAL = 1 as DocumentFlavor;\nconst MODERN = 2 as DocumentFlavor;\nconst PORTRAIT = 0 as PageOrientType;\nconst LANDSCAPE = 1 as PageOrientType;\n\ntype DocumentStyle = NonNullable<IDocumentData[\"documentStyle\"]>;\n\n/** Univer lays documents out in 96-dpi CSS pixels: one inch is 96 units. */\nexport const PX_PER_INCH = 96;\n\n/** Paper sizes the Page setup dialog offers, in 96-dpi pixels, portrait (width x height). */\nexport const PAPER_SIZES = {\n Letter: { width: 816, height: 1056, label: \"Letter (8.5 x 11 in)\" },\n Legal: { width: 816, height: 1344, label: \"Legal (8.5 x 14 in)\" },\n Tabloid: { width: 1056, height: 1632, label: \"Tabloid (11 x 17 in)\" },\n Executive: { width: 696, height: 1008, label: \"Executive (7.25 x 10.5 in)\" },\n Statement: { width: 528, height: 816, label: \"Statement (5.5 x 8.5 in)\" },\n A3: { width: 1123, height: 1587, label: \"A3 (11.69 x 16.54 in)\" },\n A4: { width: 794, height: 1124, label: \"A4 (8.27 x 11.69 in)\" },\n A5: { width: 559, height: 794, label: \"A5 (5.83 x 8.27 in)\" },\n} as const;\nexport type PaperSizeName = keyof typeof PAPER_SIZES;\n\n/** A real page, like Google Docs: Letter, one-inch margins (624px of text), paginated. */\nexport const DEFAULT_DOCUMENT_PAGE_STYLE: DocumentStyle = {\n pageSize: { width: 816, height: 1056 },\n documentFlavor: TRADITIONAL,\n pageOrient: PORTRAIT,\n marginTop: PX_PER_INCH,\n marginBottom: PX_PER_INCH,\n marginLeft: PX_PER_INCH,\n marginRight: PX_PER_INCH,\n // Univer applies no paragraph spacing to a paginated page by itself; without this every paragraph\n // runs into the next (Google Docs' own default: 1.15 lines, 10px after).\n defaultParagraphStyle: { spaceAbove: { v: 0 }, spaceBelow: { v: 10 }, lineSpacing: 1.15 },\n};\n\n/** Fresh copy — Univer mutates the style it is handed. */\nexport function defaultDocumentPageStyle(): DocumentStyle {\n return {\n ...DEFAULT_DOCUMENT_PAGE_STYLE,\n pageSize: { ...DEFAULT_DOCUMENT_PAGE_STYLE.pageSize! },\n defaultParagraphStyle: { ...DEFAULT_DOCUMENT_PAGE_STYLE.defaultParagraphStyle! },\n };\n}\n\n/**\n * The squeezed geometry every document was stamped with until 2026-10-15: A4 at 72 dpi (595 x 842)\n * with 90/72 margins, in Univer's pageless flavour, so the text column was ~415px with no paper.\n * Pageless was never offered then, so this exact shape is always the old default, never a choice.\n */\nexport function isLegacySqueezedPageStyle(style: DocumentStyle | undefined): boolean {\n const size = style?.pageSize;\n return (\n !!size &&\n size.width === 595 &&\n size.height === 842 &&\n style?.marginLeft === 90 &&\n style?.marginRight === 90 &&\n style?.marginTop === 72 &&\n style?.marginBottom === 72\n );\n}\n\n/** What the Page setup dialog edits. Margins are in inches, like Google's. */\nexport interface PageSetupValues {\n pageless: boolean;\n orientation: \"portrait\" | \"landscape\";\n paper: PaperSizeName;\n marginTop: number;\n marginBottom: number;\n marginLeft: number;\n marginRight: number;\n /** Paper colour, hex. Always a light colour so the black ink stays readable. */\n pageColor: string;\n}\n\nexport const PAGE_COLORS = [\"#ffffff\", \"#fff8e7\", \"#f3f3f3\", \"#e8f0fe\", \"#e6f4ea\", \"#fef7e0\"] as const;\nexport const DEFAULT_PAGE_COLOR = PAGE_COLORS[0];\n/** Key on `documentStyle` carrying the paper colour (Univer paints it from the host's surface theme). */\nexport const PAGE_COLOR_KEY = \"matrxPageColor\";\n\nconst round2 = (n: number) => Math.round(n * 100) / 100;\n\n/** The dialog's values, read from a document's style (missing parts fall back to the default page). */\nexport function pageSetupFromStyle(style: DocumentStyle | undefined): PageSetupValues {\n const landscape = style?.pageOrient === LANDSCAPE;\n const w = style?.pageSize?.width ?? DEFAULT_DOCUMENT_PAGE_STYLE.pageSize!.width!;\n const h = style?.pageSize?.height ?? DEFAULT_DOCUMENT_PAGE_STYLE.pageSize!.height!;\n const [pw, ph] = landscape ? [h, w] : [w, h];\n const paper =\n (Object.keys(PAPER_SIZES) as PaperSizeName[]).find(\n (k) => Math.abs(PAPER_SIZES[k].width - pw) <= 1 && Math.abs(PAPER_SIZES[k].height - ph) <= 1,\n ) ?? \"Letter\";\n const inch = (v: number | undefined) => round2((v ?? PX_PER_INCH) / PX_PER_INCH);\n const color = (style as Record<string, unknown> | undefined)?.[PAGE_COLOR_KEY];\n return {\n pageless: style?.documentFlavor === MODERN,\n orientation: landscape ? \"landscape\" : \"portrait\",\n paper,\n marginTop: inch(style?.marginTop),\n marginBottom: inch(style?.marginBottom),\n marginLeft: inch(style?.marginLeft),\n marginRight: inch(style?.marginRight),\n pageColor: typeof color === \"string\" && color ? color : DEFAULT_PAGE_COLOR,\n };\n}\n\n/** Params for Univer's `docs.command.page-setup` (pageSize is the as-printed size: swapped when landscape). */\nexport function pageSetupCommandParams(v: PageSetupValues) {\n const base = PAPER_SIZES[v.paper];\n const landscape = v.orientation === \"landscape\";\n return {\n documentFlavor: v.pageless ? MODERN : TRADITIONAL,\n pageOrient: landscape ? LANDSCAPE : PORTRAIT,\n pageSize: landscape ? { width: base.height, height: base.width } : { width: base.width, height: base.height },\n marginTop: Math.round(v.marginTop * PX_PER_INCH),\n marginBottom: Math.round(v.marginBottom * PX_PER_INCH),\n marginLeft: Math.round(v.marginLeft * PX_PER_INCH),\n marginRight: Math.round(v.marginRight * PX_PER_INCH),\n };\n}\n"],"mappings":"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","names":[]}
|