@stll/folio-core 0.22.3 → 0.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-edits/apply.d.ts +1 -1
- package/dist/controller/layoutPipeline.js +7 -3
- package/dist/document-operations.d.ts +4 -4
- package/dist/document-operations.js +17 -1
- package/dist/docx/blockContentParser.js +2 -47
- package/dist/docx/fieldParser.d.ts +1 -1
- package/dist/docx/fieldParser.js +12 -4
- package/dist/docx/numberingParser.d.ts +2 -11
- package/dist/docx/numberingParser.js +3 -79
- package/dist/docx/ooxmlCounterFormatter.d.ts +8 -0
- package/dist/docx/ooxmlCounterFormatter.js +134 -0
- package/dist/docx/rezip.d.ts +1 -1
- package/dist/docx/rezip.js +12 -31
- package/dist/docx/serializer/tableSerializer.js +1 -1
- package/dist/docx/tableParser.js +2 -1
- package/dist/fields/bookmarkPages.js +1 -1
- package/dist/fields/evaluateField.js +1 -1
- package/dist/fields/fieldContext.d.ts +2 -0
- package/dist/fields/resolveFieldValues.js +5 -2
- package/dist/layout-bridge/convert/headerFooterLayout.js +6 -0
- package/dist/layout-bridge/convert/toFlowBlocks.js +51 -109
- package/dist/layout-engine/index.d.ts +3 -2
- package/dist/layout-engine/index.js +40 -16
- package/dist/layout-engine/measure/cache.js +1 -1
- package/dist/layout-engine/measure/complexScriptFormatting.d.ts +18 -0
- package/dist/layout-engine/measure/complexScriptFormatting.js +11 -0
- package/dist/layout-engine/measure/measureContainer.js +31 -16
- package/dist/layout-engine/measure/measureHelpers.js +4 -0
- package/dist/layout-engine/measure/measureParagraph.js +13 -3
- package/dist/layout-engine/measure/measureTypes.d.ts +4 -0
- package/dist/layout-engine/paginator.d.ts +5 -3
- package/dist/layout-engine/paginator.js +34 -13
- package/dist/layout-engine/types.d.ts +31 -4
- package/dist/layout-painter/imageLayout.d.ts +1 -1
- package/dist/layout-painter/index.js +2 -1
- package/dist/layout-painter/renderPage.js +9 -3
- package/dist/layout-painter/renderParagraph.js +42 -25
- package/dist/layout-painter/renderUtils.d.ts +2 -0
- package/dist/managers/AutoSaveManager.js +8 -40
- package/dist/managers/TableSelectionManager.d.ts +1 -1
- package/dist/managers/autoSaveCodec.d.ts +17 -0
- package/dist/managers/autoSaveCodec.js +109 -0
- package/dist/paged-layout/sectionGeometry.d.ts +3 -2
- package/dist/paged-layout/sectionGeometry.js +17 -1
- package/dist/prosemirror/attrs/index.js +278 -25
- package/dist/prosemirror/commands/comments.js +3 -3
- package/dist/prosemirror/commands/formatting.js +19 -19
- package/dist/prosemirror/commands/index.d.ts +2 -2
- package/dist/prosemirror/commands/paragraph.js +32 -32
- package/dist/prosemirror/commands/propertyChangeScope.d.ts +4 -2
- package/dist/prosemirror/commands/propertyChangeScope.js +8 -8
- package/dist/prosemirror/commands/table.d.ts +10 -52
- package/dist/prosemirror/commands/table.js +34 -34
- package/dist/prosemirror/conversion/fromProseDoc.js +24 -33
- package/dist/prosemirror/conversion/sdtAttrs.d.ts +2 -1
- package/dist/prosemirror/conversion/sdtAttrs.js +9 -4
- package/dist/prosemirror/conversion/toProseDoc.js +4 -1
- package/dist/prosemirror/extensions/ExtensionManager.d.ts +6 -3
- package/dist/prosemirror/extensions/ExtensionManager.js +5 -3
- package/dist/prosemirror/extensions/core/ParagraphExtension.d.ts +1 -1
- package/dist/prosemirror/extensions/features/ListExtension.js +4 -4
- package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.d.ts +3 -2
- package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.js +31 -17
- package/dist/prosemirror/extensions/nodes/ShapeExtension.d.ts +1 -1
- package/dist/prosemirror/extensions/nodes/TableExtension.js +1 -0
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.d.ts +1 -1
- package/dist/prosemirror/extensions/types.d.ts +134 -1
- package/dist/prosemirror/index.d.ts +2 -2
- package/dist/prosemirror/plugins/selectionTracker.js +25 -99
- package/dist/prosemirror/revisionCarriers.js +3 -1
- package/dist/prosemirror/schema/index.d.ts +2 -2
- package/dist/prosemirror/schema/index.js +87 -0
- package/dist/prosemirror/schema/marks.d.ts +8 -0
- package/dist/prosemirror/schema/nodes.d.ts +15 -2
- package/dist/prosemirror/selectionState.d.ts +11 -5
- package/dist/prosemirror/selectionState.js +94 -57
- package/dist/utils/tableOperations.d.ts +7 -6
- package/package.json +3 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ColumnLayout, FOOTNOTE_SEPARATOR_HEIGHT, Fragment, Page, PageHeaderFooterRefs, PageMargins } from "./types.js";
|
|
1
|
+
import { ColumnLayout, FOOTNOTE_SEPARATOR_HEIGHT, Fragment, Page, PageHeaderFooterRefs, PageMargins, SectionPageNumbering } from "./types.js";
|
|
2
2
|
//#region src/layout-engine/paginator.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* Current state of a page being laid out.
|
|
@@ -45,8 +45,10 @@ type PaginatorOptions = {
|
|
|
45
45
|
* first-page header) vs. its body pages. Pages 2+ use `margins`.
|
|
46
46
|
*/
|
|
47
47
|
firstPageMargins?: PageMargins;
|
|
48
|
-
/** Per-section body margins used on even
|
|
48
|
+
/** Per-section body margins used on even authored page numbers. */
|
|
49
49
|
sectionEvenPageMargins?: (PageMargins | undefined)[];
|
|
50
|
+
/** Page-number policy for the initial section. */
|
|
51
|
+
pageNumbering?: SectionPageNumbering;
|
|
50
52
|
/** Column configuration (optional). */
|
|
51
53
|
columns?: ColumnLayout;
|
|
52
54
|
/** Per-page footnote reserved heights (pageNumber → height in pixels). */
|
|
@@ -114,7 +116,7 @@ declare function createPaginator(options: PaginatorOptions): {
|
|
|
114
116
|
h: number;
|
|
115
117
|
}, newMargins?: PageMargins, applyImmediately?: boolean) => void;
|
|
116
118
|
/** Mark the next created page as the first page of a new section. */
|
|
117
|
-
startSection: (sectionIndex: number) => void;
|
|
119
|
+
startSection: (sectionIndex: number, pageNumbering?: SectionPageNumbering) => void;
|
|
118
120
|
};
|
|
119
121
|
type Paginator = ReturnType<typeof createPaginator>;
|
|
120
122
|
//#endregion
|
|
@@ -35,6 +35,9 @@ function createPaginator(options) {
|
|
|
35
35
|
let pendingMargins;
|
|
36
36
|
let currentSectionIndex = 0;
|
|
37
37
|
let currentSectionPageNumber = 0;
|
|
38
|
+
let currentPageNumbering = options.pageNumbering ?? { type: "continue" };
|
|
39
|
+
let nextLogicalPageNumber = currentPageNumbering.type === "restart" ? currentPageNumbering.start : 1;
|
|
40
|
+
let sectionStartPending = true;
|
|
38
41
|
const pages = [];
|
|
39
42
|
const states = [];
|
|
40
43
|
function getContentBottom() {
|
|
@@ -48,7 +51,7 @@ function createPaginator(options) {
|
|
|
48
51
|
}
|
|
49
52
|
function currentPageUsesActiveLayout(state) {
|
|
50
53
|
if (pendingPageSize || pendingMargins) return false;
|
|
51
|
-
return arePageSizesEqual(state.page.size, pageSize) && areMarginsEqual(state.page.margins, getPageMargins(state.page.number, state.page.
|
|
54
|
+
return arePageSizesEqual(state.page.size, pageSize) && areMarginsEqual(state.page.margins, getPageMargins(state.page.number, state.page.logicalNumber));
|
|
52
55
|
}
|
|
53
56
|
if (getContentHeight() <= 0) panic("Paginator: page size and margins yield no content area");
|
|
54
57
|
let columnWidths = calculateColumnWidths(pageSize.w, margins.left, margins.right, columns);
|
|
@@ -63,8 +66,8 @@ function createPaginator(options) {
|
|
|
63
66
|
if (getContentHeight() <= 0) panic("Paginator: section page size and margins yield no content area");
|
|
64
67
|
recalculateColumnWidths();
|
|
65
68
|
}
|
|
66
|
-
function getPageMargins(pageNumber,
|
|
67
|
-
const evenMargins =
|
|
69
|
+
function getPageMargins(pageNumber, logicalPageNumber) {
|
|
70
|
+
const evenMargins = logicalPageNumber % 2 === 0 ? options.sectionEvenPageMargins?.[currentSectionIndex] : void 0;
|
|
68
71
|
const pageMargins = pageNumber === 1 && options.firstPageMargins ? { ...options.firstPageMargins } : { ...evenMargins ?? margins };
|
|
69
72
|
if (options.mirrorMargins === true && pageNumber % 2 === 0) return {
|
|
70
73
|
...pageMargins,
|
|
@@ -79,7 +82,7 @@ function createPaginator(options) {
|
|
|
79
82
|
* Get X position for a given column index.
|
|
80
83
|
*/
|
|
81
84
|
function getColumnX(columnIndex) {
|
|
82
|
-
let x = states.at(-1)?.page.margins.left ?? getPageMargins(1,
|
|
85
|
+
let x = states.at(-1)?.page.margins.left ?? getPageMargins(1, nextLogicalPageNumber).left;
|
|
83
86
|
for (let index = 0; index < columnIndex; index++) x += (columnWidths[index] ?? columnWidths[0] ?? 0) + gapAfterColumn(columns, index);
|
|
84
87
|
return x;
|
|
85
88
|
}
|
|
@@ -89,14 +92,19 @@ function createPaginator(options) {
|
|
|
89
92
|
function createNewPage() {
|
|
90
93
|
if (pendingPageSize || pendingMargins) applyPendingLayout();
|
|
91
94
|
const pageNumber = pages.length + 1;
|
|
95
|
+
const logicalNumber = nextLogicalPageNumber;
|
|
96
|
+
nextLogicalPageNumber += 1;
|
|
97
|
+
sectionStartPending = false;
|
|
92
98
|
currentSectionPageNumber += 1;
|
|
93
|
-
const pageMargins = getPageMargins(pageNumber,
|
|
99
|
+
const pageMargins = getPageMargins(pageNumber, logicalNumber);
|
|
94
100
|
const topMargin = pageMargins.top;
|
|
95
101
|
const contentBottom = pageSize.h - pageMargins.bottom;
|
|
96
102
|
const footnoteHeight = options.footnoteReservedHeights?.get(pageNumber) ?? 0;
|
|
97
103
|
const pageContentBottom = contentBottom - footnoteHeight;
|
|
98
104
|
const page = {
|
|
99
105
|
number: pageNumber,
|
|
106
|
+
logicalNumber,
|
|
107
|
+
...currentPageNumbering.format === void 0 ? {} : { logicalNumberFormat: currentPageNumbering.format },
|
|
100
108
|
fragments: [],
|
|
101
109
|
margins: pageMargins,
|
|
102
110
|
size: { ...pageSize },
|
|
@@ -236,12 +244,12 @@ function createPaginator(options) {
|
|
|
236
244
|
*/
|
|
237
245
|
function forcePageBreak(breakOptions = {}) {
|
|
238
246
|
const current = states.at(-1);
|
|
239
|
-
if (breakOptions.coalesceBlankPage && current && current.page.fragments.length === 0 && current.cursorY === current.topMargin
|
|
247
|
+
if (breakOptions.coalesceBlankPage && current && current.page.fragments.length === 0 && current.cursorY === current.topMargin) {
|
|
240
248
|
if (current.page.sectionIndex !== currentSectionIndex) {
|
|
241
|
-
|
|
242
|
-
|
|
249
|
+
retargetCurrentBlankPage();
|
|
250
|
+
return current;
|
|
243
251
|
}
|
|
244
|
-
return current;
|
|
252
|
+
if (currentPageUsesActiveLayout(current)) return current;
|
|
245
253
|
}
|
|
246
254
|
return createNewPage();
|
|
247
255
|
}
|
|
@@ -249,7 +257,8 @@ function createPaginator(options) {
|
|
|
249
257
|
const current = states.at(-1);
|
|
250
258
|
if (!current || current.page.fragments.length > 0 || current.cursorY !== current.topMargin) return false;
|
|
251
259
|
if (pendingPageSize || pendingMargins) applyPendingLayout();
|
|
252
|
-
|
|
260
|
+
retargetSectionMetadata(current.page);
|
|
261
|
+
const pageMargins = getPageMargins(current.page.number, current.page.logicalNumber);
|
|
253
262
|
const topMargin = pageMargins.top;
|
|
254
263
|
const rawContentBottom = pageSize.h - pageMargins.bottom;
|
|
255
264
|
const footnoteHeight = options.footnoteReservedHeights?.get(current.page.number) ?? 0;
|
|
@@ -267,8 +276,6 @@ function createPaginator(options) {
|
|
|
267
276
|
current.contentBottom = rawContentBottom - footnoteHeight;
|
|
268
277
|
current.trailingSpacing = 0;
|
|
269
278
|
columnRegionTop = topMargin;
|
|
270
|
-
currentSectionPageNumber = 1;
|
|
271
|
-
applySectionMetadata(current.page);
|
|
272
279
|
return true;
|
|
273
280
|
}
|
|
274
281
|
/**
|
|
@@ -310,9 +317,23 @@ function createPaginator(options) {
|
|
|
310
317
|
pendingPageSize = void 0;
|
|
311
318
|
pendingMargins = void 0;
|
|
312
319
|
}
|
|
313
|
-
function startSection(sectionIndex) {
|
|
320
|
+
function startSection(sectionIndex, pageNumbering = { type: "continue" }) {
|
|
314
321
|
currentSectionIndex = sectionIndex;
|
|
315
322
|
currentSectionPageNumber = 0;
|
|
323
|
+
currentPageNumbering = pageNumbering;
|
|
324
|
+
sectionStartPending = true;
|
|
325
|
+
if (pageNumbering.type === "restart") nextLogicalPageNumber = pageNumbering.start;
|
|
326
|
+
}
|
|
327
|
+
function retargetSectionMetadata(page) {
|
|
328
|
+
currentSectionPageNumber = 1;
|
|
329
|
+
if (sectionStartPending && currentPageNumbering.type === "restart") {
|
|
330
|
+
page.logicalNumber = currentPageNumbering.start;
|
|
331
|
+
nextLogicalPageNumber = currentPageNumbering.start + 1;
|
|
332
|
+
}
|
|
333
|
+
sectionStartPending = false;
|
|
334
|
+
if (currentPageNumbering.format === void 0) delete page.logicalNumberFormat;
|
|
335
|
+
else page.logicalNumberFormat = currentPageNumbering.format;
|
|
336
|
+
applySectionMetadata(page);
|
|
316
337
|
}
|
|
317
338
|
function applySectionMetadata(page) {
|
|
318
339
|
page.sectionIndex = currentSectionIndex;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { OutlineStyleAttr } from "../types/documentEnumValues.js";
|
|
2
2
|
import { ImagePosition, ImageWrap, SdtProperties, SdtType, ShapeTextBody, TableCellFormatting, TableWidthType } from "@stll/docx-core/model";
|
|
3
3
|
declare namespace types_d_exports {
|
|
4
|
-
export { BlockId, BorderStyle, CellBorderSpec, CellBorders, ColumnBreakBlock, ColumnBreakMeasure, ColumnLayout, DEFAULT_TEXTBOX_MARGINS, DEFAULT_TEXTBOX_WIDTH, DocumentPosition, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, FieldRun, FloatingTablePosition, FlowBlock, FootnoteContent, Fragment, FragmentBase, HeaderFooterContent, HeaderFooterContentHeights, HeaderFooterLayout, HitTestResult, HyperlinkInfo, ImageBlock, ImageFragment, ImageMeasure, ImageRun, ImageRunPosition, Layout, LayoutOptions, LineBreakRun, ListNumPr, MathRun, Measure, MeasuredLine, Page, PageBreakBlock, PageBreakMeasure, PageHeaderFooterRefs, PageMargins, ParagraphAttrs, ParagraphBlock, ParagraphBorders, ParagraphFragment, ParagraphIndent, ParagraphMeasure, ParagraphSpacing, RenderedPageBreakRun, Run, RunFormatting, SdtGroup, SectionBreakBlock, SectionBreakMeasure, TabAlignment, TabRun, TabStop, TableBlock, TableCell, TableCellMeasure, TableFragment, TableMeasure, TableRow, TableRowMeasure, TextBoxBlock, TextBoxFlowAttrs, TextBoxFragment, TextBoxMeasure, TextRun, floatingTextBoxReservesBand, floatingTextBoxWrapsText, getTableRowLeadingWidth, isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun, tableColumnsArePinned };
|
|
4
|
+
export { BlockId, BorderStyle, CellBorderSpec, CellBorders, ColumnBreakBlock, ColumnBreakMeasure, ColumnLayout, DEFAULT_TEXTBOX_MARGINS, DEFAULT_TEXTBOX_WIDTH, DocumentPosition, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, FieldRun, FloatingTablePosition, FlowBlock, FootnoteContent, Fragment, FragmentBase, HeaderFooterContent, HeaderFooterContentHeights, HeaderFooterLayout, HitTestResult, HyperlinkInfo, ImageBlock, ImageFragment, ImageMeasure, ImageRun, ImageRunPosition, Layout, LayoutOptions, LineBreakRun, ListNumPr, MathRun, Measure, MeasuredLine, Page, PageBreakBlock, PageBreakMeasure, PageHeaderFooterRefs, PageMargins, ParagraphAttrs, ParagraphBlock, ParagraphBorders, ParagraphFragment, ParagraphIndent, ParagraphMeasure, ParagraphSpacing, RenderedPageBreakRun, Run, RunFormatting, SdtGroup, SectionBreakBlock, SectionBreakMeasure, SectionPageNumbering, TabAlignment, TabRun, TabStop, TableBlock, TableCell, TableCellMeasure, TableFragment, TableMeasure, TableRow, TableRowMeasure, TextBoxBlock, TextBoxFlowAttrs, TextBoxFragment, TextBoxMeasure, TextRun, floatingTextBoxReservesBand, floatingTextBoxWrapsText, getTableRowLeadingWidth, isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun, tableColumnsArePinned };
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
7
7
|
* Unique identifier for a block in the document.
|
|
@@ -46,6 +46,14 @@ type RunFormatting = {
|
|
|
46
46
|
* does NOT do and is why this slot has to reach layout at all.
|
|
47
47
|
*/
|
|
48
48
|
complexScriptFontFamily?: string;
|
|
49
|
+
/** Independent complex-script size (`w:szCs`), in points. */
|
|
50
|
+
complexScriptFontSize?: number;
|
|
51
|
+
/** Independent complex-script weight (`w:bCs`). */
|
|
52
|
+
complexScriptBold?: boolean;
|
|
53
|
+
/** Independent complex-script slant (`w:iCs`). */
|
|
54
|
+
complexScriptItalic?: boolean;
|
|
55
|
+
/** Force the complex-script formatting slot for every character (`w:cs`). */
|
|
56
|
+
forceComplexScript?: boolean;
|
|
49
57
|
/** Run language metadata resolved from `w:lang`. */
|
|
50
58
|
language?: {
|
|
51
59
|
val?: string;
|
|
@@ -689,9 +697,20 @@ type SectionBreakBlock = {
|
|
|
689
697
|
orientation?: "portrait" | "landscape";
|
|
690
698
|
margins?: PageMargins;
|
|
691
699
|
columns?: ColumnLayout;
|
|
700
|
+
/** Authored page-number continuation or restart policy for the section ending here. */
|
|
701
|
+
pageNumbering?: SectionPageNumbering;
|
|
692
702
|
/** Line pitch authored by the section properties that end at this boundary, in twips. */
|
|
693
703
|
documentGridLinePitchTwips?: number;
|
|
694
704
|
};
|
|
705
|
+
/** Normalized section page-number policy. An omitted OOXML start continues numbering. */
|
|
706
|
+
type SectionPageNumbering = {
|
|
707
|
+
type: "continue";
|
|
708
|
+
format?: string;
|
|
709
|
+
} | {
|
|
710
|
+
type: "restart";
|
|
711
|
+
start: number;
|
|
712
|
+
format?: string;
|
|
713
|
+
};
|
|
695
714
|
type PageHeaderFooterRefs = {
|
|
696
715
|
titlePg?: boolean;
|
|
697
716
|
evenAndOddHeaders?: boolean;
|
|
@@ -1057,8 +1076,12 @@ type PageMargins = {
|
|
|
1057
1076
|
* A rendered page containing positioned fragments.
|
|
1058
1077
|
*/
|
|
1059
1078
|
type Page = {
|
|
1060
|
-
/**
|
|
1079
|
+
/** Physical page number (1-indexed), used for navigation and page counts. */
|
|
1061
1080
|
number: number;
|
|
1081
|
+
/** Authored page number shown by PAGE fields. */
|
|
1082
|
+
logicalNumber: number;
|
|
1083
|
+
/** OOXML number format for this page's section. */
|
|
1084
|
+
logicalNumberFormat?: string;
|
|
1062
1085
|
/** Fragments positioned on this page. */
|
|
1063
1086
|
fragments: Fragment[];
|
|
1064
1087
|
/** Page margins. */
|
|
@@ -1167,8 +1190,10 @@ type LayoutOptions = {
|
|
|
1167
1190
|
* same extension.
|
|
1168
1191
|
*/
|
|
1169
1192
|
firstPageMargins?: PageMargins;
|
|
1170
|
-
/** Per-section body margins used on even
|
|
1193
|
+
/** Per-section body margins used on even authored page numbers. */
|
|
1171
1194
|
sectionEvenPageMargins?: (PageMargins | undefined)[];
|
|
1195
|
+
/** Page-number policy for the initial section. */
|
|
1196
|
+
pageNumbering?: SectionPageNumbering;
|
|
1172
1197
|
/** Body-level final section page size. */
|
|
1173
1198
|
finalPageSize?: {
|
|
1174
1199
|
w: number;
|
|
@@ -1178,6 +1203,8 @@ type LayoutOptions = {
|
|
|
1178
1203
|
finalMargins?: PageMargins;
|
|
1179
1204
|
/** Body-level final section column configuration. */
|
|
1180
1205
|
finalColumns?: ColumnLayout;
|
|
1206
|
+
/** Body-level final section page-number policy. */
|
|
1207
|
+
finalPageNumbering?: SectionPageNumbering;
|
|
1181
1208
|
/** Column configuration. */
|
|
1182
1209
|
columns?: ColumnLayout;
|
|
1183
1210
|
/** Gap between rendered pages (for UI). */
|
|
@@ -1353,4 +1380,4 @@ declare function tableColumnsArePinned(table: TableBlock): boolean;
|
|
|
1353
1380
|
/** Return the leading visual offset for a row with omitted grid columns. */
|
|
1354
1381
|
declare const getTableRowLeadingWidth: (row: TableRow, columnWidths: readonly number[]) => number;
|
|
1355
1382
|
//#endregion
|
|
1356
|
-
export { BlockId, BorderStyle, CellBorderSpec, CellBorders, ColumnBreakBlock, ColumnBreakMeasure, ColumnLayout, DEFAULT_TEXTBOX_MARGINS, DEFAULT_TEXTBOX_WIDTH, DocumentPosition, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, FieldRun, FloatingTablePosition, FlowBlock, FootnoteContent, Fragment, FragmentBase, HeaderFooterContent, HeaderFooterContentHeights, HeaderFooterLayout, HitTestResult, HyperlinkInfo, ImageBlock, ImageFragment, ImageMeasure, ImageRun, ImageRunPosition, Layout, LayoutOptions, LineBreakRun, ListNumPr, MathRun, Measure, MeasuredLine, Page, PageBreakBlock, PageBreakMeasure, PageHeaderFooterRefs, PageMargins, ParagraphAttrs, ParagraphBlock, ParagraphBorders, ParagraphFragment, ParagraphIndent, ParagraphMeasure, ParagraphSpacing, RenderedPageBreakRun, Run, RunFormatting, SdtGroup, SectionBreakBlock, SectionBreakMeasure, TabAlignment, TabRun, TabStop, TableBlock, TableCell, TableCellMeasure, TableFragment, TableMeasure, TableRow, TableRowMeasure, TextBoxBlock, TextBoxFlowAttrs, TextBoxFragment, TextBoxMeasure, TextRun, floatingTextBoxReservesBand, floatingTextBoxWrapsText, getTableRowLeadingWidth, isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun, tableColumnsArePinned, types_d_exports };
|
|
1383
|
+
export { BlockId, BorderStyle, CellBorderSpec, CellBorders, ColumnBreakBlock, ColumnBreakMeasure, ColumnLayout, DEFAULT_TEXTBOX_MARGINS, DEFAULT_TEXTBOX_WIDTH, DocumentPosition, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, FieldRun, FloatingTablePosition, FlowBlock, FootnoteContent, Fragment, FragmentBase, HeaderFooterContent, HeaderFooterContentHeights, HeaderFooterLayout, HitTestResult, HyperlinkInfo, ImageBlock, ImageFragment, ImageMeasure, ImageRun, ImageRunPosition, Layout, LayoutOptions, LineBreakRun, ListNumPr, MathRun, Measure, MeasuredLine, Page, PageBreakBlock, PageBreakMeasure, PageHeaderFooterRefs, PageMargins, ParagraphAttrs, ParagraphBlock, ParagraphBorders, ParagraphFragment, ParagraphIndent, ParagraphMeasure, ParagraphSpacing, RenderedPageBreakRun, Run, RunFormatting, SdtGroup, SectionBreakBlock, SectionBreakMeasure, SectionPageNumbering, TabAlignment, TabRun, TabStop, TableBlock, TableCell, TableCellMeasure, TableFragment, TableMeasure, TableRow, TableRowMeasure, TextBoxBlock, TextBoxFlowAttrs, TextBoxFragment, TextBoxMeasure, TextRun, floatingTextBoxReservesBand, floatingTextBoxWrapsText, getTableRowLeadingWidth, isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun, tableColumnsArePinned, types_d_exports };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FlowBlock, Measure } from "../layout-engine/types.js";
|
|
2
|
+
import { ImageAttrs } from "../prosemirror/schema/nodes.js";
|
|
2
3
|
import { BlockLookup } from "./index.js";
|
|
3
4
|
import { WrapType } from "../docx/wrapTypes.js";
|
|
4
|
-
import { ImageAttrs } from "../prosemirror/schema/nodes.js";
|
|
5
5
|
//#region src/layout-painter/imageLayout.d.ts
|
|
6
6
|
/**
|
|
7
7
|
* Anchored wrap-type targets — the OOXML wrap types except `inline`.
|
|
@@ -81,7 +81,8 @@ var LayoutPainter = class {
|
|
|
81
81
|
for (const i_item of pages) {
|
|
82
82
|
const page = i_item;
|
|
83
83
|
const context = {
|
|
84
|
-
pageNumber: page.
|
|
84
|
+
pageNumber: page.logicalNumber,
|
|
85
|
+
...page.logicalNumberFormat === void 0 ? {} : { pageNumberFormat: page.logicalNumberFormat },
|
|
85
86
|
totalPages: this.totalPages,
|
|
86
87
|
section: "body"
|
|
87
88
|
};
|
|
@@ -601,6 +601,7 @@ function renderFootnoteContent(footnote, contentWidth, doc, context) {
|
|
|
601
601
|
wrapper.style.height = `${content.height}px`;
|
|
602
602
|
const renderContext = {
|
|
603
603
|
pageNumber: context?.pageNumber ?? 0,
|
|
604
|
+
...context?.pageNumberFormat === void 0 ? {} : { pageNumberFormat: context.pageNumberFormat },
|
|
604
605
|
totalPages: context?.totalPages ?? 0,
|
|
605
606
|
section: context?.section ?? "body",
|
|
606
607
|
contentWidth
|
|
@@ -1133,8 +1134,7 @@ function applySectionHeaderFooterOptions(page, pageOptions, options) {
|
|
|
1133
1134
|
if (!refs) return false;
|
|
1134
1135
|
const isFirstSectionPage = page.sectionPageNumber === 1;
|
|
1135
1136
|
const useFirst = refs.titlePg === true && isFirstSectionPage;
|
|
1136
|
-
const
|
|
1137
|
-
const useEven = refs.evenAndOddHeaders === true && sectionPageNumber % 2 === 0;
|
|
1137
|
+
const useEven = refs.evenAndOddHeaders === true && page.logicalNumber % 2 === 0;
|
|
1138
1138
|
const headerRId = (() => {
|
|
1139
1139
|
if (useFirst) return refs.headerFirst;
|
|
1140
1140
|
if (useEven) return refs.headerEven;
|
|
@@ -1176,7 +1176,8 @@ function sectionPagesContext(page, counts) {
|
|
|
1176
1176
|
*/
|
|
1177
1177
|
function buildPageRenderArgs(page, totalPages, options) {
|
|
1178
1178
|
const context = {
|
|
1179
|
-
pageNumber: page.
|
|
1179
|
+
pageNumber: page.logicalNumber,
|
|
1180
|
+
...page.logicalNumberFormat === void 0 ? {} : { pageNumberFormat: page.logicalNumberFormat },
|
|
1180
1181
|
totalPages,
|
|
1181
1182
|
section: "body",
|
|
1182
1183
|
...options.bookmarkPages ? { bookmarkPages: options.bookmarkPages } : {},
|
|
@@ -1224,6 +1225,7 @@ function computePageFingerprintInternal(page, blockLookup, options) {
|
|
|
1224
1225
|
parts.push(`m:${pageMarginsFingerprint(page.margins)}`);
|
|
1225
1226
|
if (page.authoredMargins) parts.push(`am:${pageMarginsFingerprint(page.authoredMargins)}`);
|
|
1226
1227
|
parts.push(`n:${page.number}`);
|
|
1228
|
+
parts.push(`ln:${page.logicalNumber},${page.logicalNumberFormat ?? ""}`);
|
|
1227
1229
|
if (page.sectionIndex !== void 0) parts.push(`si:${page.sectionIndex}`);
|
|
1228
1230
|
if (page.sectionPageNumber !== void 0) parts.push(`sp:${page.sectionPageNumber}`);
|
|
1229
1231
|
if (page.headerFooterRefs) parts.push(`hf:${JSON.stringify(page.headerFooterRefs)}`);
|
|
@@ -1334,6 +1336,10 @@ function runContentKey(run) {
|
|
|
1334
1336
|
if (run.highlight) parts.push(`hi:${run.highlight}`);
|
|
1335
1337
|
if (run.fontFamily) parts.push(`ff:${run.fontFamily}`);
|
|
1336
1338
|
if (run.complexScriptFontFamily) parts.push(`cs:${run.complexScriptFontFamily}`);
|
|
1339
|
+
if (run.complexScriptFontSize !== void 0) parts.push(`cs-size:${run.complexScriptFontSize}`);
|
|
1340
|
+
if (run.complexScriptBold !== void 0) parts.push(`cs-bold:${run.complexScriptBold}`);
|
|
1341
|
+
if (run.complexScriptItalic !== void 0) parts.push(`cs-italic:${run.complexScriptItalic}`);
|
|
1342
|
+
if (run.forceComplexScript !== void 0) parts.push(`cs-force:${run.forceComplexScript}`);
|
|
1337
1343
|
if (run.eastAsiaFontFamily) parts.push(`ea:${run.eastAsiaFontFamily}`);
|
|
1338
1344
|
if (run.fontSize !== void 0) parts.push(`fs:${run.fontSize}`);
|
|
1339
1345
|
if (run.letterSpacing !== void 0) parts.push(`ls:${run.letterSpacing}`);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ommlToMathml } from "../docx/mathToMathml.js";
|
|
2
2
|
import { parseXmlDocument } from "../docx/xmlParser.js";
|
|
3
3
|
import { evaluateFieldInstruction } from "../fields/evaluateField.js";
|
|
4
|
+
import { hasComplexScriptFormatting, resolveComplexScriptFormatting } from "../layout-engine/measure/complexScriptFormatting.js";
|
|
4
5
|
import { getListMarkerInlineWidth, getListMarkerVisualOffset } from "../layout-engine/measure/listMarkerWidth.js";
|
|
5
6
|
import { DOCX_SCRIPT_FONT_SCALE } from "../layout-engine/measure/measureHelpers.js";
|
|
6
7
|
import { FONT_KERNING_MODE, countCompressibleSpaces, getFontKerningMode, getRunFontKerningMode, toPaintedText } from "../layout-engine/measure/textMeasurementPolicy.js";
|
|
@@ -571,6 +572,7 @@ function resolveFieldText(run, context) {
|
|
|
571
572
|
if (!context) return fallback;
|
|
572
573
|
const fieldContext = {
|
|
573
574
|
pageNumber: context.pageNumber,
|
|
575
|
+
...context.pageNumberFormat === void 0 ? {} : { pageNumberFormat: context.pageNumberFormat },
|
|
574
576
|
totalPages: context.totalPages,
|
|
575
577
|
bookmarkPages: context.bookmarkPages ?? EMPTY_BOOKMARK_PAGES,
|
|
576
578
|
bookmarkText: context.bookmarkText ?? EMPTY_BOOKMARK_TEXT,
|
|
@@ -591,6 +593,10 @@ function renderFieldRun(run, doc, context) {
|
|
|
591
593
|
kind: "text",
|
|
592
594
|
text
|
|
593
595
|
};
|
|
596
|
+
if (resolvedRun.forceComplexScript && hasComplexScriptFormatting(resolvedRun)) return renderTextRun({
|
|
597
|
+
...resolvedRun,
|
|
598
|
+
...resolveComplexScriptFormatting(resolvedRun)
|
|
599
|
+
}, doc);
|
|
594
600
|
if (needsPerScriptSpans({
|
|
595
601
|
...resolvedRun,
|
|
596
602
|
text
|
|
@@ -607,7 +613,7 @@ function renderFieldRun(run, doc, context) {
|
|
|
607
613
|
const segmentRun = {
|
|
608
614
|
...segmentBase,
|
|
609
615
|
text: segment.text,
|
|
610
|
-
...
|
|
616
|
+
...scriptFormattingOverride(resolvedRun, segment.script)
|
|
611
617
|
};
|
|
612
618
|
wrapper.append(renderTextRun(segmentRun, doc));
|
|
613
619
|
}
|
|
@@ -725,9 +731,9 @@ function sliceRunsForLine(block, line) {
|
|
|
725
731
|
* The font a script segment paints with, mirroring the measurer's
|
|
726
732
|
* `scriptFontFamily`. Returning undefined leaves the run's own `fontFamily`.
|
|
727
733
|
*/
|
|
728
|
-
const
|
|
734
|
+
const scriptFormattingOverride = (run, script) => {
|
|
735
|
+
if (run.forceComplexScript || script === SCRIPT_CLASS.complex) return resolveComplexScriptFormatting(run);
|
|
729
736
|
if (script === SCRIPT_CLASS.eastAsia && run.eastAsiaFontFamily !== void 0) return { fontFamily: run.eastAsiaFontFamily };
|
|
730
|
-
if (script === SCRIPT_CLASS.complex && run.complexScriptFontFamily !== void 0) return { fontFamily: run.complexScriptFontFamily };
|
|
731
737
|
return {};
|
|
732
738
|
};
|
|
733
739
|
/**
|
|
@@ -739,7 +745,7 @@ const scriptFontOverride = (run, script) => {
|
|
|
739
745
|
const needsPerScriptSpans = (run) => {
|
|
740
746
|
if (run.letterSpacing) return false;
|
|
741
747
|
if (run.eastAsiaFontFamily !== void 0 && hasCjk(run.text)) return true;
|
|
742
|
-
return run
|
|
748
|
+
return hasComplexScriptFormatting(run) && hasComplexScript(run.text);
|
|
743
749
|
};
|
|
744
750
|
/**
|
|
745
751
|
* Split each text run carrying an East-Asian font into per-script sub-runs, so
|
|
@@ -753,6 +759,13 @@ const needsPerScriptSpans = (run) => {
|
|
|
753
759
|
function splitTextRunsByEastAsia(runs) {
|
|
754
760
|
const result = [];
|
|
755
761
|
for (const run of runs) {
|
|
762
|
+
if (isTextRun(run) && run.forceComplexScript && hasComplexScriptFormatting(run)) {
|
|
763
|
+
result.push({
|
|
764
|
+
...run,
|
|
765
|
+
...resolveComplexScriptFormatting(run)
|
|
766
|
+
});
|
|
767
|
+
continue;
|
|
768
|
+
}
|
|
756
769
|
if (!isTextRun(run) || !needsPerScriptSpans(run)) {
|
|
757
770
|
result.push(run);
|
|
758
771
|
continue;
|
|
@@ -762,7 +775,7 @@ function splitTextRunsByEastAsia(runs) {
|
|
|
762
775
|
result.push({
|
|
763
776
|
...run,
|
|
764
777
|
text: segment.text,
|
|
765
|
-
...
|
|
778
|
+
...scriptFormattingOverride(run, segment.script),
|
|
766
779
|
...run.pmStart !== void 0 ? {
|
|
767
780
|
pmStart: run.pmStart + offset,
|
|
768
781
|
pmEnd: run.pmStart + offset + segment.text.length
|
|
@@ -866,6 +879,10 @@ function runMeasureStyle(run) {
|
|
|
866
879
|
...run.smallCaps !== void 0 ? { smallCaps: run.smallCaps } : {},
|
|
867
880
|
...run.eastAsiaFontFamily !== void 0 ? { eastAsiaFontFamily: run.eastAsiaFontFamily } : {},
|
|
868
881
|
...run.complexScriptFontFamily !== void 0 ? { complexScriptFontFamily: run.complexScriptFontFamily } : {},
|
|
882
|
+
...run.complexScriptFontSize !== void 0 ? { complexScriptFontSize: run.complexScriptFontSize } : {},
|
|
883
|
+
...run.complexScriptBold !== void 0 ? { complexScriptBold: run.complexScriptBold } : {},
|
|
884
|
+
...run.complexScriptItalic !== void 0 ? { complexScriptItalic: run.complexScriptItalic } : {},
|
|
885
|
+
...run.forceComplexScript !== void 0 ? { forceComplexScript: run.forceComplexScript } : {},
|
|
869
886
|
kerning: getRunFontKerningMode(run, 11) === FONT_KERNING_MODE.enabled
|
|
870
887
|
};
|
|
871
888
|
}
|
|
@@ -972,27 +989,32 @@ function createTextMeasurer(doc) {
|
|
|
972
989
|
return (text, fontSize = 11, fontFamily = "Calibri", style = {}) => {
|
|
973
990
|
if (!ctx) return applyLetterSpacingToMeasuredWidth(text.length * 7, text, style.letterSpacing);
|
|
974
991
|
ctx.fontKerning = getFontKerningMode(style);
|
|
975
|
-
const
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
const fontPrefix = fontPrefixParts.join(" ");
|
|
983
|
-
const perScriptFallback = {
|
|
984
|
-
...style.eastAsiaFontFamily ? { [SCRIPT_CLASS.eastAsia]: resolveFontFamily(style.eastAsiaFontFamily).cssFallback } : {},
|
|
985
|
-
...style.complexScriptFontFamily ? { [SCRIPT_CLASS.complex]: resolveFontFamily(style.complexScriptFontFamily).cssFallback } : {}
|
|
992
|
+
const fontString = (family, size, bold, italic) => {
|
|
993
|
+
const fontPrefixParts = [];
|
|
994
|
+
if (italic) fontPrefixParts.push("italic");
|
|
995
|
+
if (style.smallCaps) fontPrefixParts.push("small-caps");
|
|
996
|
+
if (bold) fontPrefixParts.push("700");
|
|
997
|
+
fontPrefixParts.push(`${size * 96 / 72}px`);
|
|
998
|
+
return `${fontPrefixParts.join(" ")} ${resolveFontFamily(family).cssFallback}`;
|
|
986
999
|
};
|
|
987
|
-
|
|
1000
|
+
const baseFont = fontString(fontFamily, fontSize, style.bold, style.italic);
|
|
1001
|
+
const complex = resolveComplexScriptFormatting(style);
|
|
1002
|
+
const complexFont = fontString(complex.fontFamily ?? fontFamily, complex.fontSize ?? fontSize, complex.bold ?? style.bold, complex.italic ?? style.italic);
|
|
1003
|
+
if (style.forceComplexScript) {
|
|
1004
|
+
ctx.font = complexFont;
|
|
1005
|
+
return applyLetterSpacingToMeasuredWidth(ctx.measureText(text).width, text, style.letterSpacing);
|
|
1006
|
+
}
|
|
1007
|
+
if (!style.letterSpacing && (style.eastAsiaFontFamily && hasCjk(text) || hasComplexScriptFormatting(style) && hasComplexScript(text))) {
|
|
988
1008
|
let segmentedWidth = 0;
|
|
989
1009
|
for (const segment of segmentByScript(text)) {
|
|
990
|
-
ctx.font =
|
|
1010
|
+
if (segment.script === SCRIPT_CLASS.eastAsia && style.eastAsiaFontFamily) ctx.font = fontString(style.eastAsiaFontFamily, fontSize, style.bold, style.italic);
|
|
1011
|
+
else if (segment.script === SCRIPT_CLASS.complex) ctx.font = complexFont;
|
|
1012
|
+
else ctx.font = baseFont;
|
|
991
1013
|
segmentedWidth += ctx.measureText(segment.text).width;
|
|
992
1014
|
}
|
|
993
1015
|
return segmentedWidth;
|
|
994
1016
|
}
|
|
995
|
-
ctx.font =
|
|
1017
|
+
ctx.font = baseFont;
|
|
996
1018
|
return applyLetterSpacingToMeasuredWidth(ctx.measureText(text).width, text, style.letterSpacing);
|
|
997
1019
|
};
|
|
998
1020
|
}
|
|
@@ -1180,12 +1202,7 @@ function renderLine(block, line, alignment, doc, options) {
|
|
|
1180
1202
|
if (!measureText) continue;
|
|
1181
1203
|
const fontSize = run.fontSize || 11;
|
|
1182
1204
|
const fontFamily = run.fontFamily || "Calibri";
|
|
1183
|
-
const measuredWidth = measureText(run.allCaps ? run.text.toLocaleUpperCase() : run.text, fontSize, fontFamily,
|
|
1184
|
-
...run.bold !== void 0 ? { bold: run.bold } : {},
|
|
1185
|
-
...run.italic !== void 0 ? { italic: run.italic } : {},
|
|
1186
|
-
...run.letterSpacing !== void 0 ? { letterSpacing: run.letterSpacing } : {},
|
|
1187
|
-
...run.smallCaps !== void 0 ? { smallCaps: run.smallCaps } : {}
|
|
1188
|
-
});
|
|
1205
|
+
const measuredWidth = measureText(run.allCaps ? run.text.toLocaleUpperCase() : run.text, fontSize, fontFamily, runMeasureStyle(run));
|
|
1189
1206
|
reserveScaledAdvance(runEl, measuredWidth, run.horizontalScale);
|
|
1190
1207
|
currentX += measuredWidth * ((run.horizontalScale ?? 100) / 100);
|
|
1191
1208
|
} else if (isImageRun(run)) {
|
|
@@ -16,6 +16,8 @@ declare function resolveImageLineAlign(imageRun: ImageRun, paragraphAlignment: "
|
|
|
16
16
|
type RenderContext = {
|
|
17
17
|
/** Current page number (1-indexed) */
|
|
18
18
|
pageNumber: number;
|
|
19
|
+
/** OOXML section-level format for the current logical page number. */
|
|
20
|
+
pageNumberFormat?: string;
|
|
19
21
|
/** Total number of pages */
|
|
20
22
|
totalPages: number;
|
|
21
23
|
/** Which section is being rendered */
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Subscribable } from "./Subscribable.js";
|
|
2
|
+
import { decodeAutoSaveEnvelope, encodeAutoSaveDocument, encodeAutoSaveEnvelopeFromDocument } from "./autoSaveCodec.js";
|
|
2
3
|
//#region src/managers/AutoSaveManager.ts
|
|
3
4
|
const DEFAULT_STORAGE_KEY = "docx-editor-autosave";
|
|
4
5
|
const DEFAULT_INTERVAL = 3e4;
|
|
5
6
|
const DEFAULT_MAX_AGE = 1440 * 60 * 1e3;
|
|
6
7
|
const DEFAULT_DEBOUNCE_DELAY = 2e3;
|
|
7
|
-
const SAVE_VERSION = 1;
|
|
8
8
|
function isLocalStorageAvailable() {
|
|
9
9
|
try {
|
|
10
10
|
const testKey = "__docx_editor_test__";
|
|
@@ -16,31 +16,7 @@ function isLocalStorageAvailable() {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
function serializeForStorage(document) {
|
|
19
|
-
return
|
|
20
|
-
...document,
|
|
21
|
-
originalBuffer: null
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
function isDocumentLike(value) {
|
|
25
|
-
return typeof value === "object" && value !== null && "package" in value;
|
|
26
|
-
}
|
|
27
|
-
function parseSavedData(json) {
|
|
28
|
-
let parsed;
|
|
29
|
-
try {
|
|
30
|
-
parsed = JSON.parse(json);
|
|
31
|
-
} catch {
|
|
32
|
-
return null;
|
|
33
|
-
}
|
|
34
|
-
if (typeof parsed !== "object" || parsed === null) return null;
|
|
35
|
-
if (!("document" in parsed) || !("savedAt" in parsed) || !("version" in parsed)) return null;
|
|
36
|
-
const { document, savedAt, version } = parsed;
|
|
37
|
-
if (typeof savedAt !== "string" || typeof version !== "number") return null;
|
|
38
|
-
if (!isDocumentLike(document)) return null;
|
|
39
|
-
return {
|
|
40
|
-
document,
|
|
41
|
-
savedAt,
|
|
42
|
-
version
|
|
43
|
-
};
|
|
19
|
+
return encodeAutoSaveDocument(document);
|
|
44
20
|
}
|
|
45
21
|
function isStale(savedAt, maxAge) {
|
|
46
22
|
const savedTime = new Date(savedAt).getTime();
|
|
@@ -99,12 +75,12 @@ var AutoSaveManager = class extends Subscribable {
|
|
|
99
75
|
this.updateStatus("saving");
|
|
100
76
|
try {
|
|
101
77
|
const serialized = serializeForStorage(doc);
|
|
102
|
-
if (serialized === this.lastSavedJson) {
|
|
78
|
+
if (serialized.json === this.lastSavedJson) {
|
|
103
79
|
this.updateStatus("saved");
|
|
104
80
|
return true;
|
|
105
81
|
}
|
|
106
|
-
this.persistToStorage(
|
|
107
|
-
this.lastSavedJson = serialized;
|
|
82
|
+
this.persistToStorage(serialized);
|
|
83
|
+
this.lastSavedJson = serialized.json;
|
|
108
84
|
const saveTime = /* @__PURE__ */ new Date();
|
|
109
85
|
this.lastSaveTime = saveTime;
|
|
110
86
|
this.updateStatus("saved");
|
|
@@ -133,7 +109,7 @@ var AutoSaveManager = class extends Subscribable {
|
|
|
133
109
|
if (!this.storageAvailable) return null;
|
|
134
110
|
const savedJson = localStorage.getItem(this.storageKey);
|
|
135
111
|
if (!savedJson) return null;
|
|
136
|
-
const savedData =
|
|
112
|
+
const savedData = decodeAutoSaveEnvelope(savedJson);
|
|
137
113
|
if (!savedData) return null;
|
|
138
114
|
if (isStale(savedData.savedAt, this.maxAge)) {
|
|
139
115
|
this.clear();
|
|
@@ -179,7 +155,7 @@ var AutoSaveManager = class extends Subscribable {
|
|
|
179
155
|
destroy() {
|
|
180
156
|
this.stopTimers();
|
|
181
157
|
if (this.isEnabled && this.currentDocument && this.storageAvailable) try {
|
|
182
|
-
this.persistToStorage(this.currentDocument);
|
|
158
|
+
this.persistToStorage(serializeForStorage(this.currentDocument));
|
|
183
159
|
} catch (error) {
|
|
184
160
|
this.onErrorCallback?.(error instanceof Error ? error : new Error(String(error)));
|
|
185
161
|
}
|
|
@@ -194,15 +170,7 @@ var AutoSaveManager = class extends Subscribable {
|
|
|
194
170
|
}
|
|
195
171
|
}
|
|
196
172
|
persistToStorage(document) {
|
|
197
|
-
|
|
198
|
-
document: {
|
|
199
|
-
...document,
|
|
200
|
-
originalBuffer: null
|
|
201
|
-
},
|
|
202
|
-
savedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
203
|
-
version: SAVE_VERSION
|
|
204
|
-
};
|
|
205
|
-
localStorage.setItem(this.storageKey, JSON.stringify(dataToSave));
|
|
173
|
+
localStorage.setItem(this.storageKey, encodeAutoSaveEnvelopeFromDocument(document, (/* @__PURE__ */ new Date()).toISOString()));
|
|
206
174
|
}
|
|
207
175
|
debounceSave() {
|
|
208
176
|
if (this.debounceTimer) clearTimeout(this.debounceTimer);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
import { TableAction, TableContext } from "../utils/tableOperations.js";
|
|
2
3
|
import { Subscribable } from "./Subscribable.js";
|
|
3
4
|
import { CellCoordinates } from "./types.js";
|
|
4
|
-
import { TableAction, TableContext } from "../utils/tableOperations.js";
|
|
5
5
|
//#region src/managers/TableSelectionManager.d.ts
|
|
6
6
|
/** Data attributes for table elements in the rendered DOM */
|
|
7
7
|
declare const TABLE_DATA_ATTRIBUTES: {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
//#region src/managers/autoSaveCodec.d.ts
|
|
3
|
+
declare const AUTOSAVE_FORMAT_VERSION = 2;
|
|
4
|
+
type DecodedAutoSave = {
|
|
5
|
+
document: document_d_exports.Document;
|
|
6
|
+
savedAt: string;
|
|
7
|
+
version: typeof AUTOSAVE_FORMAT_VERSION;
|
|
8
|
+
};
|
|
9
|
+
type EncodedAutoSaveDocument = {
|
|
10
|
+
json: string;
|
|
11
|
+
};
|
|
12
|
+
declare const encodeAutoSaveDocument: (document: document_d_exports.Document) => EncodedAutoSaveDocument;
|
|
13
|
+
declare const encodeAutoSaveEnvelopeFromDocument: (document: EncodedAutoSaveDocument, savedAt: string) => string;
|
|
14
|
+
declare const encodeAutoSaveEnvelope: (document: document_d_exports.Document, savedAt: string) => string;
|
|
15
|
+
declare const decodeAutoSaveEnvelope: (json: string) => DecodedAutoSave | null;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { AUTOSAVE_FORMAT_VERSION, DecodedAutoSave, EncodedAutoSaveDocument, decodeAutoSaveEnvelope, encodeAutoSaveDocument, encodeAutoSaveEnvelope, encodeAutoSaveEnvelopeFromDocument };
|