import { FlowBlock, Layout, Measure, Fragment, DrawingFragment, ImageFragment, Line, TableFragment, TableBlock, TableMeasure, ParagraphBlock, ParagraphMeasure } from '../../contracts/src/index.js'; import { PageGeometryHelper } from './page-geometry-helper.js'; export type Point = { x: number; y: number; }; export type PageHit = { pageIndex: number; page: Layout['pages'][number]; }; export type FragmentHit = { fragment: Fragment; block: FlowBlock; measure: Measure; pageIndex: number; pageY: number; }; export type PositionHit = { pos: number; layoutEpoch: number; blockId: string; pageIndex: number; column: number; lineIndex: number; }; /** * Result of hit-testing a table fragment. * Contains all information needed to identify the cell and paragraph at a click point. */ export type TableHitResult = { /** The table fragment that was hit */ fragment: TableFragment; /** The table block from the document structure */ block: TableBlock; /** The table measurement data */ measure: TableMeasure; /** Index of the page containing the hit */ pageIndex: number; /** Row index of the hit cell (0-based) */ cellRowIndex: number; /** Column index of the hit cell (0-based) */ cellColIndex: number; /** The paragraph block inside the cell */ cellBlock: ParagraphBlock; /** Measurement data for the paragraph inside the cell */ cellMeasure: ParagraphMeasure; /** X coordinate relative to the cell content area */ localX: number; /** Y coordinate relative to the cell content area */ localY: number; /** * Cumulative line count of preceding paragraph blocks in this cell. * Used by callers to compute the hit paragraph's local first-line flag * when the row continues from a prior page: `isFirstLineOfParagraph` is * `lineIndex === 0 && max(0, cellLineStart - blockStartGlobal) === 0`, * matching `renderTableCell.ts`'s `localStartLine` computation. */ blockStartGlobal: number; }; type AtomicFragment = DrawingFragment | ImageFragment; export type GeometryPageHint = { pageIndex: number; pageRelativeY?: number; }; export type ClickToPositionGeometryOptions = { geometryHelper?: PageGeometryHelper; pageHint?: GeometryPageHint; }; export declare const isAtomicFragment: (fragment: Fragment) => fragment is AtomicFragment; export declare const getAtomicPmRange: (fragment: AtomicFragment, block: FlowBlock) => { pmStart?: number; pmEnd?: number; }; export declare const isRtlBlock: (block: FlowBlock) => boolean; export declare const determineColumn: (layout: Layout, fragmentX: number) => number; /** * Finds the line index at a given Y offset within a set of lines. */ export declare const findLineIndexAtY: (lines: Line[], offsetY: number, fromLine: number, toLine: number) => number | null; /** * Maps an X coordinate within a line to a ProseMirror position. */ export declare const mapPointToPm: (block: FlowBlock, line: Line, x: number, isRTL: boolean, availableWidthOverride?: number, alignmentOverride?: string) => number | null; /** * Finds the nearest paragraph or atomic fragment to a point on a page. */ export declare function snapToNearestFragment(pageHit: PageHit, blocks: FlowBlock[], measures: Measure[], pageRelativePoint: Point): FragmentHit | null; /** * Find a block by fragment blockId, handling continuation fragments. * When paragraphs split across pages, continuation fragments get suffixed IDs * (e.g., "5-paragraph-1") while the blocks array uses the base ID ("5-paragraph"). */ export declare function findBlockIndexByFragmentId(blocks: FlowBlock[], fragmentBlockId: string, targetPmRange?: { from: number; to: number; }): number; /** * Calculates cumulative Y position for a page (fallback when no geometry helper provided). */ export declare const calculatePageTopFallback: (layout: Layout, pageIndex: number) => number; /** * Find the page hit given layout and a coordinate relative to the layout container. * Accounts for gaps between pages when calculating page boundaries. */ export declare function hitTestPage(layout: Layout, point: Point, geometryHelper?: PageGeometryHelper): PageHit | null; /** * Hit-test fragments within a page for a given point (page-relative coordinates). */ export declare function hitTestFragment(layout: Layout, pageHit: PageHit, blocks: FlowBlock[], measures: Measure[], point: Point): FragmentHit | null; export declare const hitTestAtomicFragment: (pageHit: PageHit, blocks: FlowBlock[], measures: Measure[], point: Point) => FragmentHit | null; /** * Hit-test table fragments to find the cell and paragraph at a click point. */ export declare const hitTestTableFragment: (pageHit: PageHit, blocks: FlowBlock[], measures: Measure[], point: Point) => TableHitResult | null; /** * Enriches a DOM-resolved PM position into a full PositionHit by searching layout * metadata. Pure data lookup — no DOM reads. * * Extracted from the DOM-success path of the original `clickToPosition()`. */ export declare function resolvePositionHitFromDomPosition(layout: Layout, blocks: FlowBlock[], measures: Measure[], domPos: number, layoutEpoch: number): PositionHit; /** * Geometry-only hit testing. DOM-free — no `elementsFromPoint`, no `getBoundingClientRect`. * * When `options.pageHint` is provided, uses the hint's page index and optional * page-relative Y instead of recomputing from geometry. This allows callers that * have already done DOM page detection to pass their result through. * * Extracted from the geometry fallback path of the original `clickToPosition()`. */ export declare function clickToPositionGeometry(layout: Layout, blocks: FlowBlock[], measures: Measure[], containerPoint: Point, options?: ClickToPositionGeometryOptions): PositionHit | null; export {}; //# sourceMappingURL=position-hit.d.ts.map