| 244 | } |
| 245 | |
| 246 | function _getIframeOffset(el?: HTMLElement | null) { |
| 247 | const offset = { top: 0, left: 0 }; |
| 248 | |
| 249 | if (!el) return offset; |
| 250 | |
| 251 | let targetWindow: Window | null = el.ownerDocument.defaultView; |
| 252 | |
| 253 | try { |
| 254 | while (targetWindow && targetWindow !== window.top) { |
| 255 | const targetIframe = targetWindow?.frameElement; |
| 256 | |
| 257 | if (targetIframe) { |
| 258 | const rect = targetIframe.getBoundingClientRect(); |
| 259 | offset.top += rect.top + targetIframe.scrollTop; |
| 260 | offset.left += rect.left + targetIframe.scrollLeft; |
| 261 | } |
| 262 | |
| 263 | targetWindow = targetWindow.parent; |
| 264 | } |
| 265 | } catch { |
| 266 | // Cross-origin iframe — stop traversal and use the offset accumulated so far. |
| 267 | } |
| 268 | |
| 269 | return offset; |
| 270 | } |
| 271 | |
| 272 | function _getVisibleHeight( |
| 273 | el: HTMLElement, |