dropflow
Version:
A small CSS2 document renderer built from specifications
239 lines (238 loc) • 8.42 kB
TypeScript
import { Logger } from './util.js';
import { HTMLElement } from './dom.js';
import { Style } from './style.js';
import { InlineMetrics, Linebox, Paragraph, Run } from './layout-text.js';
import { Box, FormattingBox, RenderItem, PrelayoutContext } from './layout-box.js';
export interface LayoutContext {
/**
* The block formatting context that formats the subject in a layout function.
* This is only undefined for the root box or when an element is out of flow.
*/
bfc?: BlockFormattingContext;
}
export declare class BlockFormattingContext {
inlineSize: number;
fctx?: FloatContext;
stack: (BlockContainer | {
post: BlockContainer;
})[];
cbBlockStart: number;
cbLineLeft: number;
cbLineRight: number;
private sizeStack;
private offsetStack;
private last;
private level;
private hypotheticals;
private margin;
constructor(inlineSize: number);
collapseStart(box: FormattingBox): void;
boxStart(box: BlockContainer, ctx: LayoutContext): void;
boxEnd(box: BlockContainer): void;
boxAtomic(box: FormattingBox): void;
getLocalVacancyForLine(bfc: BlockFormattingContext, blockOffset: number, blockSize: number, vacancy: IfcVacancy): void;
ensureFloatContext(blockOffset: number): FloatContext;
finalize(box: BlockContainer): void;
positionBlockContainers(): void;
}
declare class FloatSide {
items: FormattingBox[];
shelfBlockOffset: number;
shelfTrackIndex: number;
blockOffsets: number[];
inlineSizes: number[];
inlineOffsets: number[];
floatCounts: number[];
constructor(blockOffset: number);
initialize(blockOffset: number): void;
repr(): string;
getSizeOfTracks(start: number, end: number, inlineOffset: number): number;
getOverflow(): number;
getFloatCountOfTracks(start: number, end: number): number;
getEndTrack(start: number, blockOffset: number, blockSize: number): number;
getTrackRange(blockOffset: number, blockSize?: number): [number, number];
getOccupiedSpace(blockOffset: number, blockSize: number, inlineOffset: number): number;
boxStart(blockOffset: number): void;
dropShelf(blockOffset: number): void;
getNextTrackOffset(): number;
getBottom(): number;
splitTrack(trackIndex: number, blockOffset: number): void;
splitIfShelfDropped(): void;
placeFloat(box: FormattingBox, vacancy: IfcVacancy, cbLineLeft: number, cbLineRight: number): void;
}
export declare class IfcVacancy {
leftOffset: number;
rightOffset: number;
inlineSize: number;
blockOffset: number;
leftFloatCount: number;
rightFloatCount: number;
static EPSILON: number;
constructor(leftOffset: number, rightOffset: number, blockOffset: number, inlineSize: number, leftFloatCount: number, rightFloatCount: number);
fits(inlineSize: number): boolean;
hasFloats(): boolean;
}
export declare class FloatContext {
bfc: BlockFormattingContext;
leftFloats: FloatSide;
rightFloats: FloatSide;
misfits: FormattingBox[];
constructor(bfc: BlockFormattingContext, blockOffset: number);
boxStart(): void;
getVacancyForLine(blockOffset: number, blockSize: number): IfcVacancy;
getVacancyForBox(box: FormattingBox, lineWidth: number): IfcVacancy;
getLeftBottom(): number;
getRightBottom(): number;
getBothBottom(): number;
findLinePosition(blockOffset: number, blockSize: number, inlineSize: number): IfcVacancy;
placeFloat(lineWidth: number, lineIsEmpty: boolean, box: FormattingBox): void;
consumeMisfits(): void;
dropShelf(blockOffset: number): void;
postLine(line: Linebox, didBreak: boolean): void;
preTextContent(): void;
}
export interface BlockContainerOfInlines extends BlockContainer {
children: IfcInline[];
}
export type BlockLevel = BlockContainer | ReplacedBox;
export interface BlockContainerOfBlockContainers extends BlockContainer {
children: BlockLevel[];
}
export declare class BlockContainer extends FormattingBox {
children: IfcInline[] | BlockLevel[];
static ATTRS: {
isInline: number;
isBfcRoot: number;
isAnonymous: number;
enableLogging: number;
};
constructor(style: Style, children: IfcInline[] | BlockLevel[], attrs: number);
contribution(mode: 'min-content' | 'max-content'): number;
getLogSymbol(): "◼︎" | "○︎" | "▬";
logName(log: Logger): void;
getContainingBlockToContent(): {
blockStart: number;
lineLeft: number;
lineRight: number;
};
getLastBaseline(): number | undefined;
isBlockContainer(): this is BlockContainer;
isInlineLevel(): boolean;
isBfcRoot(): boolean;
loggingEnabled(): boolean;
isBlockContainerOfInlines(): this is BlockContainerOfInlines;
canCollapseThrough(): boolean;
isBlockContainerOfBlockContainers(): this is BlockContainerOfBlockContainers;
propagate(parent: Box): void;
doTextLayout(ctx: LayoutContext): void;
hasBackground(): boolean;
hasForeground(): boolean;
}
export declare function layoutBlockLevelBox(box: BlockLevel, ctx: LayoutContext): void;
export declare function layoutFloatBox(box: BlockLevel, ctx: LayoutContext): void;
export declare class Break extends RenderItem {
className: string;
isBreak(): this is Break;
getLogSymbol(): string;
logName(log: Logger): void;
propagate(parent: Box): void;
}
export declare class Inline extends Box {
children: InlineLevel[];
nshaped: number;
metrics: InlineMetrics;
start: number;
end: number;
constructor(start: number, end: number, style: Style, children: InlineLevel[], attrs: number);
prelayoutPreorder(ctx: PrelayoutContext): void;
propagate(parent: Box): void;
hasText(): number;
hasSoftWrap(): number;
hasCollapsibleWs(): number;
hasFloatOrReplaced(): number;
hasBreakOrInlineOrReplaced(): number;
hasComplexText(): number;
hasSoftHyphen(): number;
hasNewlines(): number;
hasPaintedInlines(): number;
hasInlineBlocks(): number;
hasSizedInline(): number;
hasColoredInline(): number;
hasLineLeftGap(): boolean | undefined;
hasLineRightGap(): boolean | undefined;
getInlineSideSize(side: 'pre' | 'post'): number;
isInline(): this is Inline;
isInlineLevel(): boolean;
getLogSymbol(): string;
logName(log: Logger): void;
absolutify(): void;
hasBackground(): boolean;
hasForeground(): boolean;
}
export declare class IfcInline extends Inline {
children: InlineLevel[];
text: string;
paragraph: Paragraph;
constructor(style: Style, text: string, children: InlineLevel[], attrs: number);
isIfcInline(): this is IfcInline;
loggingEnabled(): boolean;
prelayoutPostorder(ctx: PrelayoutContext): void;
positionItemsPostlayout(): void;
postlayoutPreorder(): void;
shouldLayoutContent(): number;
doTextLayout(ctx: LayoutContext): void;
}
export declare class ReplacedBox extends FormattingBox {
src: string;
constructor(style: Style, src: string);
isReplacedBox(): this is ReplacedBox;
logName(log: Logger): void;
getLogSymbol(): string;
hasBackground(): boolean;
hasForeground(): boolean;
getImage(): import("./layout-image.js").Image | undefined;
getIntrinsicIsize(): number;
getIntrinsicBsize(): number;
getRatio(): number;
propagate(parent: Box): void;
contribution(): number;
getLastBaseline(): undefined;
getDefiniteInnerInlineSize(): number;
getDefiniteInnerBlockSize(): number;
}
export type InlineLevel = Inline | Run | Break | BlockContainer | ReplacedBox;
type InlineIteratorBuffered = {
state: 'pre' | 'post';
item: Inline;
} | {
state: 'text';
item: Run;
} | {
state: 'box';
item: BlockLevel;
} | {
state: 'break';
} | {
state: 'breakop';
};
type InlineIteratorValue = InlineIteratorBuffered | {
state: 'breakspot';
};
export declare function createInlineIterator(inline: IfcInline): {
next: () => {
done: true;
} | {
done: false;
value: InlineIteratorValue;
};
};
export declare function createPreorderInlineIterator(inline: IfcInline): {
next: () => {
done: true;
} | {
done: false;
value: Inline | Run;
};
};
export declare function generateBlockContainer(el: HTMLElement): BlockContainer;
export {};