import { MarkdownHydrateOptions, MarkdownRenderer, MarkdownSegment } from './markdown-render'; import { SourceDomPoint, SourceRect, BlockMap } from './source-map'; /** * A document rendered as one element per top-level block, for the rich * surface and the preview. * * `patch` re-renders only the blocks whose source changed, so a remote edit * three paragraphs away leaves the caret's block — and the caret — alone. The * rich surface also holds paragraphs that exist only in the DOM: the empty * line Enter just made has no Markdown of its own until something is typed * into it. Those carry an empty `raw` and sit at the end of the block before. */ export interface BlockItem { el: HTMLElement; /** The block's source; '' for an empty paragraph that exists only in the DOM. */ raw: string; type: string; /** Source between the previous non-empty block and this one; '' for empty items. */ gapBefore: string; map: BlockMap | null; } export interface BlockViewOptions { hydrate: () => MarkdownHydrateOptions; /** Called on every element the view creates, after hydration. */ decorate?: (el: HTMLElement, item: BlockItem) => void; } export interface BlockPoint extends SourceDomPoint { item: BlockItem | null; } export declare class BlockView { readonly root: HTMLElement; readonly renderer: MarkdownRenderer; readonly options: BlockViewOptions; items: BlockItem[]; trailing: string; private starts; private docCache; private readonly byElement; private rendererVersion; constructor(root: HTMLElement, renderer: MarkdownRenderer, options: BlockViewOptions); get doc(): string; /** Whether reference definitions or the emoji set changed since the blocks were rendered. */ private rendererChanged; createItem(segment: MarkdownSegment, gapBefore: string): BlockItem; /** Hydrates a freshly rendered element and indexes it. */ prepare(item: BlockItem): void; register(item: BlockItem): void; render(doc: string): void; /** * Brings the view to `doc`, keeping every block whose source is unchanged. * Returns the items that were created. */ patch(doc: string): BlockItem[]; /** * Swaps the given items' elements for fresh renders of their (unchanged) * source — the surface tidying blocks typed into. Blocks render against the * whole document's reference definitions, so this lexes all of it; when * that no longer splits into the same blocks, everything re-renders. * Returns false in that case. */ refresh(targets: BlockItem[]): boolean; /** Re-runs hydration, e.g. once KaTeX has loaded. */ rehydrate(): void; setItems(items: BlockItem[], trailing?: string): void; invalidate(): void; itemFor(el: Element): BlockItem | null; /** The top-level element containing `node`, or null for the root and outside nodes. */ topElement(node: Node | null): HTMLElement | null; itemAt(node: Node | null): BlockItem | null; startOf(item: BlockItem): number; private positions; mapOf(item: BlockItem): BlockMap; domToSource(node: Node, offset: number, bias?: -1 | 1): number; /** The item holding `pos`; a position between blocks belongs to the block before it. */ private locate; sourceToDom(pos: number): BlockPoint; /** Client rects covering the source range, per text run and element. */ rangeRects(from: number, to: number): SourceRect[]; caretRect(pos: number): SourceRect | null; }