clean up safari logic

This commit is contained in:
Pas 2025-10-29 21:41:23 -06:00
parent 11eea4c977
commit b51ecc3d87
5 changed files with 40 additions and 49 deletions

View file

@ -1,31 +1,27 @@
# Safari Extension Development Guide
# Safari Extension Support
## Building for Safari
## Overview
To build the extension specifically for Safari:
This extension now supports Safari through a unified cross-platform build. The same `chrome-mv3` build works in Chrome and Safari (including Orion browser).
## Building for All Platforms
Build the extension for all platforms:
```bash
pnpm build:safari
```
## Development for Safari
For Safari development (without hot-reload to avoid WebSocket issues):
```bash
pnpm dev:safari
pnpm build
```
## Safari Installation & Testing
### 1. Load Extension in Safari
1. Build the extension: `pnpm build:safari`
1. Build the extension: `pnpm build`
2. Open Safari and go to Safari → Preferences → Advanced
3. Check "Show Develop menu in menu bar"
4. Go to Develop → Allow Unsigned Extensions (for development)
5. Go to Safari → Preferences → Extensions
6. Click the "+" button and select the `build/safari-mv3-prod` folder
6. Click the "+" button and select the `build/chrome-mv3-prod` folder
### 2. Grant Permissions
@ -47,7 +43,7 @@ Safari requires manual permission setup:
#### Issue: WebSocket Connection Blocked
**Fix**: Use `pnpm dev:safari` which disables hot-reload WebSockets that Safari blocks.
**Fix**: Safari blocks WebSocket connections for security. The extension automatically detects Safari and applies appropriate delays and retry logic.
#### Issue: Permissions Not Working
@ -69,9 +65,9 @@ Safari requires manual permission setup:
- [ ] Extension loads in Safari Extensions preferences
- [ ] Website permissions are granted in Safari Preferences → Websites
- [ ] No "Invalid call to runtime.connect()" errors
- [ ] No WebSocket connection warnings
- [ ] Permission guide shows correctly when Safari is detected
- [ ] Permission guide shows correctly when Safari/Orion is detected
- [ ] All message handlers work properly
- [ ] Same build works in Chrome, Firefox, and Safari
### 6. Production Deployment
@ -80,4 +76,6 @@ For Safari App Store distribution:
1. You'll need to create a native macOS app wrapper
2. Use Xcode to create the Safari extension project
3. Follow Apple's Safari extension guidelines
4. The built extension in `build/safari-mv3-prod` can be embedded in the macOS app
4. The built extension in `build/chrome-mv3-prod` can be embedded in the macOS app
For web stores (Chrome, Firefox, Edge), use the same `build/chrome-mv3-prod` folder.

View file

@ -1,12 +0,0 @@
const manifest = {
host_permissions: ['<all_urls>'],
permissions: ['storage', 'declarativeNetRequest', 'activeTab', 'cookies'],
web_accessible_resources: [
{
resources: ['assets/active.png', 'assets/inactive.png'],
matches: ['<all_urls>']
}
]
}
export default manifest

View file

@ -6,13 +6,10 @@
"author": "P-Stream",
"scripts": {
"dev": "plasmo dev",
"dev:safari": "plasmo dev --target=safari-mv3 --no-hmr",
"build": "plasmo build",
"build:firefox": "plasmo build --target=firefox-mv3",
"build:safari": "plasmo build --target=safari-mv3",
"package": "plasmo package",
"package:firefox": "plasmo package --target=firefox-mv3",
"package:safari": "plasmo package --target=safari-mv3",
"lint": "eslint --ext .tsx,.ts src",
"lint:fix": "eslint --fix --ext .tsx,.ts src",
"lint:report": "eslint --ext .tsx,.ts --output-file eslint_report.json --format json src",

View file

@ -1,22 +1,11 @@
import { relayMessage } from '@plasmohq/messaging';
import type { PlasmoCSConfig } from 'plasmo';
import { isSafari } from '~utils/extension';
export const config: PlasmoCSConfig = {
matches: ['<all_urls>'],
};
// Safari requires a delay before setting up messaging
const isSafari = () => {
try {
return (
chrome.runtime.getURL('').startsWith('safari-web-extension://') ||
(typeof browser !== 'undefined' && browser.runtime.getURL('').startsWith('safari-web-extension://'))
);
} catch {
return false;
}
};
const setupMessaging = () => {
try {
relayMessage({

View file

@ -1,3 +1,16 @@
// Type declarations for Orion/Safari webkit APIs
declare global {
interface Window {
webkit?: {
messageHandlers: {
kagiEvents?: any;
base?: any;
[key: string]: any;
};
};
}
}
export const isChrome = () => {
return chrome.runtime.getURL('').startsWith('chrome-extension://');
};
@ -12,10 +25,16 @@ export const isFirefox = () => {
export const isSafari = () => {
try {
return (
chrome.runtime.getURL('').startsWith('safari-web-extension://') ||
browser.runtime.getURL('').startsWith('safari-web-extension://')
);
// Check for standard Safari scheme
const hasSafariScheme = chrome.runtime.getURL('').startsWith('safari-web-extension://') ||
browser.runtime.getURL('').startsWith('safari-web-extension://')
// Check for Orion (which loads Safari extensions with chrome-extension:// scheme)
const isOrion = typeof window !== 'undefined' &&
window.webkit &&
window.webkit.messageHandlers;
return hasSafariScheme || isOrion;
} catch {
return false;
}