Groundwork for picking inside a nested same-origin iframe (#17): the
coordinate module learns how a chain of nested iframes composes, and the
frame manager learns that a window or node deeper than a frame's own
document still belongs to that frame.
space.ts gains frameChain/nestOffset/intersectRects and an optional
pre-composed offset on frameToScreen/screenToFrame — translation-only,
since each nested iframe's rect is already in its parent document's
coordinates, so the canvas scale applies once at the outer boundary. An
empty chain composes to zero and the single-level path is byte-identical.
The chain hop prefers frameElement and falls back to scanning the parent
document's iframes (happy-dom implements window.parent but not
frameElement), capped at MAX_NEST_DEPTH everywhere.
frames.ts: frameOf keeps its exact-document fast path and then walks the
window chain; frameOfWindow is the exported form of that walk. A Frame
now carries agents — every agent in its realm tree keyed by window —
while frame.agent stays the root's for every existing reader; a root
re-registration clears the map, because an HMR reload kills the nested
realms with it. onFrameReady hands the shell the agent as well as the
frame, so it can subscribe per realm.
Depth-0 behaviour is unchanged throughout.