fix: support preview annotations in same-origin iframes#3237
fix: support preview annotations in same-origin iframes#3237StiensWout wants to merge 5 commits into
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ApprovabilityVerdict: Needs human review This PR introduces significant new capability (iframe annotation support) with ~480 lines of new logic including recursive document traversal, pointer capture, and wheel event proxying. Additionally, there are 4 unresolved review comments identifying potential bugs in the wheel handling and URL attribution for iframe elements. You can customize Macroscope's approvability policy. Learn more. |
| deltaX: event.deltaX, | ||
| deltaY: event.deltaY, | ||
| }; | ||
| }; |
There was a problem hiding this comment.
Top-frame wheel delta scaling
Medium Severity
The normalizeWheelDelta function incorrectly scales DOM_DELTA_LINE and DOM_DELTA_PAGE wheel events using the top-level document's metrics. This leads to nested same-origin iframes scrolling by the parent's calculated pixel delta instead of their own viewport-relative values.
Reviewed by Cursor Bugbot for commit 2bc5b04. Configure here.
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
2bc5b04 to
5c01d2e
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 3 potential issues.
There are 4 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 5c01d2e. Configure here.
| } finally { | ||
| captureSurface.style.pointerEvents = previousPointerEvents; | ||
| } | ||
| }; |
There was a problem hiding this comment.
Cross-origin iframe wheel blocked
Medium Severity
The new full-screen captureSurface handles all wheel input, and scrolling depends on scrollDocumentAtPoint, which only enters frames via getAccessibleFrameDocument. Cross-origin iframe documents stay inaccessible, so wheel gestures over embedded cross-origin content no longer scroll that content (and may scroll the top page instead), unlike before when the overlay did not intercept wheel events.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 5c01d2e. Configure here.
| }; | ||
|
|
||
| const removeSelected = (target: SelectedElement): void => { | ||
| if (target.element instanceof HTMLElement || target.element instanceof SVGElement) { |
There was a problem hiding this comment.
Iframe picks use top page URL
Low Severity
Elements selected inside a same-origin iframe still get pageUrl and pageTitle from the top-frame location and document.title in captureElement and the annotation payload. Downstream consumers can associate iframe-local selectors and stack frames with the wrong page after this iframe picking support.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 5c01d2e. Configure here.
| const previousX = view.scrollX; | ||
| const previousY = view.scrollY; | ||
| view.scrollBy({ left: deltaX, top: deltaY, behavior: "auto" }); | ||
| return view.scrollX !== previousX || view.scrollY !== previousY; |
There was a problem hiding this comment.
Wheel scrolls parent through iframe
Medium Severity
In scrollDocumentAtPoint, when the pointer is over an accessible iframe’s content and nested scrolling does not consume the wheel delta, the loop keeps walking elementsFromPoint hits below the iframe and may scroll parent scrollables or the parent defaultView. That can move the top document while the cursor is over iframe content, which conflicts with treating iframe regions as the interaction surface.
Reviewed by Cursor Bugbot for commit 5c01d2e. Configure here.


Summary
Root cause
The picker listened for pointer events and used
document.elementsFromPointonly in the top document. Pointer events over iframe content were delivered to the frame instead, so the top picker never saw the interaction and could not show the selection editor for elements inside same-origin/srcdoc iframes.Impact
Preview annotations can now select elements inside accessible same-origin/srcdoc iframes while preserving a single top-frame toolbar/editor and the existing preview webview security preferences. Drawing and region workflows still operate from the top overlay, including over iframe areas.
Validation
PATH="$HOME/.vite-plus/bin:$PATH" vp run --filter @t3tools/desktop typecheckPATH="$HOME/.vite-plus/bin:$PATH" vp run --filter @t3tools/desktop testPATH="$HOME/.vite-plus/bin:$PATH" vp checkPATH="$HOME/.vite-plus/bin:$PATH" vp run typecheckvp checkreports the repository's existing unrelated warnings and no errors.Closes #3141
Note
Medium Risk
Large change to preview preload pointer/wheel/scroll behavior and coordinate math; regressions could affect top-frame-only flows, cross-origin iframe edge cases, or teardown of frame scroll listeners.
Overview
Preview element picking now works for same-origin / srcdoc iframes while the annotation UI stays in the top document. Hit testing recurses into accessible frame documents (
pickFromDocument), skips opaque cross-origin frames (treats the iframe as the target), and maps element geometry into top-level viewport coordinates for hover/selection outlines, marquee select, erase, screenshot bounds, and capture rects.Input handling moves from capture-phase
windowlisteners to a full-screen transparentcaptureSurfacewith pointer capture, so clicks over iframe areas still reach the picker. Wheel events are forwarded through that surface (including nested frames) so the page can scroll during annotation; nested frame scroll listeners trigger repaints so outlines stay aligned.main.tsonly switchesnode:osto a namespace import forhomedir().Reviewed by Cursor Bugbot for commit 5c01d2e. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Support preview annotations in same-origin iframes
pickFromDocument) and marquee selection (collectElementsInRect), enabling annotation interactions inside same-origin iframes.getDocumentViewportOffset) that climbs the frame hierarchy to produce accurate overlay positions for elements in nested frames.captureSurfaceelement that captures pointer events without blocking hover visuals; wheel events are forwarded to underlying scrollable elements across frames.refreshFrameScrollListeners) so selected outlines and visuals stay in sync when inner frames scroll.getAccessibleFrameDocument.getBoundingClientRectvalues; disconnected or out-of-viewport elements are skipped during submission.Macroscope summarized 5c01d2e.