import { Optional } from '@ephox/katamari'; import { Compare, Scroll, SugarElement, SugarLocation, type SugarPosition, Traverse } from '@ephox/sugar'; import * as CssPosition from '../../alien/CssPosition'; import type { AlloyComponent } from '../../api/component/ComponentApi'; import type { OriginAdt } from '../layout/Origins'; import type { NodeAnchor, SelectionAnchor } from './Anchoring'; // In one mode, the window is inside an iframe. If that iframe is in the // same document as the positioning element (component), then identify the offset // difference between the iframe and the component. const getOffset = (component: AlloyComponent, origin: OriginAdt, anchorInfo: I): Optional => { const win = Traverse.defaultView(anchorInfo.root).dom; const hasSameOwner = (frame: SugarElement) => { const frameOwner = Traverse.owner(frame); const compOwner = Traverse.owner(component.element); return Compare.eq(frameOwner, compOwner); }; return Optional.from(win.frameElement as HTMLFrameElement).map(SugarElement.fromDom) .filter(hasSameOwner).map(SugarLocation.absolute); }; const getRootPoint = (component: AlloyComponent, origin: OriginAdt, anchorInfo: I): CssPosition.CssPositionAdt => { const doc = Traverse.owner(component.element); const outerScroll = Scroll.get(doc); const offset = getOffset(component, origin, anchorInfo).getOr(outerScroll); return CssPosition.absolute(offset, outerScroll.left, outerScroll.top); }; export { getRootPoint };