oasis-editor 0.0.106 → 0.0.107

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.
Files changed (27) hide show
  1. package/dist/{OasisEditorApp-CwVZxG1m.js → OasisEditorApp-BFNqDc07.js} +685 -55
  2. package/dist/app/controllers/tableResize/tableResizeGeometry.d.ts +3 -2
  3. package/dist/app/controllers/tableResize/tableResizeHitTest.d.ts +3 -2
  4. package/dist/app/controllers/useEditorLayout.d.ts +2 -0
  5. package/dist/app/controllers/useEditorNavigation.d.ts +4 -1
  6. package/dist/app/controllers/useEditorTableResize.d.ts +5 -1
  7. package/dist/{index-DdcPkCmB.js → index-4uLtMJwI.js} +13706 -14175
  8. package/dist/layoutProjection/index.d.ts +1 -0
  9. package/dist/layoutProjection/layoutMetricsEpoch.d.ts +2 -0
  10. package/dist/oasis-editor.js +55 -55
  11. package/dist/oasis-editor.umd.cjs +4 -4
  12. package/dist/ui/OasisEditorEditor.d.ts +3 -2
  13. package/dist/ui/app/EditorDragLayers.d.ts +5 -1
  14. package/dist/ui/app/EditorWorkspace.d.ts +2 -1
  15. package/dist/ui/app/buildEditorViewProps.d.ts +2 -0
  16. package/dist/ui/app/createEditorDocumentRuntime.d.ts +2 -0
  17. package/dist/ui/app/createEditorInteractionRuntime.d.ts +2 -0
  18. package/dist/ui/app/useCanvasSurfaceHitResolver.d.ts +4 -3
  19. package/dist/ui/app/useEditorInteractionWiring.d.ts +2 -0
  20. package/dist/ui/canvas/canvasLayoutSnapshotProvider.d.ts +14 -0
  21. package/dist/ui/canvas/canvasSnapshotTypes.d.ts +2 -3
  22. package/dist/ui/canvas/canvasTextMeasurer.d.ts +3 -0
  23. package/dist/ui/components/DropCaret.d.ts +5 -1
  24. package/dist/ui/components/Outline/OutlinePanel.d.ts +5 -1
  25. package/dist/ui/editorUiTypes.d.ts +2 -1
  26. package/dist/ui/shells/DocumentShell.d.ts +3 -2
  27. package/package.json +1 -1
@@ -1,7 +1,458 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { v as visitRun, a as assertNever, c as createSignal, b as createEditorStateFromDocument, d as createInitialEditorState, S as STANDARD_FONT_SIZES_PT, f as fontSizePxToPt, p as probeLocalFontFamilies, e as createEditorParagraphFromRuns, i as isInlineObjectRun, g as createEditorStyledRun, h as getParagraphLength, j as getParagraphText, k as getActiveZone, l as getDocumentSections, m as getActiveSectionIndex, n as getParagraphs, o as normalizeSelection, q as positionToParagraphOffset, r as paragraphOffsetToPosition, s as clampPosition, t as findParagraphIndex, u as createCollapsedSelection, w as isSelectionCollapsed, x as parseFontSizePtToPx, y as formatFontSizePt, z as createEditorParagraph, A as getBlockParagraphs, B as findParagraphTableLocation, C as buildTableCellLayout, P as PT_PER_PX, D as createEditorTableCell, E as createEditorTableRow, F as createEditorTable, G as underlineStyleToCssDecorationStyle, H as resolveImageSrc, I as listKindForTag, J as isParagraphTag, K as collectInlineRuns, L as parseParagraphStyle, M as getRunImage, N as InlineShell, O as BalloonShell, Q as DocumentShell, R as createMemo, T as buildCanvasLayoutSnapshot, U as getCaretRectFromSnapshot, V as getParagraphRectFromSnapshot, W as createComponent, X as CaretOverlay, Y as Show, Z as createRenderEffect, _ as style, $ as setAttribute, a0 as setStyleProperty, a1 as memo, a2 as template, a3 as useI18n, a4 as createEffect, a5 as insert, a6 as use, a7 as addEventListener, a8 as Dialog, a9 as delegateEvents, aa as className, ab as For, ac as UNDERLINE_STYLE_OPTIONS, ad as Tabs, ae as onMount, af as onCleanup, ag as PluginUiHost, ah as OasisEditorEditor, ai as OasisBrandMark, aj as setPreciseFontPreference, ak as setWelcomeSeen, al as enablePreciseFontMode, am as TWIPS_PER_POINT, an as PX_PER_INCH, ao as TWIPS_PER_INCH, ap as resolveEffectiveParagraphStyle, aq as resolveEffectiveTextStyleForParagraph, ar as EMU_PER_PX, as as EMU_PER_PT, at as getRunFootnoteReference, au as getRunEndnoteReference, av as iterateFootnoteReferenceRuns, aw as iterateEndnoteReferenceRuns, ax as imageContentTypeDefaults, ay as getRunFieldChar, az as getRunFieldInstruction, aA as createEditorRun, aB as JSZip, aC as imageExtensionFromMime, aD as pxToPt$1, aE as resolveFloatingObjectRect, aF as getTextBoxFloatingGeometry, aG as getPresetPathSegments, aH as projectBlocksLayout, aI as buildListLabels, aJ as getImageFloatingGeometry, aK as textStyleToFontSizePt, aL as PX_PER_POINT, aM as resolveOpenTypeFeatureTags, aN as DEFAULT_FONT_SIZE_PX, aO as isDoubleUnderlineStyle, aP as isWavyUnderlineStyle, aQ as underlineStyleLineWidthPx, aR as underlineStyleDashArray, aS as resolveListLabel, aT as getListLabelInset, aU as getAlignedListLabelInset, aV as getParagraphBorderInsets, aW as buildSegmentTable, aX as buildCanvasTableLayout, aY as resolveCanvasTableWidth, aZ as resolveFloatingTableRect, a_ as normalizeFamily, a$ as ROBOTO_FONT_FILES, b0 as loadFontAsset, b1 as OFFICE_COMPAT_FONT_FAMILIES, b2 as BinaryReader, b3 as buildSfnt, b4 as defaultFontDecoderRegistry, b5 as SfntFontProgram, b6 as collectPdfFontFamilies, b7 as projectDocumentLayout, b8 as getPageContentWidth, b9 as getPageHeaderZoneTop, ba as getPageBodyTop, bb as getPageColumnRects, bc as findFootnoteReference, bd as FOOTNOTE_MARKER_GUTTER_PX, be as resolveImporterForFile, bf as getDocumentSectionsCanonical, bg as getDocumentParagraphsCanonical, bh as getDocumentParagraphs, bi as getDocumentPageSettings, bj as getTableCellContentWidthForParagraph, bk as on, bl as debounce, bm as unwrap, bn as perfTimer, bo as getRunTextBox, bp as createEditorDocument, bq as resolveResizedDimensions, br as resolveTextBoxRenderHeight, bs as getToolbarStyleState, bt as getCachedCanvasImage, bu as measureParagraphMinContentWidthPx, bv as getEditableBlocksForZone, bw as findParagraphLocation, bx as createSectionBoundaryParagraph, by as normalizePageSettings, bz as DEFAULT_EDITOR_PAGE_SETTINGS, bA as markStart, bB as markEnd, bC as getParagraphEntries, bD as getParagraphById, bE as createEditorFootnote, bF as createFootnoteReferenceRun, bG as renumberFootnotes, bH as getFootnoteDisplayMarker, bI as getHeadingLevel, bJ as preciseFontModeVersion, bK as isPreciseFontModeEnabled, bL as resolveNamedTextStyle, bM as togglePreciseFontMode, bN as nextFontSizePt, bO as previousFontSizePt, bP as fontSizePtToPx, bQ as createDefaultToolbarPreset, bR as MenuRegistry, bS as createToolbarRegistry, bT as Editor, bU as resolveCommandRef, bV as commandRefName, bW as createOasisEditorClient, bX as createEditorZoom, bY as startLongTaskObserver, bZ as installGlobalReport, b_ as applyStoredPreciseFontPreference, b$ as getWelcomeSeen, c0 as isLocalFontAccessSupported, c1 as EDITOR_SCROLL_PADDING_PX, c2 as Toolbar, c3 as OasisEditorLoading, c4 as I18nProvider, c5 as createTranslator, c6 as createEditorLogger, c7 as registerDomStatsSurface } from "./index-DdcPkCmB.js";
4
+ import { d as domTextMeasurer, g as getProjectedParagraphBlockHeight, e as estimateTableBlockHeight, p as projectParagraphLayout, a as getPageContentWidth, b as getPageBodyTop, c as getPageBodyBottom, l as listReferencedEndnotes, f as getFootnoteDisplayMarker, s as setActiveHyphenation, h as getDocumentSections, i as buildFootnoteReservations, M as MAX_FOOTNOTE_LAYOUT_ITERATIONS, r as reservationSignature, j as applyFootnotesToPages, k as getRunField, m as projectBlocksLayout, v as visitRun, n as assertNever, o as createSignal, q as createEditorStateFromDocument, t as createInitialEditorState, S as STANDARD_FONT_SIZES_PT, u as fontSizePxToPt, w as probeLocalFontFamilies, x as createEditorParagraphFromRuns, y as isInlineObjectRun, z as createEditorStyledRun, A as getParagraphLength, B as getParagraphText, C as getActiveZone, D as getActiveSectionIndex, E as getParagraphs, F as normalizeSelection, G as positionToParagraphOffset, H as paragraphOffsetToPosition, I as clampPosition, J as findParagraphIndex, K as createCollapsedSelection, L as isSelectionCollapsed, N as parseFontSizePtToPx, O as formatFontSizePt, P as createEditorParagraph, Q as getBlockParagraphs, R as findParagraphTableLocation, T as buildTableCellLayout, U as PT_PER_PX, V as createEditorTableCell, W as createEditorTableRow, X as createEditorTable, Y as underlineStyleToCssDecorationStyle, Z as resolveImageSrc, _ as listKindForTag, $ as isParagraphTag, a0 as collectInlineRuns, a1 as parseParagraphStyle, a2 as getRunImage, a3 as InlineShell, a4 as BalloonShell, a5 as DocumentShell, a6 as createMemo, a7 as getCaretRectFromSnapshot, a8 as getParagraphRectFromSnapshot, a9 as createComponent, aa as CaretOverlay, ab as Show, ac as createRenderEffect, ad as style, ae as setAttribute, af as setStyleProperty, ag as memo, ah as template, ai as useI18n, aj as createEffect, ak as insert, al as use, am as addEventListener, an as Dialog, ao as delegateEvents, ap as className, aq as For, ar as UNDERLINE_STYLE_OPTIONS, as as Tabs, at as onMount, au as onCleanup, av as PluginUiHost, aw as OasisEditorEditor, ax as OasisBrandMark, ay as setPreciseFontPreference, az as setWelcomeSeen, aA as enablePreciseFontMode, aB as TWIPS_PER_POINT, aC as PX_PER_INCH, aD as TWIPS_PER_INCH, aE as resolveEffectiveParagraphStyle, aF as resolveEffectiveTextStyleForParagraph, aG as EMU_PER_PX, aH as EMU_PER_PT, aI as getRunFootnoteReference, aJ as getRunEndnoteReference, aK as iterateFootnoteReferenceRuns, aL as iterateEndnoteReferenceRuns, aM as imageContentTypeDefaults, aN as getRunFieldChar, aO as getRunFieldInstruction, aP as createEditorRun, aQ as JSZip, aR as imageExtensionFromMime, aS as pxToPt$1, aT as resolveFloatingObjectRect, aU as getTextBoxFloatingGeometry, aV as getPresetPathSegments, aW as buildListLabels, aX as getImageFloatingGeometry, aY as textStyleToFontSizePt, aZ as PX_PER_POINT, a_ as resolveOpenTypeFeatureTags, a$ as DEFAULT_FONT_SIZE_PX, b0 as isDoubleUnderlineStyle, b1 as isWavyUnderlineStyle, b2 as underlineStyleLineWidthPx, b3 as underlineStyleDashArray, b4 as resolveListLabel, b5 as getListLabelInset, b6 as getAlignedListLabelInset, b7 as getParagraphBorderInsets, b8 as buildSegmentTable, b9 as buildCanvasTableLayout, ba as resolveCanvasTableWidth, bb as resolveFloatingTableRect, bc as normalizeFamily, bd as ROBOTO_FONT_FILES, be as loadFontAsset, bf as OFFICE_COMPAT_FONT_FAMILIES, bg as BinaryReader, bh as buildSfnt, bi as defaultFontDecoderRegistry, bj as SfntFontProgram, bk as collectPdfFontFamilies, bl as getPageHeaderZoneTop, bm as getPageColumnRects, bn as findFootnoteReference, bo as FOOTNOTE_MARKER_GUTTER_PX, bp as resolveImporterForFile, bq as getDocumentSectionsCanonical, br as getDocumentParagraphsCanonical, bs as getDocumentParagraphs, bt as getDocumentPageSettings, bu as getTableCellContentWidthForParagraph, bv as layoutMetricsEpoch, bw as bumpLayoutMetricsEpoch, bx as createCanvasLayoutSnapshotProvider, by as on, bz as debounce, bA as unwrap, bB as perfTimer, bC as getRunTextBox, bD as createEditorDocument, bE as resolveResizedDimensions, bF as resolveTextBoxRenderHeight, bG as getToolbarStyleState, bH as getCachedCanvasImage, bI as measureParagraphMinContentWidthPx, bJ as getEditableBlocksForZone, bK as findParagraphLocation, bL as createSectionBoundaryParagraph, bM as normalizePageSettings, bN as DEFAULT_EDITOR_PAGE_SETTINGS, bO as markStart, bP as markEnd, bQ as getParagraphEntries, bR as getParagraphById, bS as createEditorFootnote, bT as createFootnoteReferenceRun, bU as renumberFootnotes, bV as getHeadingLevel, bW as preciseFontModeVersion, bX as isPreciseFontModeEnabled, bY as resolveNamedTextStyle, bZ as togglePreciseFontMode, b_ as nextFontSizePt, b$ as previousFontSizePt, c0 as fontSizePtToPx, c1 as createDefaultToolbarPreset, c2 as MenuRegistry, c3 as createToolbarRegistry, c4 as Editor, c5 as resolveCommandRef, c6 as commandRefName, c7 as createOasisEditorClient, c8 as createEditorZoom, c9 as startLongTaskObserver, ca as installGlobalReport, cb as applyStoredPreciseFontPreference, cc as getWelcomeSeen, cd as isLocalFontAccessSupported, ce as EDITOR_SCROLL_PADDING_PX, cf as Toolbar, cg as OasisEditorLoading, ch as I18nProvider, ci as createTranslator, cj as createEditorLogger, ck as registerDomStatsSurface } from "./index-4uLtMJwI.js";
5
+ function projectHeaderFooterBlocksWithDependencies(blocks, deps, context = {}) {
6
+ const {
7
+ pageIndex,
8
+ totalPages,
9
+ measuredHeights,
10
+ styles,
11
+ contentWidth,
12
+ measurer,
13
+ defaultTabStop
14
+ } = context;
15
+ return blocks.map((block, index) => {
16
+ var _a, _b;
17
+ if (block.type === "paragraph") {
18
+ const layout = deps.projectParagraphLayout(
19
+ block,
20
+ pageIndex,
21
+ totalPages,
22
+ styles,
23
+ contentWidth,
24
+ measurer,
25
+ defaultTabStop
26
+ );
27
+ return {
28
+ blockId: block.id,
29
+ sourceBlockId: block.id,
30
+ blockType: block.type,
31
+ paragraphId: block.id,
32
+ globalIndex: index,
33
+ estimatedHeight: (measuredHeights == null ? void 0 : measuredHeights[block.id]) ?? deps.getProjectedParagraphBlockHeight(block, layout, styles),
34
+ layout,
35
+ sourceBlock: block
36
+ };
37
+ }
38
+ const tableHeight = (measuredHeights == null ? void 0 : measuredHeights[block.id]) ?? deps.estimateTableBlockHeight(
39
+ block,
40
+ styles,
41
+ contentWidth,
42
+ measurer,
43
+ defaultTabStop
44
+ );
45
+ return {
46
+ blockId: block.id,
47
+ sourceBlockId: block.id,
48
+ blockType: block.type,
49
+ globalIndex: index,
50
+ estimatedHeight: ((_a = block.style) == null ? void 0 : _a.floating) ? 0 : tableHeight,
51
+ floatingTableHeight: ((_b = block.style) == null ? void 0 : _b.floating) ? tableHeight : void 0,
52
+ sourceBlock: block
53
+ };
54
+ });
55
+ }
56
+ function projectHeaderFooterBlocks(blocks, context = {}) {
57
+ return projectHeaderFooterBlocksWithDependencies(
58
+ blocks,
59
+ {
60
+ projectParagraphLayout,
61
+ estimateTableBlockHeight,
62
+ getProjectedParagraphBlockHeight
63
+ },
64
+ {
65
+ ...context,
66
+ measurer: context.measurer ?? domTextMeasurer
67
+ }
68
+ );
69
+ }
70
+ function getProjectedBlocksHeight(blocks) {
71
+ if (!blocks || blocks.length === 0) {
72
+ return 0;
73
+ }
74
+ return blocks.reduce((sum, block) => sum + block.estimatedHeight, 0);
75
+ }
76
+ function selectSectionHeaderBlocks(section, pageIndexInSection, globalPageIndex) {
77
+ const isFirstPageOfSection = pageIndexInSection === 0;
78
+ const isEvenPageNumber = (globalPageIndex + 1) % 2 === 0;
79
+ if (isFirstPageOfSection && section.firstPageHeader) {
80
+ return section.firstPageHeader;
81
+ }
82
+ if (isEvenPageNumber && section.evenPageHeader) {
83
+ return section.evenPageHeader;
84
+ }
85
+ return section.header;
86
+ }
87
+ function selectSectionFooterBlocks(section, pageIndexInSection, globalPageIndex) {
88
+ const isFirstPageOfSection = pageIndexInSection === 0;
89
+ const isEvenPageNumber = (globalPageIndex + 1) % 2 === 0;
90
+ if (isFirstPageOfSection && section.firstPageFooter) {
91
+ return section.firstPageFooter;
92
+ }
93
+ if (isEvenPageNumber && section.evenPageFooter) {
94
+ return section.evenPageFooter;
95
+ }
96
+ return section.footer;
97
+ }
98
+ function resolveEffectiveVerticalMetrics(pageSettings, headerBlocks, footerBlocks) {
99
+ const staticBodyTop = getPageBodyTop(pageSettings);
100
+ const staticBodyBottom = getPageBodyBottom(pageSettings);
101
+ const headerHeight = getProjectedBlocksHeight(headerBlocks);
102
+ const footerHeight = getProjectedBlocksHeight(footerBlocks);
103
+ const headerTop = pageSettings.margins.header;
104
+ const footerTop = pageSettings.height - pageSettings.margins.footer - footerHeight;
105
+ const headerOccupiedBottom = headerHeight > 0 ? Math.min(pageSettings.height, headerTop + headerHeight) : 0;
106
+ const footerOccupiedTop = footerHeight > 0 ? Math.max(0, footerTop) : pageSettings.height;
107
+ const bodyTop = Math.max(staticBodyTop, headerOccupiedBottom);
108
+ const bodyBottom = Math.max(
109
+ bodyTop,
110
+ Math.min(staticBodyBottom, footerOccupiedTop)
111
+ );
112
+ return {
113
+ bodyTop,
114
+ bodyBottom,
115
+ headerTop,
116
+ footerTop,
117
+ contentHeight: Math.max(24, Math.floor(bodyBottom - bodyTop))
118
+ };
119
+ }
120
+ function createHeaderFooterVariantProjector(context) {
121
+ return (blocks, contentWidth, pageIndex, totalPageCount) => blocks ? context.projectHeaderFooterBlocks(blocks, {
122
+ pageIndex,
123
+ totalPages: totalPageCount,
124
+ measuredHeights: context.measuredHeights,
125
+ measuredParagraphLayouts: context.measuredParagraphLayouts,
126
+ styles: context.documentStyles,
127
+ contentWidth,
128
+ measurer: context.measurer,
129
+ defaultTabStop: context.defaultTabStop
130
+ }) : void 0;
131
+ }
132
+ function projectTallestHeaderVariant(section, contentWidth, projectHeaderFooterVariant) {
133
+ const variants = [
134
+ section.header,
135
+ section.firstPageHeader,
136
+ section.evenPageHeader
137
+ ].map((blocks) => projectHeaderFooterVariant(blocks, contentWidth)).filter((blocks) => !!blocks);
138
+ return variants.sort(
139
+ (a, b) => getProjectedBlocksHeight(b) - getProjectedBlocksHeight(a)
140
+ )[0];
141
+ }
142
+ function projectTallestFooterVariant(section, contentWidth, projectHeaderFooterVariant) {
143
+ const variants = [
144
+ section.footer,
145
+ section.firstPageFooter,
146
+ section.evenPageFooter
147
+ ].map((blocks) => projectHeaderFooterVariant(blocks, contentWidth)).filter((blocks) => !!blocks);
148
+ return variants.sort(
149
+ (a, b) => getProjectedBlocksHeight(b) - getProjectedBlocksHeight(a)
150
+ )[0];
151
+ }
152
+ function calculateTotalPages(context, projectHeaderFooterVariant) {
153
+ let currentTotal = 0;
154
+ const activePages = [];
155
+ for (const section of context.sections) {
156
+ const contentWidth = getPageContentWidth(section.pageSettings);
157
+ const headerBlocks = projectTallestHeaderVariant(
158
+ section,
159
+ contentWidth,
160
+ projectHeaderFooterVariant
161
+ );
162
+ const footerBlocks = projectTallestFooterVariant(
163
+ section,
164
+ contentWidth,
165
+ projectHeaderFooterVariant
166
+ );
167
+ const metrics = resolveEffectiveVerticalMetrics(
168
+ section.pageSettings,
169
+ headerBlocks,
170
+ footerBlocks
171
+ );
172
+ const pageHeight = context.maxPageHeightOverride ?? metrics.contentHeight;
173
+ const isContinuous = section.breakType === "continuous" && activePages.length > 0;
174
+ const sectionPages = context.projectBlocks({
175
+ blocks: section.blocks,
176
+ pageSettings: section.pageSettings,
177
+ maxPageHeight: pageHeight,
178
+ measuredHeights: context.measuredHeights,
179
+ measuredParagraphLayouts: context.measuredParagraphLayouts,
180
+ pageOffset: isContinuous ? currentTotal - 1 : currentTotal,
181
+ existingPages: isContinuous ? [activePages[activePages.length - 1]] : [],
182
+ measurer: context.measurer,
183
+ defaultTabStop: context.defaultTabStop
184
+ });
185
+ if (isContinuous) {
186
+ activePages.pop();
187
+ activePages.push(...sectionPages);
188
+ currentTotal = activePages.length;
189
+ } else {
190
+ activePages.push(...sectionPages);
191
+ currentTotal = activePages.length;
192
+ }
193
+ }
194
+ return currentTotal;
195
+ }
196
+ function projectAllPages(context, totalPages, projectHeaderFooterVariant, reservedHeightByPageIndex) {
197
+ const allPages = [];
198
+ for (const section of context.sections) {
199
+ const contentWidth = getPageContentWidth(section.pageSettings);
200
+ const sectionHeaderBlocks = projectTallestHeaderVariant(
201
+ section,
202
+ contentWidth,
203
+ projectHeaderFooterVariant
204
+ );
205
+ const sectionFooterBlocks = projectTallestFooterVariant(
206
+ section,
207
+ contentWidth,
208
+ projectHeaderFooterVariant
209
+ );
210
+ const sectionMetrics = resolveEffectiveVerticalMetrics(
211
+ section.pageSettings,
212
+ sectionHeaderBlocks,
213
+ sectionFooterBlocks
214
+ );
215
+ const pageHeight = context.maxPageHeightOverride ?? sectionMetrics.contentHeight;
216
+ const isContinuous = section.breakType === "continuous" && allPages.length > 0;
217
+ const sectionPageOffset = isContinuous ? allPages.length - 1 : allPages.length;
218
+ const sectionPages = context.projectBlocks({
219
+ blocks: section.blocks,
220
+ pageSettings: section.pageSettings,
221
+ maxPageHeight: pageHeight,
222
+ measuredHeights: context.measuredHeights,
223
+ measuredParagraphLayouts: context.measuredParagraphLayouts,
224
+ styles: context.documentStyles,
225
+ pageOffset: sectionPageOffset,
226
+ totalPages,
227
+ existingPages: isContinuous ? [allPages[allPages.length - 1]] : [],
228
+ measurer: context.measurer,
229
+ reservedHeightByPageIndex,
230
+ defaultTabStop: context.defaultTabStop
231
+ });
232
+ if (isContinuous) {
233
+ allPages.pop();
234
+ }
235
+ for (const page of sectionPages) {
236
+ const pageIndexInSection = page.index - sectionPageOffset;
237
+ const pageContentWidth = getPageContentWidth(page.pageSettings);
238
+ const headerBlocks = projectHeaderFooterVariant(
239
+ selectSectionHeaderBlocks(
240
+ section,
241
+ Math.max(0, pageIndexInSection),
242
+ page.index
243
+ ),
244
+ pageContentWidth,
245
+ page.index,
246
+ totalPages
247
+ ) ?? page.headerBlocks;
248
+ const footerBlocks = projectHeaderFooterVariant(
249
+ selectSectionFooterBlocks(
250
+ section,
251
+ Math.max(0, pageIndexInSection),
252
+ page.index
253
+ ),
254
+ pageContentWidth,
255
+ page.index,
256
+ totalPages
257
+ ) ?? page.footerBlocks;
258
+ const pageMetrics = resolveEffectiveVerticalMetrics(
259
+ page.pageSettings,
260
+ headerBlocks,
261
+ footerBlocks
262
+ );
263
+ const reservedHeight = (reservedHeightByPageIndex == null ? void 0 : reservedHeightByPageIndex.get(page.index)) ?? 0;
264
+ page.headerBlocks = headerBlocks;
265
+ page.footerBlocks = footerBlocks;
266
+ page.bodyTop = pageMetrics.bodyTop;
267
+ page.bodyBottom = Math.max(
268
+ pageMetrics.bodyTop,
269
+ pageMetrics.bodyBottom - reservedHeight
270
+ );
271
+ page.headerTop = pageMetrics.headerTop;
272
+ page.footerTop = pageMetrics.footerTop;
273
+ page.maxHeight = Math.max(
274
+ 24,
275
+ (context.maxPageHeightOverride ?? pageMetrics.contentHeight) - reservedHeight
276
+ );
277
+ allPages.push(page);
278
+ }
279
+ }
280
+ return allPages;
281
+ }
282
+ function projectDocumentSections(context, reservedHeightByPageIndex) {
283
+ const projectHeaderFooterVariant = createHeaderFooterVariantProjector(context);
284
+ const totalPages = context.needsTotalPages ? calculateTotalPages(context, projectHeaderFooterVariant) : void 0;
285
+ return {
286
+ totalPages,
287
+ pages: projectAllPages(
288
+ context,
289
+ totalPages,
290
+ projectHeaderFooterVariant,
291
+ reservedHeightByPageIndex
292
+ )
293
+ };
294
+ }
295
+ const FLOW_ID_PREFIX = "endnote-flow";
296
+ function makeMarkerRun(endnoteId, marker) {
297
+ return {
298
+ id: `${FLOW_ID_PREFIX}:marker:${endnoteId}`,
299
+ text: `${marker}. `,
300
+ styles: { superscript: true },
301
+ kind: "text"
302
+ };
303
+ }
304
+ function prependMarker(paragraph, endnoteId, marker) {
305
+ return {
306
+ ...paragraph,
307
+ id: `${FLOW_ID_PREFIX}:p:${endnoteId}:${paragraph.id}`,
308
+ runs: [makeMarkerRun(endnoteId, marker), ...paragraph.runs]
309
+ };
310
+ }
311
+ function emptyMarkerParagraph(endnoteId, marker) {
312
+ return {
313
+ id: `${FLOW_ID_PREFIX}:p:${endnoteId}:empty`,
314
+ type: "paragraph",
315
+ runs: [
316
+ makeMarkerRun(endnoteId, marker),
317
+ { id: `${FLOW_ID_PREFIX}:text:${endnoteId}`, text: "", kind: "text" }
318
+ ]
319
+ };
320
+ }
321
+ function spacerParagraph() {
322
+ return {
323
+ id: `${FLOW_ID_PREFIX}:spacer`,
324
+ type: "paragraph",
325
+ runs: [{ id: `${FLOW_ID_PREFIX}:spacer:text`, text: "", kind: "text" }]
326
+ };
327
+ }
328
+ function buildEndnoteFlowBlocks(document2) {
329
+ var _a, _b, _c;
330
+ const referenced = listReferencedEndnotes(document2);
331
+ const items = (_a = document2.endnotes) == null ? void 0 : _a.items;
332
+ if (!items || referenced.length === 0) {
333
+ return [];
334
+ }
335
+ const format = ((_c = (_b = document2.endnotes) == null ? void 0 : _b.settings) == null ? void 0 : _c.numberFormat) ?? "decimal";
336
+ const out = [spacerParagraph()];
337
+ for (const ref of referenced) {
338
+ const endnote = items[ref.endnoteId];
339
+ if (!endnote) continue;
340
+ const marker = ref.customMark ?? getFootnoteDisplayMarker(ref.index, format);
341
+ const blocks = endnote.blocks;
342
+ if (blocks.length === 0) {
343
+ out.push(emptyMarkerParagraph(ref.endnoteId, marker));
344
+ continue;
345
+ }
346
+ blocks.forEach((block, index) => {
347
+ if (index === 0 && block.type === "paragraph") {
348
+ out.push(prependMarker(block, ref.endnoteId, marker));
349
+ return;
350
+ }
351
+ if (index === 0) {
352
+ out.push(emptyMarkerParagraph(ref.endnoteId, marker));
353
+ }
354
+ out.push(block);
355
+ });
356
+ }
357
+ return out;
358
+ }
359
+ function injectEndnotesIntoDocument(document2) {
360
+ const flowBlocks = buildEndnoteFlowBlocks(document2);
361
+ if (flowBlocks.length === 0) {
362
+ return document2;
363
+ }
364
+ const sections = document2.sections;
365
+ if (!sections || sections.length === 0) {
366
+ return document2;
367
+ }
368
+ const lastIndex = sections.length - 1;
369
+ const nextSections = sections.map(
370
+ (section, index) => index === lastIndex ? { ...section, blocks: [...section.blocks, ...flowBlocks] } : section
371
+ );
372
+ return { ...document2, sections: nextSections };
373
+ }
374
+ function blockContainsNumPagesField(block) {
375
+ if (block.type === "paragraph") {
376
+ return block.runs.some((run) => {
377
+ var _a;
378
+ return ((_a = getRunField(run)) == null ? void 0 : _a.type) === "NUMPAGES";
379
+ });
380
+ }
381
+ return block.rows.some(
382
+ (row) => row.cells.some((cell) => cell.blocks.some(blockContainsNumPagesField))
383
+ );
384
+ }
385
+ function documentContainsNumPagesField(document2) {
386
+ return getDocumentSections(document2).some(
387
+ (section) => [
388
+ ...section.header ?? [],
389
+ ...section.firstPageHeader ?? [],
390
+ ...section.evenPageHeader ?? [],
391
+ ...section.blocks,
392
+ ...section.footer ?? [],
393
+ ...section.firstPageFooter ?? [],
394
+ ...section.evenPageFooter ?? []
395
+ ].some(blockContainsNumPagesField)
396
+ );
397
+ }
398
+ function projectDocumentLayout(document2, maxPageHeightOverride, measuredHeights, measuredParagraphLayouts, options = {}) {
399
+ var _a, _b;
400
+ const measurer = options.measurer ?? domTextMeasurer;
401
+ setActiveHyphenation(
402
+ ((_a = document2.settings) == null ? void 0 : _a.autoHyphenation) ? {
403
+ enabled: true,
404
+ zone: document2.settings.hyphenationZone,
405
+ consecutiveLimit: document2.settings.consecutiveHyphenLimit,
406
+ doNotHyphenateCaps: document2.settings.doNotHyphenateCaps
407
+ } : void 0
408
+ );
409
+ const layoutDocument = injectEndnotesIntoDocument(document2);
410
+ const sections = getDocumentSections(layoutDocument);
411
+ const needsTotalPages = documentContainsNumPagesField(layoutDocument);
412
+ const sectionContext = {
413
+ sections,
414
+ documentStyles: document2.styles,
415
+ maxPageHeightOverride,
416
+ measuredHeights,
417
+ measuredParagraphLayouts,
418
+ measurer,
419
+ defaultTabStop: (_b = document2.settings) == null ? void 0 : _b.defaultTabStop,
420
+ needsTotalPages,
421
+ projectBlocks: projectBlocksLayout,
422
+ projectHeaderFooterBlocks
423
+ };
424
+ const projectedSections = projectDocumentSections(sectionContext);
425
+ let pages = projectedSections.pages;
426
+ const totalPages = projectedSections.totalPages;
427
+ if (!document2.footnotes || Object.keys(document2.footnotes.items).length === 0) {
428
+ setActiveHyphenation(void 0);
429
+ return { pages };
430
+ }
431
+ const footnoteContext = {
432
+ document: document2,
433
+ totalPages,
434
+ measuredHeights,
435
+ measuredParagraphLayouts,
436
+ measurer,
437
+ projectBlocks: projectHeaderFooterBlocks
438
+ };
439
+ let reservations = buildFootnoteReservations(pages, footnoteContext);
440
+ let previousSignature = "";
441
+ for (let iteration = 0; iteration < MAX_FOOTNOTE_LAYOUT_ITERATIONS; iteration += 1) {
442
+ const signature = reservationSignature(reservations);
443
+ if (signature === previousSignature) {
444
+ break;
445
+ }
446
+ previousSignature = signature;
447
+ pages = projectDocumentSections(sectionContext, reservations).pages;
448
+ reservations = buildFootnoteReservations(pages, footnoteContext);
449
+ }
450
+ const result = {
451
+ pages: applyFootnotesToPages(pages, footnoteContext)
452
+ };
453
+ setActiveHyphenation(void 0);
454
+ return result;
455
+ }
5
456
  function cloneStyle(style2) {
6
457
  return style2 ? { ...style2 } : void 0;
7
458
  }
@@ -30611,13 +31062,15 @@ function computeShouldShowCaret(state, caretBox) {
30611
31062
  }
30612
31063
  function DropCaret(props) {
30613
31064
  const layout = createMemo(() => {
30614
- var _a, _b;
31065
+ var _a, _b, _c;
30615
31066
  const pos = props.targetPos();
30616
31067
  const surfaceRef = props.surfaceRef;
30617
31068
  if (!surfaceRef) return null;
30618
- const snapshot = buildCanvasLayoutSnapshot({
31069
+ const snapshot = props.snapshotProvider.getCanvasLayoutSnapshot({
30619
31070
  surface: surfaceRef,
30620
- state: props.state
31071
+ state: props.state,
31072
+ documentLayout: props.documentLayout(),
31073
+ zoomFactor: (_a = props.zoomFactor) == null ? void 0 : _a.call(props)
30621
31074
  });
30622
31075
  let viewportLeft = 0;
30623
31076
  let viewportTop = 0;
@@ -30642,7 +31095,7 @@ function DropCaret(props) {
30642
31095
  };
30643
31096
  }
30644
31097
  }
30645
- const caret = ((_a = props.caretViewport) == null ? void 0 : _a.call(props)) ?? null;
31098
+ const caret = ((_b = props.caretViewport) == null ? void 0 : _b.call(props)) ?? null;
30646
31099
  if (caret) {
30647
31100
  viewportLeft = caret.left;
30648
31101
  viewportTop = caret.top;
@@ -30653,7 +31106,7 @@ function DropCaret(props) {
30653
31106
  height
30654
31107
  };
30655
31108
  }
30656
- const pointer = ((_b = props.pointerPos) == null ? void 0 : _b.call(props)) ?? null;
31109
+ const pointer = ((_c = props.pointerPos) == null ? void 0 : _c.call(props)) ?? null;
30657
31110
  if (pointer) {
30658
31111
  viewportLeft = pointer.x;
30659
31112
  viewportTop = pointer.y - 12;
@@ -30777,6 +31230,15 @@ function EditorDragLayers(props) {
30777
31230
  get state() {
30778
31231
  return props.state;
30779
31232
  },
31233
+ get documentLayout() {
31234
+ return props.documentLayout;
31235
+ },
31236
+ get snapshotProvider() {
31237
+ return props.snapshotProvider;
31238
+ },
31239
+ get zoomFactor() {
31240
+ return props.zoomFactor;
31241
+ },
30780
31242
  targetPos: pos
30781
31243
  })
30782
31244
  }), createComponent(Show, {
@@ -30790,6 +31252,15 @@ function EditorDragLayers(props) {
30790
31252
  get state() {
30791
31253
  return props.state;
30792
31254
  },
31255
+ get documentLayout() {
31256
+ return props.documentLayout;
31257
+ },
31258
+ get snapshotProvider() {
31259
+ return props.snapshotProvider;
31260
+ },
31261
+ get zoomFactor() {
31262
+ return props.zoomFactor;
31263
+ },
30793
31264
  targetPos: pos
30794
31265
  })
30795
31266
  }), createComponent(Show, {
@@ -30803,6 +31274,15 @@ function EditorDragLayers(props) {
30803
31274
  get state() {
30804
31275
  return props.state;
30805
31276
  },
31277
+ get documentLayout() {
31278
+ return props.documentLayout;
31279
+ },
31280
+ get snapshotProvider() {
31281
+ return props.snapshotProvider;
31282
+ },
31283
+ get zoomFactor() {
31284
+ return props.zoomFactor;
31285
+ },
30806
31286
  targetPos: pos,
30807
31287
  get pointerPos() {
30808
31288
  return props.textDrag.pointerPos;
@@ -32739,6 +33219,7 @@ function buildEditorViewProps(ctx) {
32739
33219
  files
32740
33220
  } = ctx;
32741
33221
  const layout = {
33222
+ documentLayout: layoutInput.documentLayout,
32742
33223
  viewportHeight: layoutInput.viewportHeight,
32743
33224
  class: layoutInput.className,
32744
33225
  style: layoutInput.style,
@@ -32883,6 +33364,9 @@ function EditorWorkspace(props) {
32883
33364
  get measuredParagraphLayouts() {
32884
33365
  return view2.measuredParagraphLayouts;
32885
33366
  },
33367
+ get documentLayout() {
33368
+ return view2.documentLayout;
33369
+ },
32886
33370
  get viewportHeight() {
32887
33371
  return view2.viewportHeight;
32888
33372
  },
@@ -32934,6 +33418,7 @@ function EditorWorkspace(props) {
32934
33418
  get layout() {
32935
33419
  return {
32936
33420
  ...props.view.layout,
33421
+ documentLayout: props.view.documentLayout,
32937
33422
  measuredBlockHeights: props.view.measuredBlockHeights,
32938
33423
  measuredParagraphLayouts: props.view.measuredParagraphLayouts,
32939
33424
  readOnly: props.view.isReadOnly()
@@ -40947,6 +41432,110 @@ function computeCommentHighlights(snapshot, state) {
40947
41432
  }
40948
41433
  return boxes;
40949
41434
  }
41435
+ const canvasTextMeasurer = {
41436
+ composeMeasuredParagraphLines: (options) => domTextMeasurer.composeMeasuredParagraphLines(options),
41437
+ resolveRenderedLineHeightPx: (styles, lineHeightMultiple) => domTextMeasurer.resolveRenderedLineHeightPx(styles, lineHeightMultiple)
41438
+ };
41439
+ function areLayoutParagraphsEquivalentForRender(previous, next) {
41440
+ if (previous === next) {
41441
+ return true;
41442
+ }
41443
+ if (!previous || !next) {
41444
+ return false;
41445
+ }
41446
+ if (previous.text !== next.text || previous.startOffset !== next.startOffset || previous.endOffset !== next.endOffset || previous.lines.length !== next.lines.length) {
41447
+ return false;
41448
+ }
41449
+ return next.lines.every((line, index) => {
41450
+ const previousLine = previous.lines[index];
41451
+ return previousLine !== void 0 && previousLine.startOffset === line.startOffset && previousLine.endOffset === line.endOffset && previousLine.top === line.top && previousLine.height === line.height;
41452
+ });
41453
+ }
41454
+ function canReuseLayoutBlock(previous, next) {
41455
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
41456
+ return Boolean(
41457
+ previous && previous.blockId === next.blockId && previous.sourceBlock === next.sourceBlock && previous.estimatedHeight === next.estimatedHeight && ((_a = previous.tableSegment) == null ? void 0 : _a.startRowIndex) === ((_b = next.tableSegment) == null ? void 0 : _b.startRowIndex) && ((_c = previous.tableSegment) == null ? void 0 : _c.endRowIndex) === ((_d = next.tableSegment) == null ? void 0 : _d.endRowIndex) && ((_e = previous.tableSegment) == null ? void 0 : _e.repeatedHeaderRowCount) === ((_f = next.tableSegment) == null ? void 0 : _f.repeatedHeaderRowCount) && sameNumberArray(
41458
+ (_g = previous.tableSegment) == null ? void 0 : _g.startRowCellBlockStarts,
41459
+ (_h = next.tableSegment) == null ? void 0 : _h.startRowCellBlockStarts
41460
+ ) && sameNumberArray(
41461
+ (_i = previous.tableSegment) == null ? void 0 : _i.endRowCellBlockEnds,
41462
+ (_j = next.tableSegment) == null ? void 0 : _j.endRowCellBlockEnds
41463
+ ) && sameTableCellBlockPositions(
41464
+ (_k = previous.tableSegment) == null ? void 0 : _k.startRowCellBlockPositions,
41465
+ (_l = next.tableSegment) == null ? void 0 : _l.startRowCellBlockPositions
41466
+ ) && sameTableCellBlockPositions(
41467
+ (_m = previous.tableSegment) == null ? void 0 : _m.endRowCellBlockPositions,
41468
+ (_n = next.tableSegment) == null ? void 0 : _n.endRowCellBlockPositions
41469
+ ) && areLayoutParagraphsEquivalentForRender(previous.layout, next.layout)
41470
+ );
41471
+ }
41472
+ function sameNumberArray(left, right) {
41473
+ if (((left == null ? void 0 : left.length) ?? 0) !== ((right == null ? void 0 : right.length) ?? 0)) return false;
41474
+ return (right ?? []).every((value, index) => (left == null ? void 0 : left[index]) === value);
41475
+ }
41476
+ function sameTableCellBlockPositions(left, right) {
41477
+ if (((left == null ? void 0 : left.length) ?? 0) !== ((right == null ? void 0 : right.length) ?? 0)) return false;
41478
+ return (right ?? []).every((value, index) => {
41479
+ const previous = left == null ? void 0 : left[index];
41480
+ return (previous == null ? void 0 : previous.blockIndex) === value.blockIndex && (previous == null ? void 0 : previous.offset) === value.offset;
41481
+ });
41482
+ }
41483
+ function canReuseLayoutPage(previous, next) {
41484
+ const samePageSettings = Boolean(
41485
+ previous && previous.pageSettings.width === next.pageSettings.width && previous.pageSettings.height === next.pageSettings.height && previous.pageSettings.orientation === next.pageSettings.orientation && previous.pageSettings.margins.top === next.pageSettings.margins.top && previous.pageSettings.margins.right === next.pageSettings.margins.right && previous.pageSettings.margins.bottom === next.pageSettings.margins.bottom && previous.pageSettings.margins.left === next.pageSettings.margins.left && previous.pageSettings.margins.header === next.pageSettings.margins.header && previous.pageSettings.margins.footer === next.pageSettings.margins.footer && previous.pageSettings.margins.gutter === next.pageSettings.margins.gutter
41486
+ );
41487
+ if (!previous || previous.id !== next.id || previous.index !== next.index || previous.height !== next.height || previous.maxHeight !== next.maxHeight || !samePageSettings || previous.bodyTop !== next.bodyTop || previous.bodyBottom !== next.bodyBottom || previous.headerTop !== next.headerTop || previous.footerTop !== next.footerTop || previous.footnoteTop !== next.footnoteTop || previous.footnoteSeparatorTop !== next.footnoteSeparatorTop) {
41488
+ return false;
41489
+ }
41490
+ const sameBlocks = (left, right) => {
41491
+ if (((left == null ? void 0 : left.length) ?? 0) !== ((right == null ? void 0 : right.length) ?? 0)) {
41492
+ return false;
41493
+ }
41494
+ return (right ?? []).every((block, index) => (left == null ? void 0 : left[index]) === block);
41495
+ };
41496
+ const sameFootnoteReferences = (left, right) => {
41497
+ if (((left == null ? void 0 : left.length) ?? 0) !== ((right == null ? void 0 : right.length) ?? 0)) {
41498
+ return false;
41499
+ }
41500
+ return (right ?? []).every(
41501
+ (footnoteId, index) => (left == null ? void 0 : left[index]) === footnoteId
41502
+ );
41503
+ };
41504
+ return sameBlocks(previous.blocks, next.blocks) && sameBlocks(previous.headerBlocks, next.headerBlocks) && sameBlocks(previous.footerBlocks, next.footerBlocks) && sameBlocks(previous.footnoteBlocks, next.footnoteBlocks) && sameFootnoteReferences(
41505
+ previous.footnoteReferenceIds,
41506
+ next.footnoteReferenceIds
41507
+ );
41508
+ }
41509
+ function createLayoutIdentityStabilizer() {
41510
+ let reusableLayoutBlocks = /* @__PURE__ */ new Map();
41511
+ let reusableLayoutPages = /* @__PURE__ */ new Map();
41512
+ return function stabilize(layout) {
41513
+ const nextBlockCache = /* @__PURE__ */ new Map();
41514
+ const stabilizeBlocks = (blocks) => blocks == null ? void 0 : blocks.map((block) => {
41515
+ const previous = reusableLayoutBlocks.get(block.blockId);
41516
+ const stable = canReuseLayoutBlock(previous, block) ? previous : block;
41517
+ nextBlockCache.set(stable.blockId, stable);
41518
+ return stable;
41519
+ });
41520
+ const pages = layout.pages.map((page) => {
41521
+ const nextPage = {
41522
+ ...page,
41523
+ blocks: stabilizeBlocks(page.blocks) ?? [],
41524
+ headerBlocks: stabilizeBlocks(page.headerBlocks),
41525
+ footerBlocks: stabilizeBlocks(page.footerBlocks),
41526
+ footnoteBlocks: stabilizeBlocks(page.footnoteBlocks)
41527
+ };
41528
+ const previous = reusableLayoutPages.get(nextPage.id);
41529
+ if (canReuseLayoutPage(previous, nextPage)) {
41530
+ return previous;
41531
+ }
41532
+ return nextPage;
41533
+ });
41534
+ reusableLayoutBlocks = nextBlockCache;
41535
+ reusableLayoutPages = new Map(pages.map((page) => [page.id, page]));
41536
+ return { pages };
41537
+ };
41538
+ }
40950
41539
  function scheduleFrame(callback) {
40951
41540
  if (typeof window !== "undefined" && typeof window.requestAnimationFrame === "function") {
40952
41541
  return window.requestAnimationFrame(() => callback());
@@ -40987,6 +41576,22 @@ function useEditorLayout(props) {
40987
41576
  const [preferredColumnX, setPreferredColumnX] = createSignal(
40988
41577
  null
40989
41578
  );
41579
+ const stabilize = createLayoutIdentityStabilizer();
41580
+ const documentLayout = createMemo(() => {
41581
+ layoutMetricsEpoch();
41582
+ return stabilize(
41583
+ projectDocumentLayout(
41584
+ props.state.document,
41585
+ void 0,
41586
+ measuredBlockHeights(),
41587
+ measuredParagraphLayouts(),
41588
+ {
41589
+ measurer: canvasTextMeasurer
41590
+ }
41591
+ )
41592
+ );
41593
+ });
41594
+ const canvasSnapshotProvider = createCanvasLayoutSnapshotProvider();
40990
41595
  let syncRequestId = 0;
40991
41596
  const syncInputBox = (_reason = "selection") => {
40992
41597
  var _a;
@@ -40999,11 +41604,10 @@ function useEditorLayout(props) {
40999
41604
  setCaretBox((current) => ({ ...current, visible: false }));
41000
41605
  return;
41001
41606
  }
41002
- const snapshot = buildCanvasLayoutSnapshot({
41607
+ const snapshot = canvasSnapshotProvider.getCanvasLayoutSnapshot({
41003
41608
  surface,
41004
41609
  state: props.state,
41005
- measuredBlockHeights: measuredBlockHeights(),
41006
- measuredParagraphLayouts: measuredParagraphLayouts(),
41610
+ documentLayout: documentLayout(),
41007
41611
  zoomFactor: (_a = props.zoomFactor) == null ? void 0 : _a.call(props)
41008
41612
  });
41009
41613
  if (!snapshot) {
@@ -41040,6 +41644,7 @@ function useEditorLayout(props) {
41040
41644
  setMeasuredParagraphLayouts(
41041
41645
  (current) => normalizeParagraphLayouts(current, options.paragraphIds ?? [])
41042
41646
  );
41647
+ bumpLayoutMetricsEpoch();
41043
41648
  }
41044
41649
  requestInputBoxSync(reason);
41045
41650
  return options.resolveWhenDone ? Promise.resolve() : null;
@@ -41052,17 +41657,20 @@ function useEditorLayout(props) {
41052
41657
  if (invalidation.dirtyAll || invalidation.structureChanged) {
41053
41658
  setMeasuredBlockHeights({});
41054
41659
  setMeasuredParagraphLayouts({});
41660
+ bumpLayoutMetricsEpoch();
41055
41661
  } else if ((((_b = invalidation.dirtyParagraphIds) == null ? void 0 : _b.length) ?? 0) > 0) {
41056
41662
  const dirtyIds = invalidation.dirtyParagraphIds ?? [];
41057
41663
  setMeasuredParagraphLayouts(
41058
41664
  (current) => normalizeParagraphLayouts(current, dirtyIds)
41059
41665
  );
41666
+ bumpLayoutMetricsEpoch();
41060
41667
  }
41061
41668
  requestInputBoxSync("content-change");
41062
41669
  };
41063
41670
  const stabilizeLayoutAfterImport = async () => {
41064
41671
  setMeasuredBlockHeights({});
41065
41672
  setMeasuredParagraphLayouts({});
41673
+ bumpLayoutMetricsEpoch();
41066
41674
  await new Promise((resolve) => {
41067
41675
  scheduleFrame(() => resolve());
41068
41676
  });
@@ -41110,10 +41718,13 @@ function useEditorLayout(props) {
41110
41718
  const clearPreferredColumn = () => setPreferredColumnX(null);
41111
41719
  const onCleanupHook = () => {
41112
41720
  syncRequestId += 1;
41721
+ canvasSnapshotProvider.clear();
41113
41722
  };
41114
41723
  return {
41115
41724
  measuredBlockHeights,
41116
41725
  measuredParagraphLayouts,
41726
+ documentLayout,
41727
+ canvasSnapshotProvider,
41117
41728
  inputBox,
41118
41729
  selectionBoxes,
41119
41730
  commentHighlights,
@@ -41664,6 +42275,8 @@ function createEditorDocumentRuntime(deps) {
41664
42275
  const {
41665
42276
  measuredBlockHeights,
41666
42277
  measuredParagraphLayouts,
42278
+ documentLayout,
42279
+ canvasSnapshotProvider,
41667
42280
  inputBox,
41668
42281
  selectionBoxes,
41669
42282
  commentHighlights,
@@ -41733,6 +42346,8 @@ function createEditorDocumentRuntime(deps) {
41733
42346
  clearPreferredColumn();
41734
42347
  setMeasuredBlockHeights({});
41735
42348
  setMeasuredParagraphLayouts({});
42349
+ bumpLayoutMetricsEpoch();
42350
+ canvasSnapshotProvider.clear();
41736
42351
  clearHistory();
41737
42352
  };
41738
42353
  createEditorChangeBroadcast({
@@ -41748,6 +42363,8 @@ function createEditorDocumentRuntime(deps) {
41748
42363
  isImportInProgress,
41749
42364
  measuredBlockHeights,
41750
42365
  measuredParagraphLayouts,
42366
+ documentLayout,
42367
+ canvasSnapshotProvider,
41751
42368
  inputBox,
41752
42369
  selectionBoxes,
41753
42370
  commentHighlights,
@@ -44509,43 +45126,17 @@ function resolveCanvasSurfaceHitAtPoint(options) {
44509
45126
  };
44510
45127
  }
44511
45128
  function createCanvasSurfaceHitResolver(deps) {
44512
- let canvasSnapshotCache = null;
44513
45129
  const resolveSurfaceHitAtPoint = (clientX, clientY, context = {}) => {
44514
45130
  const currentSurfaceRef = deps.surfaceRef();
44515
- const currentViewportRef = deps.viewportRef();
44516
45131
  if (!currentSurfaceRef) return null;
44517
- const currentMeasuredBlockHeights = deps.measuredBlockHeights();
44518
- const currentMeasuredParagraphLayouts = deps.measuredParagraphLayouts();
44519
45132
  const currentState = deps.state();
44520
- const viewportScrollTop = (currentViewportRef == null ? void 0 : currentViewportRef.scrollTop) ?? 0;
44521
- const viewportScrollLeft = (currentViewportRef == null ? void 0 : currentViewportRef.scrollLeft) ?? 0;
44522
- const windowWidth = window.innerWidth;
44523
- const windowHeight = window.innerHeight;
44524
45133
  const zoomFactor = deps.zoomFactor();
44525
- const shouldReuseSnapshot = canvasSnapshotCache && canvasSnapshotCache.documentRef === currentState.document && canvasSnapshotCache.measuredBlockHeightsRef === currentMeasuredBlockHeights && canvasSnapshotCache.measuredParagraphLayoutsRef === currentMeasuredParagraphLayouts && canvasSnapshotCache.surfaceRef === currentSurfaceRef && canvasSnapshotCache.viewportScrollTop === viewportScrollTop && canvasSnapshotCache.viewportScrollLeft === viewportScrollLeft && canvasSnapshotCache.surfaceClientWidth === currentSurfaceRef.clientWidth && canvasSnapshotCache.surfaceClientHeight === currentSurfaceRef.clientHeight && canvasSnapshotCache.windowWidth === windowWidth && canvasSnapshotCache.windowHeight === windowHeight && canvasSnapshotCache.zoomFactor === zoomFactor;
44526
- const snapshot = shouldReuseSnapshot ? canvasSnapshotCache.snapshot : buildCanvasLayoutSnapshot({
45134
+ const snapshot = deps.canvasSnapshotProvider.getCanvasLayoutSnapshot({
44527
45135
  surface: currentSurfaceRef,
44528
45136
  state: currentState,
44529
- measuredBlockHeights: currentMeasuredBlockHeights,
44530
- measuredParagraphLayouts: currentMeasuredParagraphLayouts,
45137
+ documentLayout: deps.documentLayout(),
44531
45138
  zoomFactor
44532
45139
  });
44533
- if (!shouldReuseSnapshot) {
44534
- canvasSnapshotCache = {
44535
- snapshot,
44536
- documentRef: currentState.document,
44537
- measuredBlockHeightsRef: currentMeasuredBlockHeights,
44538
- measuredParagraphLayoutsRef: currentMeasuredParagraphLayouts,
44539
- surfaceRef: currentSurfaceRef,
44540
- viewportScrollTop,
44541
- viewportScrollLeft,
44542
- surfaceClientWidth: currentSurfaceRef.clientWidth,
44543
- surfaceClientHeight: currentSurfaceRef.clientHeight,
44544
- windowWidth,
44545
- windowHeight,
44546
- zoomFactor
44547
- };
44548
- }
44549
45140
  recordCanvasDebugLayoutSnapshot(snapshot);
44550
45141
  if (!snapshot) {
44551
45142
  recordCanvasDebugHit(null);
@@ -44958,10 +45549,12 @@ function getTableById(state, tableId) {
44958
45549
  );
44959
45550
  return table ?? null;
44960
45551
  }
44961
- function buildTableGeometries(surface, state) {
44962
- const snapshot = buildCanvasLayoutSnapshot({
45552
+ function buildTableGeometries(surface, state, documentLayout, canvasSnapshotProvider, zoomFactor) {
45553
+ const snapshot = canvasSnapshotProvider.getCanvasLayoutSnapshot({
44963
45554
  surface,
44964
- state
45555
+ state,
45556
+ documentLayout,
45557
+ zoomFactor
44965
45558
  });
44966
45559
  if (!snapshot) {
44967
45560
  return [];
@@ -45057,8 +45650,14 @@ function buildTableGeometries(surface, state) {
45057
45650
  }
45058
45651
  const EDGE_THRESHOLD_COLUMN_PX = 4;
45059
45652
  const EDGE_THRESHOLD_ROW_PX = 4;
45060
- function findTableResizeHoverInfo(event, surface, state) {
45061
- const geometries = buildTableGeometries(surface, state);
45653
+ function findTableResizeHoverInfo(event, surface, state, documentLayout, canvasSnapshotProvider, zoomFactor) {
45654
+ const geometries = buildTableGeometries(
45655
+ surface,
45656
+ state,
45657
+ documentLayout,
45658
+ canvasSnapshotProvider,
45659
+ zoomFactor
45660
+ );
45062
45661
  if (geometries.length === 0) {
45063
45662
  return null;
45064
45663
  }
@@ -45427,6 +46026,7 @@ const DRAG_THRESHOLD_PX = 2;
45427
46026
  function createEditorTableResize(deps) {
45428
46027
  const [resizing, setResizing] = createSignal(null);
45429
46028
  const handleMouseMove = (event) => {
46029
+ var _a;
45430
46030
  if (resizing()) {
45431
46031
  setActiveCursorClass(resizing().type === "column");
45432
46032
  return;
@@ -45436,7 +46036,14 @@ function createEditorTableResize(deps) {
45436
46036
  clearResizeCursorClasses();
45437
46037
  return;
45438
46038
  }
45439
- const info = findTableResizeHoverInfo(event, surface, deps.state());
46039
+ const info = findTableResizeHoverInfo(
46040
+ event,
46041
+ surface,
46042
+ deps.state(),
46043
+ deps.documentLayout(),
46044
+ deps.canvasSnapshotProvider,
46045
+ (_a = deps.zoomFactor) == null ? void 0 : _a.call(deps)
46046
+ );
45440
46047
  if (!info) {
45441
46048
  clearResizeCursorClasses();
45442
46049
  return;
@@ -45444,10 +46051,17 @@ function createEditorTableResize(deps) {
45444
46051
  setHoverCursorClass(info.side === "left" || info.side === "right");
45445
46052
  };
45446
46053
  const handleMouseDown = (event) => {
45447
- var _a;
46054
+ var _a, _b;
45448
46055
  const surface = deps.surfaceRef();
45449
46056
  if (!surface) return false;
45450
- const info = findTableResizeHoverInfo(event, surface, deps.state());
46057
+ const info = findTableResizeHoverInfo(
46058
+ event,
46059
+ surface,
46060
+ deps.state(),
46061
+ deps.documentLayout(),
46062
+ deps.canvasSnapshotProvider,
46063
+ (_a = deps.zoomFactor) == null ? void 0 : _a.call(deps)
46064
+ );
45451
46065
  if (!info) return false;
45452
46066
  const state = deps.state();
45453
46067
  const tableLayout = buildTableCellLayout(info.tableNode);
@@ -45478,7 +46092,7 @@ function createEditorTableResize(deps) {
45478
46092
  maxColumnIndex,
45479
46093
  minColumnWidthsPx,
45480
46094
  resizeFromLeftEdge: isLeftTableEdge,
45481
- initialTableIndentLeftPt: parseSizeToPt((_a = info.tableNode.style) == null ? void 0 : _a.indentLeft) ?? 0,
46095
+ initialTableIndentLeftPt: parseSizeToPt((_b = info.tableNode.style) == null ? void 0 : _b.indentLeft) ?? 0,
45482
46096
  guideBounds: getGuideBounds(deps.viewportRef)
45483
46097
  });
45484
46098
  setActiveCursorClass(true);
@@ -46618,9 +47232,10 @@ function createEditorNavigation(deps) {
46618
47232
  const surfaceRect = (surfaceRef == null ? void 0 : surfaceRef.getBoundingClientRect()) ?? null;
46619
47233
  const preferredX = deps.preferredColumnX();
46620
47234
  const desiredX = preferredX === null ? deps.caretBox().left + ((surfaceRect == null ? void 0 : surfaceRect.left) ?? 0) : preferredX;
46621
- const snapshot = surfaceRef ? buildCanvasLayoutSnapshot({
47235
+ const snapshot = surfaceRef ? deps.canvasSnapshotProvider.getCanvasLayoutSnapshot({
46622
47236
  surface: surfaceRef,
46623
47237
  state,
47238
+ documentLayout: deps.documentLayout(),
46624
47239
  zoomFactor: (_a = deps.zoomFactor) == null ? void 0 : _a.call(deps)
46625
47240
  }) : null;
46626
47241
  let targetIndex = currentIndex + direction;
@@ -46817,7 +47432,9 @@ function useEditorInteractionWiring(ctx) {
46817
47432
  applyTransactionalState: ctx.applyTransactionalState,
46818
47433
  surfaceRef: ctx.surfaceRef,
46819
47434
  viewportRef: ctx.viewportRef,
46820
- zoomFactor: ctx.zoomFactor
47435
+ zoomFactor: ctx.zoomFactor,
47436
+ documentLayout: ctx.documentLayout,
47437
+ canvasSnapshotProvider: ctx.canvasSnapshotProvider
46821
47438
  });
46822
47439
  const tableDrag = createEditorTableDrag({
46823
47440
  state,
@@ -46878,7 +47495,9 @@ function useEditorInteractionWiring(ctx) {
46878
47495
  clearPreferredColumn: ctx.clearPreferredColumn,
46879
47496
  resetTransactionGrouping: ctx.resetTransactionGrouping,
46880
47497
  focusInput: ctx.focusInput,
46881
- zoomFactor: ctx.zoomFactor
47498
+ zoomFactor: ctx.zoomFactor,
47499
+ documentLayout: ctx.documentLayout,
47500
+ canvasSnapshotProvider: ctx.canvasSnapshotProvider
46882
47501
  });
46883
47502
  const { handleCopy, handleCut, handlePaste, handleDrop } = createEditorClipboardController({
46884
47503
  state,
@@ -46930,8 +47549,8 @@ function createEditorInteractionRuntime(deps) {
46930
47549
  caretBox,
46931
47550
  preferredColumnX,
46932
47551
  setPreferredColumnX,
46933
- measuredBlockHeights,
46934
- measuredParagraphLayouts
47552
+ documentLayout,
47553
+ canvasSnapshotProvider
46935
47554
  } = deps;
46936
47555
  const selectedImageRun = () => getSelectedImageRun(state);
46937
47556
  const selectedTextBoxRun = () => getSelectedTextBoxRun(state);
@@ -46945,8 +47564,8 @@ function createEditorInteractionRuntime(deps) {
46945
47564
  state: () => state,
46946
47565
  surfaceRef: () => surfaceRef() ?? null,
46947
47566
  viewportRef: () => viewportRef() ?? null,
46948
- measuredBlockHeights,
46949
- measuredParagraphLayouts,
47567
+ documentLayout,
47568
+ canvasSnapshotProvider,
46950
47569
  zoomFactor
46951
47570
  });
46952
47571
  const resolveSurfaceHitAtPoint = canvasHitResolver.resolveSurfaceHitAtPoint;
@@ -47017,6 +47636,8 @@ function createEditorInteractionRuntime(deps) {
47017
47636
  preferredColumnX: () => preferredColumnX(),
47018
47637
  setPreferredColumnX,
47019
47638
  zoomFactor,
47639
+ documentLayout,
47640
+ canvasSnapshotProvider,
47020
47641
  resolveSurfaceHitAtPoint,
47021
47642
  resolvePositionAtSurfacePoint,
47022
47643
  tableOps,
@@ -50708,6 +51329,8 @@ function OasisEditorApp(props = {}) {
50708
51329
  docIO,
50709
51330
  measuredBlockHeights,
50710
51331
  measuredParagraphLayouts,
51332
+ documentLayout,
51333
+ canvasSnapshotProvider,
50711
51334
  inputBox,
50712
51335
  selectionBoxes,
50713
51336
  commentHighlights,
@@ -50747,8 +51370,8 @@ function OasisEditorApp(props = {}) {
50747
51370
  caretBox,
50748
51371
  preferredColumnX,
50749
51372
  setPreferredColumnX,
50750
- measuredBlockHeights,
50751
- measuredParagraphLayouts
51373
+ documentLayout,
51374
+ canvasSnapshotProvider
50752
51375
  });
50753
51376
  const {
50754
51377
  selectedImageRun,
@@ -50848,6 +51471,7 @@ function OasisEditorApp(props = {}) {
50848
51471
  fileHandlers: editorFileHandlers
50849
51472
  } = buildEditorViewProps({
50850
51473
  layout: {
51474
+ documentLayout,
50851
51475
  viewportHeight: ui().viewportHeight,
50852
51476
  className: ui().class,
50853
51477
  style: ui().style,
@@ -51001,6 +51625,7 @@ function OasisEditorApp(props = {}) {
51001
51625
  viewportHeight: () => ui().viewportHeight,
51002
51626
  measuredBlockHeights,
51003
51627
  measuredParagraphLayouts,
51628
+ documentLayout,
51004
51629
  layout: editorLayoutProps,
51005
51630
  overlays: editorOverlayProps,
51006
51631
  refs: editorRefs,
@@ -51014,6 +51639,11 @@ function OasisEditorApp(props = {}) {
51014
51639
  get surfaceRef() {
51015
51640
  return surfaceRef();
51016
51641
  },
51642
+ documentLayout,
51643
+ snapshotProvider: canvasSnapshotProvider,
51644
+ get zoomFactor() {
51645
+ return zoom.zoomFactor;
51646
+ },
51017
51647
  tableResize,
51018
51648
  imageOps,
51019
51649
  tableDrag,