Skip to content

Run rule engine in all frames#4

Merged
twschiller merged 1 commit into
mainfrom
iframe-coverage
May 30, 2026
Merged

Run rule engine in all frames#4
twschiller merged 1 commit into
mainfrom
iframe-coverage

Conversation

@twschiller

Copy link
Copy Markdown
Contributor

Summary

  • Enable all_frames: true in the content script manifest (with match_origin_as_fallback so about:blank / about:srcdoc iframes are covered) so PII/secrets masking, prompt-injection hiding, ads-hide, hidden-text-strip, comments/reviews hiding, and the rest of the rule catalog actually reach content that lives inside iframes (Disqus, Trustpilot, AdSense, third-party comment widgets, etc.).
  • Add a topFrameOnly opt-in on the Rule type — set on the rules whose targets are inherently page-wide so they don't fire pointlessly in every subframe: footer-hide, cookie-banner-hide, newsletter-modal-hide, chat-widget-hide, search-url-helper, irrelevant-sections-hide.
  • Gate the floating options badge to the top frame only (no more N badges per page).
  • New lib/frame.ts is the single source of truth for "are we the top frame", with a defensive try/catch around the cross-origin window.top access.
  • New unit test (lib/__tests__/rule-engine.test.ts) covers the three frame-gating branches (top-frame + frame-agnostic rule applied, top-only rule skipped in subframes, unavailable rule never applied).

Notes

  • No new host permissions required — <all_urls> in matches already covers every origin the script needs to inject into.
  • ads-hide deliberately runs in subframes too — many ad networks render the actual ad content inside their iframe, so the EasyList stylesheet needs to be present in each frame. Per-frame stylesheet cost (~600KB CSS text per frame) is a known tradeoff worth a follow-up perf pass.
  • Demo-site iframe fixtures are out of scope for this PR; they can land separately once a real iframe-bearing page exists in the demo.

Test plan

  • bun run check (biome) — passes (one pre-existing unrelated warning in Options.tsx, untouched)
  • bun run test — 385/385 pass, including the 3 new frame-gating tests
  • bunx tsc --noEmit — clean
  • bun run build — produces dist/manifest.json with all_frames: true and match_origin_as_fallback: true
  • Manual: load unpacked into Chrome, visit a page with a same-origin iframe (e.g. Disqus comments embedded via iframe), confirm comments-hide / reviews-hide placeholders appear inside the iframe and that only one options badge renders on the top frame
  • Manual: confirm cookie-banner-hide / newsletter-modal-hide still fire normally on the top frame and do not log anything inside subframes

🤖 Generated with Claude Code

Enable `all_frames: true` (with `match_origin_as_fallback`) so the rule
engine runs in every same-origin and covered cross-origin iframe — not
just the top document. Rules whose targets are page-wide (footer, cookie
banner, newsletter modal, chat widget, search-URL recipe, LLM
classifier) opt into a new `topFrameOnly` flag so they don't fire
pointlessly in subframes. The options badge is also gated to the top
frame so users don't get one per iframe.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented May 30, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agent-browser-shield-demo-site Ready Ready Preview, Comment May 30, 2026 4:21am

Request Review

@twschiller twschiller merged commit a57b54f into main May 30, 2026
6 checks passed
@twschiller twschiller deleted the iframe-coverage branch May 30, 2026 04:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant