Skip to content

Add Chrome support (Phases 1-5)#76

Merged
evanwon merged 17 commits into
mainfrom
chrome-support-phase1
Mar 13, 2026
Merged

Add Chrome support (Phases 1-5)#76
evanwon merged 17 commits into
mainfrom
chrome-support-phase1

Conversation

@evanwon
Copy link
Copy Markdown
Owner

@evanwon evanwon commented Mar 13, 2026

Summary

  • Phase 1: Browser API abstraction layer (BrowserApi) supporting both Firefox MV2 and Chrome MV3
  • Phase 2: Multi-browser build system (tools/build.js) generating Chrome MV3 output from Firefox MV2 source
  • Phase 3: Chrome MV3 manifest adaptation, offscreen clipboard support, service worker compatibility
  • Phase 4: Chrome integration tests, browser-aware options UI, notification/message handling fixes
  • Phase 5: CI/CD pipeline updates — passes chrome-enabled: true to shared extension-workflows (v1.1.0)

All 278 tests pass. Firefox behavior is completely unchanged. Chrome support is opt-in at every layer.

Test plan

  • test-pr.yml CI passes with Chrome build + validate steps
  • Verify goodreads-shelf-position-editor CI is unaffected
  • Manual: load Chrome build in Chrome and test copy functionality
  • Manual: verify Firefox extension still works identically

🤖 Generated with Claude Code

evanwon and others added 17 commits March 3, 2026 16:33
Create BrowserApi module that abstracts browser extension APIs across
Firefox (MV2) and Chrome (MV3). Refactor all source files to use
BrowserApi instead of direct browser.* calls. Fix export patterns in
utility modules to support Node, window, and globalThis contexts.

Co-Authored-By: Claude <noreply@anthropic.com>
- Create Chrome MV3 manifest template with version placeholders
- Add build script (tools/build.js) that produces Firefox and Chrome builds
- Chrome build concatenates background scripts into service-worker.js
- Add Chrome template validation to version checker
- Add build:chrome, build:firefox, build:all npm scripts
- 18 new tests covering build output and version validation

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Bring in shared extension-workflows tooling and CI/CD migration.
Resolve conflicts by adopting shared package for validate-versions
(which already includes Chrome template validation) and reconciling
build scripts.

Co-Authored-By: Claude <noreply@anthropic.com>
All Phase 3 deliverables (Chrome MV3 manifest, service worker build,
BrowserApi migration, globalThis usage) were implemented during
Phases 1-2. Verified: 255 tests pass, lint clean, Chrome build works.

Co-Authored-By: Claude <noreply@anthropic.com>
Chrome does not reliably resolve Promises returned from async
onMessage listeners. Switched clipboard-writer to use the
sendResponse callback with `return true` for cross-browser compat.
Updated tests to match the new callback pattern.

Co-Authored-By: Claude <noreply@anthropic.com>
Chrome MV3 content scripts injected via scripting.executeScript lack
user gesture context, so both navigator.clipboard and execCommand fail.

Added offscreen document approach (standard Chrome MV3 pattern):
- src/offscreen/clipboard.{html,js} for clipboard DOM operations
- BrowserApi.copyToClipboard() abstracts MV2 vs MV3 clipboard path
- Chrome manifest gains 'offscreen' permission
- background.js delegates to BrowserApi.copyToClipboard()

Co-Authored-By: Claude <noreply@anthropic.com>
Three Chrome MV3 compatibility fixes:

1. Offscreen clipboard: Use execCommand with pre-existing textarea
   and fire-and-forget pattern (matches Chrome's official sample).
   navigator.clipboard.writeText requires focus which offscreen
   documents never have.

2. Background onMessage: Switch from async/return to sendResponse
   callback pattern. Chrome doesn't reliably resolve Promises
   returned from onMessage listeners.

3. Remove diagnostic logging added during debugging.

Co-Authored-By: Claude <noreply@anthropic.com>
- Add notification ID to notifications.create() for Chrome compatibility
- Add copyToClipboard() tests covering MV2 and MV3 paths
- Add offscreen/clipboard.js test suite
- Add Chrome API fallback test for clipboard-writer
- Fix fragile badge assertions to use BrowserApi instead of browser mock
- Add offscreen API to Chrome test mock infrastructure
- Update chrome-support-plan.md to document offscreen document approach

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add clickable chrome://extensions/shortcuts link in options page for Chrome
- Create Chrome MV3 integration test suite (BrowserApi, notifications, message handler)
- Add shortcut help tests for Chrome and Firefox in options test suite
- Mark Phase 4 complete in chrome-support-plan
- Add keyboard shortcut verification item to Phase 6 checklist
- Update README with cross-browser architecture notes

Co-Authored-By: Claude <noreply@anthropic.com>
Pass chrome-enabled: true and CWS variables to the shared
extension-workflows reusable workflows. Add manifests/** to
test-pr.yml paths filter so Chrome manifest changes trigger CI.

Co-Authored-By: Claude <noreply@anthropic.com>
Upgrade jest-environment-jsdom to v30 (fixes @tootallnate/once
CVE) and minimatch transitive deps (fixes ReDoS CVEs). Zero
audit findings remaining.

Co-Authored-By: Claude <noreply@anthropic.com>
PR #76 CI passes with Chrome build + validate steps.
extension-workflows v1.1.0 merged and tagged. goodreads repo
verified unaffected (chrome-enabled defaults to false, no Chrome
steps executed).

Co-Authored-By: Claude <noreply@anthropic.com>
Update all workflow refs, package.json dependency URL, and
documentation links to match the renamed GitHub repository.

Co-Authored-By: Claude <noreply@anthropic.com>
Update devDependencies key, require() paths in test files,
and package name references in docs to match the renamed package.

Co-Authored-By: Claude <noreply@anthropic.com>
@evanwon evanwon merged commit 810c506 into main Mar 13, 2026
1 check passed
@evanwon evanwon deleted the chrome-support-phase1 branch March 13, 2026 16:27
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