Post not yet marked as solved
Hello,
I am trying to download a file from the extension's settings page with the following code, but I cannot set the filename no matter what I try. It keeps downloading as Unknown.txt.
The same code works well if I do it through a hosted page with an actual URL.
let downloadFile = function(contents, filename) {
var element = document.createElement('a');
element.setAttribute('href', 'data:application/octet-stream,' + encodeURIComponent(contents));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
downloadFile('test', 'file.txt');
Is this intended or a bug?
Post not yet marked as solved
Hello,
I have a browser extension that is already released for other browsers, and I want to start releasing for Safari as well, and I have a few questions about the payments system.
My extension allows users to unlock features by making a payment through Stripe or PayPal and receiving a license key.
For Safari I want to use Apple’s IAP system as I already know that this is a requirement but I also want to allow people that already purchased the license through other browsers to use it with Safari.
So my question,
Am I allowed to allow people bring their license keys purchased from other browsers?
Throughout the Safari extension I will only use Apple’s IAP system and offer the same price as on other browsers. So I will not ”reward” people with discounts if they use other payment processors outside of Safari.
Thank you!
Post not yet marked as solved
Hello,
I have developed a Safari extension that intercepts browser requests. I'm utilizing the chromeWebRequest API for this purpose. You can find more information about it here: https://developer.chrome.com/docs/extensions/reference/webRequest/
I have successfully retrieved all the headers for the request. However, I am facing an issue when trying to retrieve the request body, particularly when the content-type of the request is multipart/form-data.
I would greatly appreciate any assistance with this matter. Thank you.
Post not yet marked as solved
I have a Safari extension needs to store more than 10GB data in indexedDB. I added unlimitedStorage permission to my extension, but there's still a limitation about 1.5GB, after write 1.5GB data in indexedDB, all put operation will failed with 'Failed to PutOrAdd in database because not enough space for domai'
At this time, storage.local can still write. I'm not sure why, but Firefox and Chrome both can give unlimited storage for the indexedDB, so, please apply the permission also for indexedDB!
It's hard to manage a big data by the raw storage.local API.
I am trying to run JavaScript only after the page has loaded, and according to here - https://developer.apple.com/documentation/safariservices/safari_app_extensions/injecting_a_script_into_a_webpage, I should use DOMContentLoaded. However, it does not seem to work.
This is my content.js file:
function runOnStart() {
document.addEventListener('DOMContentLoaded', function(e) {
document.body.style.background = "rgb(20, 20, 20)";
document.html.style.background = "rgb(20, 20, 20)";
var divElements = document.body.getElementsByTagName('div');
for(var i = 0; i < divElements.length; i++) {
let elem = divElements[i];
elem.style.background = "rgba(255, 255, 255, 0.05)";
}
});
}
runOnStart();
If I take the code outside of the event listener, it runs fine, but a lot of the elements haven't loaded in yet so it doesn't work as it should.
The function is definitely running, but the event listener simply doesn't work. I appreciate any help you can give!
I recently saw Carrot Shopping has a Allow Permissions badge next to its mobile safari extension icon in the toolbar for prompting user to allow permissions. I searched everywhere including the official safari extension documentation for turning this feature on for our extension, but I haven't been able to find anything related to this badge. Has anyone have any experience enabling this badge for their mobile safari extension? Would be super helpful if someone can guide me to the right documentation.
I've created a Safari Extension app using the MultiPlanform option.
I can successfully distribute the iOS app for beta testing with TestFlight, but when I try to do this with the macOS version, I get the following error:
The product archive is invalid. The Info.plist must contain a LSApplicationCategoryType key, whose value is the UTI for a valid category. For more details, see "Submitting your Mac apps to the App Store".
For the record, I searched for the mentioned document and couldn't find it. A link would be nice.
Regardless, when I look at the macOS (App) in the Navigator Panel, there is no Info.plist file. There is one, however, in iOS (App).
When I open Test Flight on my Mac, I see the app, but that's most likely because I have an M1 chip.
I can't find any documentation on this, so I'm asking:
Do I need to create an Info.plist file for the macOS (App), and if so, what do I need to put in there?
If I don't need this, how do I deal with this error?
Thanks in advance for any helpful advice.
Post not yet marked as solved
All of my third party extensions have blue icons now, in Safari 14.0. It looks pretty awful.
Is there a way to keep the monochrome colors or a way for us, as developers, to provide a different kind of icon to sustain the monochrome colors for our extensions?
I am assuming the blue color denotes something, like the extension being "active". I wasn't able to find documentation on this change nor any related api doc.
Post not yet marked as solved
Hello,
I am in the process of converting a Web Extension to a Safari Extension. I need to use browser.downloads.onCreated.addListener in my extension but the browser.downloads API is not supported yet.
Do I have another way to do that?
I can check if my Safari app extension is enabled using the SFSafariExtensionManager getStateOfSafariExtensionWithIdentifier API for default.
But in case the user disables the extension for his own profile, I want to know if my safari app extension is enabled in that particular safari profile programatically using API. I'm trying this with Safari 17 on macOS 14 Beta. It's possible? If so, what API can do this for me?
Post not yet marked as solved
Hi,
According to Blocking Content with Your Safari Web Extension, we can now use the Declarative Net Request API to block content in a Safari Web Extension.
However, not everything in the API has been implemented just yet.
The supported RuleCondition are domainType, excludedResourceTypes, isUrlFilterCaseSensitive, regexFilter, and resourceTypes.
Does anyone know when the initiatorDomains rule condition will be supported?
In the meantime, is there a way for an extension to block requests based on an originator domain?
Thanks
Post not yet marked as solved
Hi.
For my Safari Web Extension, using getMatchedRules() from declarativeNetRequest does not seem to work.
I've declared the permission for declarativeNetRequestFeedback in my manifest.json file and tried the activeTab permission too.
getMatchedRules() was added in a previous Safari release and was adjusted in Safari 16.4. I'm using Safari 16.5.
It only returns an empty array when it's called.
I know the rules are there and they're being applied from the static rules json, it's just that getMatchedRules() is not showing them for some reason.
I'm using:
const rules = await browser.declarativeNetRequest.getMatchedRules();
But it only ever returns:
{rulesMatchedInfo: []}
Can anyone tell me what I'm doing wrong please? The same code works fine in Chromium based browsers.
Thank you.
Post not yet marked as solved
Hi! I'm working on an iOS Safari extension that has a ServiceWorker. Lately we've noticed that this ServiceWorker seems to get killed seemingly at random, and there are no logs or crash reports to tell us what happened.
I'm hypothesizing that iOS might be shutting down Safari ServiceWorkers when the ProcessInfo.thermalState approaches .serious. I have circumstantial evidence that our ServiceWorker tends to get killed more often at higher levels of thermalState but can't yet say conclusively that this is the case. I can't find any direct evidence of this on internet searches either.
Is anyone able to shed light onto this topic? The specific symptoms are:
ServiceWorker stops, and the menu entry for its console window no longer appears on macOS Safari.
No crash logs via Xcode or Sentry, and no Console messages as far as we could tell (caveat: MobileSafari generates a LOT of messages! We might have missed it.)
If attached via debugger, the native part of our extension just disappears and the debugger loses connection with no error message.
ServiceWorker no longer works for the lifetime of the Safari process. Sometimes, when we kill Safari and restart, we can get the ServiceWorker back. This usually requires toggling our extension's "enabled" state in system settings.
In some cases, even killing/relaunching Safari and toggling the system setting doesn't bring our ServiceWorker back. I'm hypothesizing right now that this happens when the thermal state is high.
I've tried simulating a serious/critical thermal state in the Xcode Devices window, but couldn't repro the ServiceWorker problem. I don't know if that setting affects the whole system, though, or just our own apps.
Help appreciated!
Yuna
Post not yet marked as solved
0
I integrate with safriService (SFSafariViewController) to log in through a single sign-on password, the problem was the first time I log in using SFSafariViewController but the authentication follow not complete the first time so the safari browser still appear & can not direct into my app after authentication follow to become a success, another behavior is when I login again the authentication follow work fine & get the token then directed into my app fine so the main problem is the first time I login SFSafariViewController does not catch the user auth
if let url = URL(string: "url") {
let safariVC = SFSafariViewController(url: url)
safariVC.delegate = self
safariVC.dismissButtonStyle = .done
present(safariVC, animated: true, completion: nil)
}
extension DouWebViewVC: SFSafariViewControllerDelegate {
func safariViewController(_ controller: SFSafariViewController, didCompleteInitialLoad didLoadSuccessfully: Bool) {
if didLoadSuccessfully {
print("didLoadSuccessfully")
// Do something with the URL here
}
}
//initialLoadDidRedirectTo
func safariViewController(_ controller: SFSafariViewController, initialLoadDidRedirectTo requestUrl: URL) {
let absoluteUrl = requestUrl.absoluteString
print("requestUrl(requestUrl)")
}
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
print("safariViewControllerDidFinish")
}
}
Post not yet marked as solved
Ignoring the fact that we still need to use MV2 in order to use webRequest in Safari (with the persistent: true flag set, a requirement not needed in FireFox MV2), there are certain requests that never have a request side event raised for them, but do have their associated response side events raised.
I've noticed this specifically for cases where the request contains a raw or binary request body.
A simple way to reproduce this, is to log into Twitter which uses binary payloads. You will notice if you add listeners to any of onBeforeSendHeaders,onSendHeaders, or onBeforeRequest that you get zero events for any request that would be the login request. Now if you also add a listener to onResponseStarted however, you will get a response event for the login request (including the requestId of the request that never had a request side event raised).
Please could Safari just do what FireFox and Chromium do and have the request body be stored in either requestBody.formBody (if the payload was of a form-like mime type), or if not just have the raw data stored in requestBody.raw.
At this point, I'd even take the requestBody being a parsed form object OR a binary array, but having the request event just swallowed by the browser, I'm assuming due to it being unable to parse it to an object, is poor.
The webRequest API for Safari is completely unaligned to Chromium based browsers and FireFox. In Chromium webRequest works just fine with MV3 service workers, and in FireFox it works just fine with non-persistent background scripts.
As for webNavigation, the APIs behaviour seems unaligned too. I mean, entering a new URL into the address bar of the current tab doesn't even raise a navigation event. This seems like one of the most basic navigation related actions that an extension would want to know about. :exploding-head:
Post not yet marked as solved
browser.scripting.registerContentScripts was introduced in Safari 16.4.
However, in Safari 16.6, we have just noticed that browser.scripting.registerContentScripts removes content scripts declared in the manifest (FB12817504).
Any work-arounds?
Post not yet marked as solved
I migrated my extension from Manifest V2 to V3 recently, and it works fine on Chrome/Edge, but got failed on Safari. The only error message that I can see is:
由于出现错误,service_worker脚本载入失败。
It says service_worker failed to load.
There is no other messages I can found.
Can you please tell me how to get more informations about the error? Thanks!
Post not yet marked as solved
I'm getting the following error when I try to import my service worker script:
[Error] Failed to load resource: unsupported URL (background_ah.worker.js, line 0)
[Error] NetworkError: Load failed
Using the following code:
try {
self.importScripts('./background_ah.worker.js');
} catch (e) {
console.error(e);
}
Am I doing something wrong? The file is there but from the error it seems the extension protocol is not supported at all.
It works in Chrome and it's based on this:
https://stackoverflow.com/questions/66406672/chrome-extension-mv3-modularize-service-worker-js-file
Post not yet marked as solved
Declarative net Request modify header rule is not working for safari. Works fine on all other browsers (chrome, edge , FF etc)
Error: [Error] Error: Invalid call to declarativeNetRequest.updateDynamicRules(). Error with rule at index 0: Rule with id 100 is invalid. The header x-source is not recognized.
> > let x = [{ "id": 100, "priority": 1, "action": { "type": "modifyHeaders", "requestHeaders": [ { "header": "x-source", "operation": "set", "value": "test" } ] }, "condition": { "urlFilter": "https://*/*" } }]
await browser.declarativeNetRequest.updateDynamicRules({ addRules: x });
However, if I change the header name to "Origin" it works. Is there a restriction on which all header names are supported?
Post not yet marked as solved
I'm porting a Chrome extension to Safari. All works well besides the auth flow, which uses SameSite=Strict cookies.
On Chrome, such cookies are easily set and work as expected, but not on Safari.
Now, as I understand, technically, requests from chrome-extension:// and safari-web-extension:// origins are cross-site in relation to the server, which makes me think that on Chrome, the SameSite=Strict attribute is simply ignored as an exception for extensions. With that said, the backend team wants to keep the attribute for security reasons and so removing it or replacing it with SameSite=None isn't an option.
Is this an intended behavior of Safari or a bug? Is there a way to get around this without changing the attribute?