import { Arr } from '@ephox/katamari'; import { Height, type SugarElement, SugarLocation, Width, WindowVisualViewport } from '@ephox/sugar'; import * as OuterPosition from '../frame/OuterPosition'; import type { CssPositionAdt } from './CssPosition'; const pointed = (point: CssPositionAdt, width: number, height: number): BoxByPoint => ({ point, width, height }); export interface Rect { readonly x: number; readonly y: number; readonly width: number; readonly height: number; } const rect = (x: number, y: number, width: number, height: number): Rect => ({ x, y, width, height }); export interface Bounds { readonly x: number; readonly y: number; readonly width: number; readonly height: number; readonly right: number; readonly bottom: number; } export interface BoxByPoint { readonly point: CssPositionAdt; readonly width: number; readonly height: number; } const bounds = (x: number, y: number, width: number, height: number): Bounds => ({ x, y, width, height, right: x + width, bottom: y + height }); const box = (element: SugarElement): Bounds => { const xy = SugarLocation.absolute(element); const w = Width.getOuter(element); const h = Height.getOuter(element); return bounds(xy.left, xy.top, w, h); }; // NOTE: We used to use AriaFocus.preserve here, but there is no reason to do that now that // we are not changing the visibility of the element. Hopefully (2015-09-29). const absolute = (element: SugarElement): Bounds => { const position = OuterPosition.find(element); const width = Width.getOuter(element); const height = Height.getOuter(element); return bounds(position.left, position.top, width, height); }; const constrain = (original: Bounds, constraint: Bounds): Bounds => { const left = Math.max(original.x, constraint.x); const top = Math.max(original.y, constraint.y); const right = Math.min(original.right, constraint.right); const bottom = Math.min(original.bottom, constraint.bottom); const width = right - left; const height = bottom - top; return bounds( left, top, width, height ); }; const constrainByMany = (original: Bounds, constraints: Bounds[]): Bounds => { return Arr.foldl( constraints, (acc, c) => constrain(acc, c), original ); }; const win = (): Bounds => WindowVisualViewport.getBounds(window); export { pointed, rect, bounds, box, absolute, win, constrain, constrainByMany };