Skip to content

feat: add Safari Web Extension support#337

Open
coryboyle wants to merge 2 commits intoBabylonJS:masterfrom
coryboyle:feat/safari-extension
Open

feat: add Safari Web Extension support#337
coryboyle wants to merge 2 commits intoBabylonJS:masterfrom
coryboyle:feat/safari-extension

Conversation

@coryboyle
Copy link

@coryboyle coryboyle commented Mar 17, 2026

Summary

Add Safari Web Extension support for macOS, enabling Spector.js WebGL debugging in Safari.

Architecture

The Safari extension lives in safari-extension/ (separate from the Chrome/Firefox extensions/ directory) because Safari requires a fundamentally different approach to MAIN-world code execution.

Key design decisions

  • browser.scripting.registerContentScripts() with world: "MAIN" — Safari doesn't support manifest-declared MAIN-world content scripts. The scripting API registers pageScript.js as a MAIN-world content script at runtime, which bypasses page CSP and runs at document_start.
  • browser.scripting.executeScript() — Injects the Spector bundle and initialization code into the page's MAIN world on demand (when the user enables Spector), also bypassing CSP.
  • Single ISOLATED-world content scriptcontentScript.js handles all browser.runtime messaging and bridges to the MAIN world via CustomEvents and shared DOM elements.
  • Defensive getContext patch — Uses Function.prototype.apply() for argument forwarding and wraps all extension logic in try-catch to ensure extension errors never break page WebGL functionality.

Files

File Purpose
safari-extension/manifest.json MV3 manifest with scripting permission
safari-extension/pageScript.js MAIN-world getContext() interception (registered via scripting API)
safari-extension/pageScriptInit.js MAIN-world Spector init (injected via scripting API)
safari-extension/contentScript.js ISOLATED-world messaging bridge
safari-extension/background.js Service worker: registers content scripts, handles bundle injection
safari-extension/popup.html/js Extension popup UI
safari-extension/result.html/js Capture result viewer
documentation/safari-extension.md Build, dev, and distribution docs

Build & Test

npm run build                    # Builds bundle + copies to safari-extension/
xcrun safari-web-extension-converter safari-extension/ \
  --project-location safari-xcode \
  --app-name "Spector.js" \
  --bundle-identifier com.babylonjs.spectorjs \
  --macos-only

Then open the Xcode project, build & run, and enable the extension in Safari.

Also included

  • CI job on macOS runner to validate the Safari extension build
  • Updated README with Safari in the browser extension list

Cory Boyle and others added 2 commits March 17, 2026 17:02
Add a Safari Web Extension in safari-extension/ that ports Spector.js
debugging capabilities to Safari on macOS.

Key implementation details:
- Uses browser.scripting.registerContentScripts() with world: MAIN
  for CSP-safe getContext() interception (Safari doesn't support
  manifest-declared MAIN world content scripts)
- Injects Spector bundle via scripting.executeScript() to bypass
  page Content Security Policy restrictions
- Single ISOLATED-world content script bridges extension APIs and
  page CustomEvents
- getContext patch uses Function.prototype.apply() with try-catch
  to ensure extension errors never break page WebGL functionality

Also includes:
- Build script updates (copies bundle to safari-extension/)
- GitHub Actions CI job on macOS runner
- Safari extension documentation
- Copilot instructions for the repository

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@coryboyle coryboyle marked this pull request as ready for review March 17, 2026 21:15
Copy link
Member

@sebavan sebavan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it looks like a lot of code in the safari-extension folder is a dupplicate and this might make maintenance harder.

Any way to share any shareable thing ?

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.

2 participants