Safari Extensions

RSS for tag

Enhance and customize the web browsing experience on Mac, iPhone, and iPad with Safari Extensions

Posts under Safari Extensions tag

87 Posts

Post

Replies

Boosts

Views

Activity

Detecting tabs change in Safari App Extension when switching windows inside validateToolbarItem.
Hi. I'm a developer of Tab Finder (https://apps.apple.com/us/app/tab-finder/id6741719894) My problem is that every time i switch from my first window to a second window, the tabs in the validateToolbarItem() are INcorrect on a first call, but when I switch back from the second window to my main window, the tabs are CORRECT even on a first call. To demonstrate it, i recorded a video: https://youtu.be/RwskzrSJ8u0 To run the same sample extension from the video, you can get the code from this GitHub repo: https://github.com/kopyl/test-tabs-change Its only purpose is to log URLs of an active page of all tabs. The SafariExtensionHandler's code of the sample app is very simple: import SafariServices func printOpenTabsHost(in window: SFSafariWindow) async { let tabs = await window.allTabs() log("Logging tabs for a new window: \(window.hashValue)") for tab in tabs { let page = await tab.activePage() let properties = await page?.properties() let url = properties?.url log(url?.absoluteString ?? "No URL") } } class SafariExtensionViewController: SFSafariExtensionViewController { static let shared = SafariExtensionViewController() } class SafariExtensionHandler: SFSafariExtensionHandler { override func validateToolbarItem(in window: SFSafariWindow, validationHandler: @escaping ((Bool, String) -> Void)) { Task { await printOpenTabsHost(in: window) } validationHandler(true, "") } override func popoverViewController() -> SFSafariExtensionViewController { return SafariExtensionViewController.shared } } Could you please tell if i'm missing something and how to see the actual tabs inside the overridden validateToolbarItem call of the SafariExtensionHandler (or in any other way, I'm okay with any implementation as long as it works).
0
0
416
Mar ’25
DNR Redirect Rule Won’t Redirect to Extension Path
DNR rules redirecting to an extension path lead to an error page: “Safari can’t open the page. The error is: “The operation couldn’t be completed. (NSURLErrorDomain error -1008.)” (NSURLErrorDomain:-1,008).” Here is a demo extension that replicates the bug: https://github.com/lenacohen/Safari-Test-Extensions/tree/main/dnr-extension-path-redirect This is an example of a redirect rule that leads to an error page instead of the extension path page: chrome.declarativeNetRequest.updateDynamicRules({addRules: [ { id: 2, priority: 1, action: { type: "redirect", redirect: { extensionPath: "/web_accessible_resources/test_redirect.html" } }, condition: { urlFilter: "||washingtonpost.com^", resourceTypes: [ "main_frame" ] } } ]}); The extension path is included in web_accessible_resources in the extension manifest: "web_accessible_resources": [{ "resources": [ "web_accessible_resources/test_redirect.html" ], I also submitted a bug report on Apple's Feedback Assistant: FB16607632
0
1
546
Feb ’25
"excludeMatches" array in scripting.registerContentScripts() API is totally ignored in Safari web extensions
In a project to create a web extension for Safari, using scripting.registerContentScript() API to inject a bunch of scripts into web pages, I needed to manage a dynamic whitelist (i.e., web pages where the scripts should not be injected). Fortunately, scripting.registerContentScripts() gives you the option of defining a list of web pages to be considered as a whitelist, using the excludeMatches parameter in the directive, to represent an array of pages where the script should not be injected. Here just a sample of what I mean: const matches = ['*://*/*']; const excludeMatches = ['*://*.example.com/*']; const directive = { id: 'injected-jstest', js: ['injectedscript.js'], matches: matches, excludeMatches: excludeMatches, persistAcrossSessions: false, runAt: 'document_start' }; await browser.scripting.registerContentScripts([directive]) .catch(reason => { console.log("[SW] >>> inject script error:",reason); }); Of course, the whitelist (the excludeMatches array) is not static, but varies over time according to the needs of the moment. Everything works perfectly in Chromium browsers (Chrome, Edge, ...) and Firefox, but fails miserably in Safari. In fact, Safari seems to completely ignore the excludeMatches parameter and injects the script even where it should not. Has anyone had the same problem and solved it somehow? NOTE : To test the correctness and capabilities of the API in each browser, I created a simple repository on Github with the extension code for Chromium, Firefox and Safari (XCode project).
1
0
609
Feb ’25
Unable to validate with app sandbox issues
My app is a Safari extension. When trying to validate the app, I get the following error: App sandbox not enabled. The following executables must include the "com.apple.security.app-sandbox" entitlement with a Boolean value of true in the entitlements property list: [( "app.rango.Rango.pkg/Payload/Rango for Safari.app/Contents/MacOS/Rango for Safari" )] Refer to App Sandbox page at https://developer.apple.com/documentation/security/app_sandbox for more information on sandboxing your app. I don't know why this is happening. I have app sandbox enabled in both the app and the extension target. I have both entitlement files. When executing codesign -d --entitlements :- /path/to/binary I get the following: <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict><key>com.apple.security.app-sandbox</key><true/><key>com.apple.security.files.user-selected.read-only</key><true/><key>com.apple.security.get-task-allow</key><true/><key>com.apple.security.network.client</key><true/></dict></plist> If I check on Activity Monitor, on the sandbox column it shows true. I have no idea why I keep getting this error when all indicates that the app is actually sandboxed.
4
0
584
Feb ’25
Safari web extension service worker not working after a minute
We are testing our safari web extension (https://apps.apple.com/us/app/whatfix-for-jnj-centris/id6723895659) on an iPad 7th Gen (iPadOS v - 17.4.1) I am sharing a video link where you can see the widget (named Self Help) appears on the application. However after a couple of refreshes, it vanishes. This widget is powered by the extension. We tried connecting the iPad to Mac and opened the webinspector. The extension content script sends a message to the service worker and it is expected to send back a response which it is not doing We believe it is related to an issue that has been highlighted multiple times in the developer forum - https://developer.apple.com/forums/thread/758346 We have tried using several workaorunds as suggested by peer developers in the thread but we are unable to revive the service worker once it is killed. We would like to understand from you, how to recover from this issue. Is there any workaround that we can apply to make sure that extension works fine? It would be immensely helpful if we can get on a call to explain the issue further Video Link: https://www.icloud.com/iclouddrive/0a7NR7BzDQHHU8zCHERuySBMw#RPReplay%5FFinal1740034010
1
0
395
Feb ’25
How to trigger Safari App Extension with a keyboard shortcut without a content script and Accessibility permissions?
I have a Safari App Extension which allows users to switch between last open tabs with a shortcut option+tab in the same way it's possible to switch between last open apps with command+tab. Here is how i do it: I inject a content script on all websites which has the only thing – key listener for option+tab presses. When a user presses option+tab, that keyboard listener detects it and sends a message to the Safari Handler. Then Safari Handler sends a message to the containing app and it shows a panel with last open tabs. This approach has a problem: it shows a message to a user in settings: "Can read sensitive info from web pages, including passwords..." Which is bad, because in reality i don't read passwords. If i remove SFSafariContentScript key in the Safari App Extension target's Info.plist, then this message about reading sensitive data disappears, but then i loose the ability to open the tabs panel. How can I open my app window with a shortcut without frightening a user? It's possible to listen to global key presses, but that would require a user to grant the app permissions of Accessibility (Privacy & Security) in macOS system settings, which also sounds shady. I know an app which does not require an Accessibility permission: https://apps.apple.com/ua/app/tabback-lite/id6469582909 and at the same time it does not tell a user about reading sensitive data in the extension settings. Here is my app: https://apps.apple.com/ua/app/tab-finder/id6741719894 It's open-source: https://github.com/kopyl/safari-tab-switcher
2
0
613
Feb ’25
Safari extension service worker appears with a delay in the Develop dropdown
Hi, I'm developing an extension and I need to debug console logs that are logged in the Service Worker. The worker is configured in the manifest and is generally working as expected: However, when I open the browser, go to any site, and open Develop -> Service Workers or Develop -> Web Extension Background Content it is not visible there, so I can't really access the logs: But then I noticed that if I go out of focus from the browser for some time (and probably let the SW die), it becomes visible and I can open it without an issue: So, a couple of questions: Why isn't it instantly accessible? The extension Service Worker dev tools should be accessible regardless of what is happening to the tab or the browser, even if the SW terminates. Why does it eventually appear under Web Extension Background Content instead of the Service Workers when it is in fact an SW?
0
1
442
Feb ’25