From af974ca4d95123278436a02dc5f5494dfa239fc4 Mon Sep 17 00:00:00 2001 From: Tadeu Tupinamba Date: Wed, 15 Apr 2026 16:57:50 -0300 Subject: [PATCH] refactor(painter): deliver resolved items to decoration provider callback --- .../painters/dom/src/renderer.ts | 48 ++++++++---- .../HeaderFooterSessionManager.ts | 77 +++++++++++++++++- .../tests/HeaderFooterSessionManager.test.ts | 78 +++++++++++++++++++ .../PresentationEditor.collaboration.test.ts | 1 + .../PresentationEditor.decorationSync.test.ts | 1 + .../PresentationEditor.draggableFocus.test.ts | 1 + .../PresentationEditor.focusWrapping.test.ts | 1 + ...sentationEditor.footnotesPmMarkers.test.ts | 1 + ...entationEditor.getCurrentPageIndex.test.ts | 1 + ...PresentationEditor.getElementAtPos.test.ts | 1 + .../PresentationEditor.goToAnchor.test.ts | 1 + .../tests/PresentationEditor.media.test.ts | 1 + ...resentationEditor.scrollToPosition.test.ts | 1 + ...esentationEditor.sectionPageStyles.test.ts | 1 + .../tests/PresentationEditor.test.ts | 1 + .../tests/PresentationEditor.zoom.test.ts | 1 + 16 files changed, 198 insertions(+), 18 deletions(-) diff --git a/packages/layout-engine/painters/dom/src/renderer.ts b/packages/layout-engine/painters/dom/src/renderer.ts index 05c754e740..6a67feaab7 100644 --- a/packages/layout-engine/painters/dom/src/renderer.ts +++ b/packages/layout-engine/painters/dom/src/renderer.ts @@ -268,6 +268,9 @@ type OptionalBlockMeasurePair = { type PageDecorationPayload = { fragments: Fragment[]; + /** Resolved items aligned 1:1 with `fragments`. Same length, same order. + * Absent when provider has no resolved data (painter falls back to blockLookup). */ + items?: ResolvedPaintItem[]; height: number; /** Optional measured content height to aid bottom alignment in footers. */ contentHeight?: number; @@ -2334,16 +2337,13 @@ export class DomPainter { * Used to determine special Y positioning for page-relative anchored media * in header/footer decoration sections. */ - private isPageRelativeAnchoredFragment(fragment: Fragment): boolean { + private isPageRelativeAnchoredFragment(fragment: Fragment, resolvedItem?: ResolvedPaintItem): boolean { if (fragment.kind !== 'image' && fragment.kind !== 'drawing') { return false; } - const lookup = this.blockLookup.get(fragment.blockId); - if (!lookup) { - return false; - } - const block = lookup.block; - if (block.kind !== 'image' && block.kind !== 'drawing') { + const resolvedBlock = resolvedItem && 'block' in resolvedItem ? resolvedItem.block : undefined; + const block = resolvedBlock ?? this.blockLookup.get(fragment.blockId)?.block; + if (!block || (block.kind !== 'image' && block.kind !== 'drawing')) { return false; } return block.anchor?.vRelativeFrom === 'page'; @@ -2463,9 +2463,10 @@ export class DomPainter { const contentHeight = typeof data.contentHeight === 'number' ? data.contentHeight - : data.fragments.reduce((max, f) => { + : data.fragments.reduce((max, f, fi) => { + const resolvedItem = data.items?.[fi]; const fragHeight = - 'height' in f && typeof f.height === 'number' ? f.height : this.estimateFragmentHeight(f); + 'height' in f && typeof f.height === 'number' ? f.height : this.estimateFragmentHeight(f, resolvedItem); return Math.max(max, f.y + Math.max(0, fragHeight)); }, 0); // Offset to push content to bottom of container @@ -2482,7 +2483,7 @@ export class DomPainter { }; // Compute between-border flags for header/footer paragraph fragments - const betweenBorderFlags = computeBetweenBorderFlags(data.fragments, this.blockLookup); + const betweenBorderFlags = computeBetweenBorderFlags(data.fragments, this.blockLookup, data.items); // Separate behindDoc fragments from normal fragments. // Prefer explicit fragment.behindDoc when present. Keep zIndex===0 as a @@ -2517,8 +2518,15 @@ export class DomPainter { // By inserting at the beginning and using z-index: 0, they render below body content // which also has z-index values but comes later in DOM order. behindDocFragments.forEach(({ fragment, originalIndex }) => { - const fragEl = this.renderFragment(fragment, context, undefined, betweenBorderFlags.get(originalIndex)); - const isPageRelative = this.isPageRelativeAnchoredFragment(fragment); + const resolvedItem = data.items?.[originalIndex]; + const fragEl = this.renderFragment( + fragment, + context, + undefined, + betweenBorderFlags.get(originalIndex), + resolvedItem, + ); + const isPageRelative = this.isPageRelativeAnchoredFragment(fragment, resolvedItem); let pageY: number; if (isPageRelative && kind === 'footer') { @@ -2541,8 +2549,15 @@ export class DomPainter { // Render normal fragments in the header/footer container normalFragments.forEach(({ fragment, originalIndex }) => { - const fragEl = this.renderFragment(fragment, context, undefined, betweenBorderFlags.get(originalIndex)); - const isPageRelative = this.isPageRelativeAnchoredFragment(fragment); + const resolvedItem = data.items?.[originalIndex]; + const fragEl = this.renderFragment( + fragment, + context, + undefined, + betweenBorderFlags.get(originalIndex), + resolvedItem, + ); + const isPageRelative = this.isPageRelativeAnchoredFragment(fragment, resolvedItem); if (isPageRelative && kind === 'footer') { // Footer page-relative: fragment.y is normalized to band-local coords @@ -6670,7 +6685,10 @@ export class DomPainter { * @param fragment - The fragment to estimate height for * @returns Estimated height in pixels, or 0 if height cannot be determined */ - private estimateFragmentHeight(fragment: Fragment): number { + private estimateFragmentHeight(fragment: Fragment, resolvedItem?: ResolvedPaintItem): number { + if (resolvedItem && 'height' in resolvedItem && typeof resolvedItem.height === 'number') { + return resolvedItem.height; + } const lookup = this.blockLookup.get(fragment.blockId); const measure = lookup?.measure; diff --git a/packages/super-editor/src/editors/v1/core/presentation-editor/header-footer/HeaderFooterSessionManager.ts b/packages/super-editor/src/editors/v1/core/presentation-editor/header-footer/HeaderFooterSessionManager.ts index 698f155d34..a667767e66 100644 --- a/packages/super-editor/src/editors/v1/core/presentation-editor/header-footer/HeaderFooterSessionManager.ts +++ b/packages/super-editor/src/editors/v1/core/presentation-editor/header-footer/HeaderFooterSessionManager.ts @@ -11,8 +11,17 @@ * @module presentation-editor/header-footer/HeaderFooterSessionManager */ -import type { Layout, FlowBlock, Measure, Page, SectionMetadata, Fragment } from '@superdoc/contracts'; +import type { + Layout, + FlowBlock, + Measure, + Page, + SectionMetadata, + Fragment, + ResolvedHeaderFooterLayout, +} from '@superdoc/contracts'; import type { PageDecorationProvider } from '@superdoc/painter-dom'; +import { resolveHeaderFooterLayout } from '@superdoc/layout-resolved'; import type { Editor } from '../../Editor.js'; import type { @@ -176,6 +185,19 @@ export type SessionManagerCallbacks = { }) => void; }; +// ============================================================================= +// Helpers +// ============================================================================= + +/** + * Resolve a `HeaderFooterLayoutResult` into a `ResolvedHeaderFooterLayout`. + * Paired with the originals so the decoration provider can deliver aligned + * `items` alongside `fragments`. + */ +function resolveResult(result: HeaderFooterLayoutResult): ResolvedHeaderFooterLayout { + return resolveHeaderFooterLayout(result.layout, result.blocks, result.measures); +} + // ============================================================================= // HeaderFooterSessionManager // ============================================================================= @@ -203,6 +225,12 @@ export class HeaderFooterSessionManager { #headerLayoutsByRId: Map = new Map(); #footerLayoutsByRId: Map = new Map(); + // Resolved layouts (aligned 1:1 with the results above) + #resolvedHeaderLayouts: ResolvedHeaderFooterLayout[] | null = null; + #resolvedFooterLayouts: ResolvedHeaderFooterLayout[] | null = null; + #resolvedHeaderByRId: Map = new Map(); + #resolvedFooterByRId: Map = new Map(); + // Decoration providers #headerDecorationProvider: PageDecorationProvider | undefined; #footerDecorationProvider: PageDecorationProvider | undefined; @@ -331,6 +359,7 @@ export class HeaderFooterSessionManager { /** Set header layout results */ set headerLayoutResults(results: HeaderFooterLayoutResult[] | null) { this.#headerLayoutResults = results; + this.#resolvedHeaderLayouts = results ? results.map(resolveResult) : null; } /** Footer layout results */ @@ -341,6 +370,7 @@ export class HeaderFooterSessionManager { /** Set footer layout results */ set footerLayoutResults(results: HeaderFooterLayoutResult[] | null) { this.#footerLayoutResults = results; + this.#resolvedFooterLayouts = results ? results.map(resolveResult) : null; } /** Header layouts by rId */ @@ -431,6 +461,8 @@ export class HeaderFooterSessionManager { ): void { this.#headerLayoutResults = headerResults; this.#footerLayoutResults = footerResults; + this.#resolvedHeaderLayouts = headerResults ? headerResults.map(resolveResult) : null; + this.#resolvedFooterLayouts = footerResults ? footerResults.map(resolveResult) : null; } /** @@ -1274,10 +1306,20 @@ export class HeaderFooterSessionManager { layout: Layout, sectionMetadata: SectionMetadata[], ): Promise { - return await layoutPerRIdHeaderFooters(headerFooterInput, layout, sectionMetadata, { + await layoutPerRIdHeaderFooters(headerFooterInput, layout, sectionMetadata, { headerLayoutsByRId: this.#headerLayoutsByRId, footerLayoutsByRId: this.#footerLayoutsByRId, }); + + // Rebuild resolved maps aligned 1:1 with the raw rId maps. + this.#resolvedHeaderByRId.clear(); + for (const [key, result] of this.#headerLayoutsByRId) { + this.#resolvedHeaderByRId.set(key, resolveResult(result)); + } + this.#resolvedFooterByRId.clear(); + for (const [key, result] of this.#footerLayoutsByRId) { + this.#resolvedFooterByRId.set(key, resolveResult(result)); + } } #computeMetrics( @@ -1578,6 +1620,8 @@ export class HeaderFooterSessionManager { createDecorationProvider(kind: 'header' | 'footer', layout: Layout): PageDecorationProvider | undefined { const results = kind === 'header' ? this.#headerLayoutResults : this.#footerLayoutResults; const layoutsByRId = kind === 'header' ? this.#headerLayoutsByRId : this.#footerLayoutsByRId; + const resolvedResults = kind === 'header' ? this.#resolvedHeaderLayouts : this.#resolvedFooterLayouts; + const resolvedByRId = kind === 'header' ? this.#resolvedHeaderByRId : this.#resolvedFooterByRId; if ((!results || results.length === 0) && (!layoutsByRId || layoutsByRId.size === 0)) { return undefined; @@ -1652,6 +1696,15 @@ export class HeaderFooterSessionManager { const slotPage = this.#findPageForNumber(rIdLayout.layout.pages, pageNumber); if (slotPage) { const fragments = slotPage.fragments ?? []; + const resolvedLayout = resolvedByRId.get(rIdLayoutKey); + const resolvedSlotPage = resolvedLayout?.pages.find((p) => p.number === slotPage.number); + const resolvedItems = resolvedSlotPage?.items; + if (resolvedItems && resolvedItems.length !== fragments.length) { + console.warn( + `[HeaderFooterSessionManager] Resolved items length (${resolvedItems.length}) does not match fragments length (${fragments.length}) for rId '${rIdLayoutKey}' page ${pageNumber}. Dropping items.`, + ); + } + const alignedItems = resolvedItems && resolvedItems.length === fragments.length ? resolvedItems : undefined; const pageHeight = page?.size?.h ?? layout.pageSize?.h ?? layoutOptions.pageSize?.h ?? defaultPageSize.h; const margins = pageMargins ?? layout.pages[0]?.margins ?? layoutOptions.margins ?? defaultMargins; const decorationMargins = @@ -1671,6 +1724,7 @@ export class HeaderFooterSessionManager { return { fragments: normalizedFragments, + items: alignedItems, height: metrics.containerHeight, contentHeight: metrics.layoutHeight > 0 ? metrics.layoutHeight : metrics.containerHeight, offset: metrics.offset, @@ -1691,7 +1745,8 @@ export class HeaderFooterSessionManager { return null; } - const variant = results.find((entry) => entry.type === headerFooterType); + const variantIndex = results.findIndex((entry) => entry.type === headerFooterType); + const variant = variantIndex >= 0 ? results[variantIndex] : undefined; if (!variant || !variant.layout?.pages?.length) { return null; } @@ -1702,6 +1757,17 @@ export class HeaderFooterSessionManager { } const fragments = slotPage.fragments ?? []; + const resolvedVariant = resolvedResults?.[variantIndex]; + const resolvedVariantPage = resolvedVariant?.pages.find((p) => p.number === slotPage.number); + const resolvedVariantItems = resolvedVariantPage?.items; + if (resolvedVariantItems && resolvedVariantItems.length !== fragments.length) { + console.warn( + `[HeaderFooterSessionManager] Resolved items length (${resolvedVariantItems.length}) does not match fragments length (${fragments.length}) for variant '${headerFooterType}' page ${pageNumber}. Dropping items.`, + ); + } + const alignedVariantItems = + resolvedVariantItems && resolvedVariantItems.length === fragments.length ? resolvedVariantItems : undefined; + const pageHeight = page?.size?.h ?? layout.pageSize?.h ?? layoutOptions.pageSize?.h ?? defaultPageSize.h; const margins = pageMargins ?? layout.pages[0]?.margins ?? layoutOptions.margins ?? defaultMargins; const decorationMargins = @@ -1718,6 +1784,7 @@ export class HeaderFooterSessionManager { return { fragments: normalizedFragments, + items: alignedVariantItems, height: metrics.containerHeight, contentHeight: metrics.layoutHeight > 0 ? metrics.layoutHeight : metrics.containerHeight, offset: metrics.offset, @@ -1798,6 +1865,10 @@ export class HeaderFooterSessionManager { this.#footerLayoutResults = null; this.#headerLayoutsByRId.clear(); this.#footerLayoutsByRId.clear(); + this.#resolvedHeaderLayouts = null; + this.#resolvedFooterLayouts = null; + this.#resolvedHeaderByRId.clear(); + this.#resolvedFooterByRId.clear(); // Clear decoration providers this.#headerDecorationProvider = undefined; diff --git a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/HeaderFooterSessionManager.test.ts b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/HeaderFooterSessionManager.test.ts index 525cb6d327..72ab196e8c 100644 --- a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/HeaderFooterSessionManager.test.ts +++ b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/HeaderFooterSessionManager.test.ts @@ -9,6 +9,8 @@ vi.mock('../../header-footer/HeaderFooterRegistryInit.js', () => ({ })); import type { Editor } from '../../Editor.js'; +import type { FlowBlock, HeaderFooterLayout, Layout, Measure, ParaFragment } from '@superdoc/contracts'; +import type { HeaderFooterLayoutResult } from '@superdoc/layout-bridge'; import { HeaderFooterSessionManager, type SessionManagerDependencies, @@ -261,4 +263,80 @@ describe('HeaderFooterSessionManager', () => { expect(manager.computeSelectionRects(1, 10)).toEqual([{ pageIndex: 1, x: 60, y: 870, width: 200, height: 32 }]); }); + + describe('createDecorationProvider — resolved items', () => { + function buildHeaderResult(): HeaderFooterLayoutResult { + const paraFragment: ParaFragment = { + kind: 'para', + blockId: 'p1', + fromLine: 0, + toLine: 1, + x: 72, + y: 10, + width: 468, + }; + const layout: HeaderFooterLayout = { + height: 50, + pages: [{ number: 1, fragments: [paraFragment] }], + }; + const blocks: FlowBlock[] = [{ kind: 'paragraph', id: 'p1', runs: [] }]; + const measures: Measure[] = [ + { + kind: 'paragraph', + lines: [{ fromRun: 0, fromChar: 0, toRun: 0, toChar: 5, width: 100, ascent: 10, descent: 3, lineHeight: 18 }], + totalHeight: 18, + }, + ]; + return { kind: 'header', type: 'default', layout, blocks, measures }; + } + + it('delivers items aligned 1:1 with fragments when variant layout is used', () => { + const deps: SessionManagerDependencies = { + getLayoutOptions: vi.fn(() => ({})), + getPageElement: vi.fn(() => null), + scrollPageIntoView: vi.fn(), + waitForPageMount: vi.fn(async () => true), + convertPageLocalToOverlayCoords: vi.fn(() => ({ x: 0, y: 0 })), + isViewLocked: vi.fn(() => false), + getBodyPageHeight: vi.fn(() => 800), + notifyInputBridgeTargetChanged: vi.fn(), + scheduleRerender: vi.fn(), + setPendingDocChange: vi.fn(), + getBodyPageCount: vi.fn(() => 1), + }; + + manager = new HeaderFooterSessionManager({ + painterHost, + visibleHost, + selectionOverlay, + editor: createMainEditorStub(), + defaultPageSize: { w: 612, h: 792 }, + defaultMargins: { top: 72, right: 72, bottom: 72, left: 72, header: 36, footer: 36 }, + }); + manager.setDependencies(deps); + manager.headerFooterIdentifier = { + headerIds: { default: 'rId-header-default', first: null, even: null, odd: null }, + footerIds: { default: null, first: null, even: null, odd: null }, + titlePg: false, + alternateHeaders: false, + }; + manager.setLayoutResults([buildHeaderResult()], null); + + const layout: Layout = { + version: 1, + flowMode: 'paginated', + pageGap: 0, + pageSize: { w: 612, h: 792 }, + pages: [{ number: 1, margins: { top: 72, right: 72, bottom: 72, left: 72, header: 36, footer: 36 } } as never], + } as unknown as Layout; + const provider = manager.createDecorationProvider('header', layout); + expect(provider).toBeDefined(); + const payload = provider!(1, layout.pages[0]!.margins, layout.pages[0]); + expect(payload).not.toBeNull(); + expect(payload!.fragments).toHaveLength(1); + expect(payload!.items).toBeDefined(); + expect(payload!.items!.length).toBe(payload!.fragments.length); + expect(payload!.items![0]!.blockId).toBe('p1'); + }); + }); }); diff --git a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.collaboration.test.ts b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.collaboration.test.ts index 6556b41d39..720e979de7 100644 --- a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.collaboration.test.ts +++ b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.collaboration.test.ts @@ -186,6 +186,7 @@ vi.mock('y-prosemirror', () => ({ vi.mock('@superdoc/layout-resolved', () => ({ resolveLayout: vi.fn(() => ({ version: 1, flowMode: 'paginated', pageGap: 0, pages: [] })), + resolveHeaderFooterLayout: vi.fn(() => ({ height: 0, pages: [] })), })); /** diff --git a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.decorationSync.test.ts b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.decorationSync.test.ts index da0f0fc702..37b37bfa45 100644 --- a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.decorationSync.test.ts +++ b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.decorationSync.test.ts @@ -280,6 +280,7 @@ vi.mock('../../header-footer/EditorOverlayManager.js', () => ({ vi.mock('@superdoc/layout-resolved', () => ({ resolveLayout: vi.fn(() => ({ version: 1, flowMode: 'paginated', pageGap: 0, pages: [] })), + resolveHeaderFooterLayout: vi.fn(() => ({ height: 0, pages: [] })), })); /** diff --git a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.draggableFocus.test.ts b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.draggableFocus.test.ts index 2dcff9abe3..3b70896003 100644 --- a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.draggableFocus.test.ts +++ b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.draggableFocus.test.ts @@ -202,6 +202,7 @@ vi.mock('../../header-footer/EditorOverlayManager.js', () => ({ vi.mock('@superdoc/layout-resolved', () => ({ resolveLayout: vi.fn(() => ({ version: 1, flowMode: 'paginated', pageGap: 0, pages: [] })), + resolveHeaderFooterLayout: vi.fn(() => ({ height: 0, pages: [] })), })); describe('PresentationEditor - Draggable Annotation Focus Suppression (SD-1179)', () => { diff --git a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.focusWrapping.test.ts b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.focusWrapping.test.ts index 49e81ea373..edc977cfd5 100644 --- a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.focusWrapping.test.ts +++ b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.focusWrapping.test.ts @@ -217,6 +217,7 @@ vi.mock('../../header-footer/EditorOverlayManager.js', () => ({ vi.mock('@superdoc/layout-resolved', () => ({ resolveLayout: vi.fn(() => ({ version: 1, flowMode: 'paginated', pageGap: 0, pages: [] })), + resolveHeaderFooterLayout: vi.fn(() => ({ height: 0, pages: [] })), })); describe('PresentationEditor - Focus Wrapping (#wrapHiddenEditorFocus)', () => { diff --git a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.footnotesPmMarkers.test.ts b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.footnotesPmMarkers.test.ts index f2fcdad938..4fe816cc87 100644 --- a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.footnotesPmMarkers.test.ts +++ b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.footnotesPmMarkers.test.ts @@ -113,6 +113,7 @@ vi.mock('@superdoc/measuring-dom', () => ({ measureBlock: vi.fn(() => ({ width: vi.mock('@superdoc/layout-resolved', () => ({ resolveLayout: mockResolveLayout, + resolveHeaderFooterLayout: vi.fn(() => ({ height: 0, pages: [] })), })); vi.mock('../../header-footer/HeaderFooterRegistry', () => ({ diff --git a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.getCurrentPageIndex.test.ts b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.getCurrentPageIndex.test.ts index da8016ae70..43952f86e3 100644 --- a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.getCurrentPageIndex.test.ts +++ b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.getCurrentPageIndex.test.ts @@ -270,6 +270,7 @@ vi.mock('../../header-footer/EditorOverlayManager', () => ({ vi.mock('@superdoc/layout-resolved', () => ({ resolveLayout: vi.fn(() => ({ version: 1, flowMode: 'paginated', pageGap: 0, pages: [] })), + resolveHeaderFooterLayout: vi.fn(() => ({ height: 0, pages: [] })), })); /** diff --git a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.getElementAtPos.test.ts b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.getElementAtPos.test.ts index f3753dd292..44b8833b16 100644 --- a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.getElementAtPos.test.ts +++ b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.getElementAtPos.test.ts @@ -184,6 +184,7 @@ vi.mock('../../header-footer/EditorOverlayManager.js', () => ({ vi.mock('@superdoc/layout-resolved', () => ({ resolveLayout: vi.fn(() => ({ version: 1, flowMode: 'paginated', pageGap: 0, pages: [] })), + resolveHeaderFooterLayout: vi.fn(() => ({ height: 0, pages: [] })), })); describe('PresentationEditor.getElementAtPos', () => { diff --git a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.goToAnchor.test.ts b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.goToAnchor.test.ts index cf12ec716b..b75b0eb138 100644 --- a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.goToAnchor.test.ts +++ b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.goToAnchor.test.ts @@ -258,6 +258,7 @@ vi.mock('../../header-footer/EditorOverlayManager', () => ({ vi.mock('@superdoc/layout-resolved', () => ({ resolveLayout: vi.fn(() => ({ version: 1, flowMode: 'paginated', pageGap: 0, pages: [] })), + resolveHeaderFooterLayout: vi.fn(() => ({ height: 0, pages: [] })), })); describe('PresentationEditor - goToAnchor', () => { diff --git a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.media.test.ts b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.media.test.ts index f39000cec9..a1dafcff95 100644 --- a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.media.test.ts +++ b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.media.test.ts @@ -128,6 +128,7 @@ vi.mock('y-prosemirror', () => ({ vi.mock('@superdoc/layout-resolved', () => ({ resolveLayout: vi.fn(() => ({ version: 1, flowMode: 'paginated', pageGap: 0, pages: [] })), + resolveHeaderFooterLayout: vi.fn(() => ({ height: 0, pages: [] })), })); describe('SD-1313: toFlowBlocks receives media from storage.image.media', () => { diff --git a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.scrollToPosition.test.ts b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.scrollToPosition.test.ts index d10f93e3ec..08aea2d32f 100644 --- a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.scrollToPosition.test.ts +++ b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.scrollToPosition.test.ts @@ -275,6 +275,7 @@ vi.mock('../../header-footer/EditorOverlayManager', () => ({ vi.mock('@superdoc/layout-resolved', () => ({ resolveLayout: vi.fn(() => ({ version: 1, flowMode: 'paginated', pageGap: 0, pages: [] })), + resolveHeaderFooterLayout: vi.fn(() => ({ height: 0, pages: [] })), })); describe('PresentationEditor - scrollToPosition', () => { diff --git a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.sectionPageStyles.test.ts b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.sectionPageStyles.test.ts index 2066d959f4..28a2da6a98 100644 --- a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.sectionPageStyles.test.ts +++ b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.sectionPageStyles.test.ts @@ -270,6 +270,7 @@ vi.mock('../../header-footer/EditorOverlayManager', () => ({ vi.mock('@superdoc/layout-resolved', () => ({ resolveLayout: vi.fn(() => ({ version: 1, flowMode: 'paginated', pageGap: 0, pages: [] })), + resolveHeaderFooterLayout: vi.fn(() => ({ height: 0, pages: [] })), })); /** diff --git a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.test.ts b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.test.ts index e7f3e45202..e15d1eb62f 100644 --- a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.test.ts +++ b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.test.ts @@ -317,6 +317,7 @@ vi.mock('@superdoc/measuring-dom', () => ({ vi.mock('@superdoc/layout-resolved', () => ({ resolveLayout: mockResolveLayout, + resolveHeaderFooterLayout: vi.fn(() => ({ height: 0, pages: [] })), })); vi.mock('@extensions/pagination/pagination-helpers.js', () => ({ diff --git a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.zoom.test.ts b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.zoom.test.ts index 221aaf00a0..4020a94542 100644 --- a/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.zoom.test.ts +++ b/packages/super-editor/src/editors/v1/core/presentation-editor/tests/PresentationEditor.zoom.test.ts @@ -289,6 +289,7 @@ vi.mock('../../header-footer/EditorOverlayManager', () => ({ vi.mock('@superdoc/layout-resolved', () => ({ resolveLayout: vi.fn(() => ({ version: 1, flowMode: 'paginated', pageGap: 0, pages: [] })), + resolveHeaderFooterLayout: vi.fn(() => ({ height: 0, pages: [] })), })); describe('PresentationEditor - Zoom Functionality', () => {