commit 2c5fc385158811acf9bed75d55dc04c711eefa21
parent 3417e4afce5eaff498a875c7ea4f7f964bbdec6a
Author: Kagami Sascha Rosylight <krosylight@proton.me>
Date: Thu, 20 Nov 2025 09:20:09 +0000
Bug 2000862 - Part 2: Use nsIURI to pass icon URL r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D273227
Diffstat:
6 files changed, 43 insertions(+), 28 deletions(-)
diff --git a/dom/interfaces/notification/nsINotificationStorage.idl b/dom/interfaces/notification/nsINotificationStorage.idl
@@ -18,7 +18,7 @@ interface nsINotificationStorageEntry : nsISupports {
readonly attribute AString lang;
readonly attribute AString body;
readonly attribute AString tag;
- readonly attribute AString icon;
+ readonly attribute ACString icon;
readonly attribute boolean requireInteraction;
readonly attribute boolean silent;
readonly attribute AString dataSerialized;
diff --git a/dom/ipc/DOMTypes.ipdlh b/dom/ipc/DOMTypes.ipdlh
@@ -237,7 +237,7 @@ struct DocShellLoadStateInit
HTTPSUpgradeTelemetryType HttpsUpgradeTelemetry;
// https://html.spec.whatwg.org/#she-navigation-api-state
- ClonedMessageData? NavigationAPIState;
+ ClonedMessageData? NavigationAPIState;
// Fields missing due to lack of need or serialization
// nsCOMPtr<nsIDocShell> mSourceDocShell;
@@ -361,6 +361,7 @@ struct IPCNotificationAction {
// Mostly same as NotificationOptions except:
// * `title` is included (it's a separate parameter in the Notification constructor)
+// * `icon` is parsed into nsIURI
// * `data` is serialized to base64 string by StructuredCloneContainer
// * `vibrate` is normalized to sequence
struct IPCNotificationOptions {
@@ -369,7 +370,7 @@ struct IPCNotificationOptions {
nsString lang;
nsString body;
nsString tag;
- nsString icon;
+ nullable nsIURI icon;
bool requireInteraction;
bool silent;
uint32_t[] vibrate;
diff --git a/dom/notification/Notification.cpp b/dom/notification/Notification.cpp
@@ -395,8 +395,7 @@ already_AddRefed<Notification> Notification::ValidateAndCreate(
// Step 12: If options["icon"] exists, then parse it using baseURL, and if
// that does not return failure, set notification’s icon URL to the return
// value. (Otherwise icon URL is not set.)
- nsAutoString iconUrl;
- ResolveIconURL(aGlobal, aOptions.mIcon, iconUrl);
+ RefPtr<nsIURI> iconUrl = ResolveIconURL(aGlobal, aOptions.mIcon);
// Step 19: Set notification’s actions to « ».
nsTArray<IPCNotificationAction> actions;
@@ -425,7 +424,7 @@ already_AddRefed<Notification> Notification::ValidateAndCreate(
nsString(aTitle), aOptions.mDir, nsString(aOptions.mLang),
nsString(aOptions.mBody), nsString(aOptions.mTag),
iconUrl, aOptions.mRequireInteraction, silent, vibrate,
- nsString(dataResult.unwrap()), std::move(actions)));
+ nsString(dataResult.unwrap()), actions));
RefPtr<Notification> notification =
new Notification(aGlobal, ipcNotification, aScope);
@@ -563,31 +562,26 @@ uint32_t Notification::MaxActions(const GlobalObject& aGlobal) {
return kMaxActions;
}
-nsresult Notification::ResolveIconURL(nsIGlobalObject* aGlobal,
- const nsACString& aIconUrl,
- nsString& aResolvedUrl) {
+already_AddRefed<nsIURI> Notification::ResolveIconURL(
+ nsIGlobalObject* aGlobal, const nsACString& aIconUrl) {
nsresult rv = NS_OK;
if (aIconUrl.IsEmpty()) {
- return rv;
+ return nullptr;
}
nsCOMPtr<nsIURI> baseUri = aGlobal->GetBaseURI();
if (!baseUri) {
- return rv;
+ return nullptr;
}
nsCOMPtr<nsIURI> srcUri;
rv = NS_NewURI(getter_AddRefs(srcUri), aIconUrl, nullptr, baseUri);
- if (NS_SUCCEEDED(rv)) {
- nsAutoCString src;
- srcUri->GetSpec(src);
- // XXX(krosylight): We should be able to pass UTF8 as-is, or ideally the URI
- // object itself.
- CopyUTF8toUTF16(src, aResolvedUrl);
+ if (NS_FAILED(rv)) {
+ return nullptr;
}
- return rv;
+ return srcUri.forget();
}
JSObject* Notification::WrapObject(JSContext* aCx,
diff --git a/dom/notification/Notification.h b/dom/notification/Notification.h
@@ -100,7 +100,12 @@ class Notification : public DOMEventTargetHelper, public SupportsWeakPtr {
}
void GetIcon(nsACString& aRetval) {
- aRetval = NS_ConvertUTF16toUTF8(mIPCNotification.options().icon());
+ nsIURI* iconUri = mIPCNotification.options().icon();
+ if (!iconUri) {
+ aRetval.Truncate();
+ return;
+ }
+ iconUri->GetSpec(aRetval);
}
void MaybeNotifyClose();
@@ -110,7 +115,7 @@ class Notification : public DOMEventTargetHelper, public SupportsWeakPtr {
static already_AddRefed<Promise> RequestPermission(
const GlobalObject& aGlobal,
- const Optional<OwningNonNull<NotificationPermissionCallback> >& aCallback,
+ const Optional<OwningNonNull<NotificationPermissionCallback>>& aCallback,
ErrorResult& aRv);
static NotificationPermission GetPermission(const GlobalObject& aGlobal,
@@ -193,9 +198,8 @@ class Notification : public DOMEventTargetHelper, public SupportsWeakPtr {
bool CreateActor();
bool SendShow(Promise* aPromise);
- static nsresult ResolveIconURL(nsIGlobalObject* aGlobal,
- const nsACString& aIconUrl,
- nsString& aResolvedUrl);
+ static already_AddRefed<nsIURI> ResolveIconURL(nsIGlobalObject* aGlobal,
+ const nsACString& aIconUrl);
};
} // namespace mozilla::dom
diff --git a/dom/notification/NotificationParent.cpp b/dom/notification/NotificationParent.cpp
@@ -279,8 +279,12 @@ nsresult NotificationParent::Show() {
}
nsCOMPtr<nsIPrincipal> principal = mArgs.mPrincipal;
- MOZ_TRY(alert->Init(options.tag(), options.icon(), options.title(),
- options.body(), true, obsoleteCookie,
+ nsAutoCString iconUrl;
+ if (RefPtr<nsIURI> iconUri = options.icon()) {
+ iconUri->GetSpec(iconUrl);
+ }
+ MOZ_TRY(alert->Init(options.tag(), NS_ConvertUTF8toUTF16(iconUrl),
+ options.title(), options.body(), true, obsoleteCookie,
NS_ConvertASCIItoUTF16(GetEnumString(options.dir())),
options.lang(), options.dataSerialized(), principal,
principal->GetIsInPrivateBrowsing(), requireInteraction,
diff --git a/dom/notification/NotificationUtils.cpp b/dom/notification/NotificationUtils.cpp
@@ -17,6 +17,7 @@
#include "nsINotificationStorage.h"
#include "nsIPermissionManager.h"
#include "nsIPushService.h"
+#include "nsNetUtil.h"
#include "nsServiceManagerUtils.h"
static bool gTriedStorageCleanup = false;
@@ -409,8 +410,13 @@ NS_IMETHODIMP NotificationStorageEntry::GetTag(nsAString& aTag) {
return NS_OK;
}
-NS_IMETHODIMP NotificationStorageEntry::GetIcon(nsAString& aIcon) {
- aIcon = mIPCNotification.options().icon();
+NS_IMETHODIMP NotificationStorageEntry::GetIcon(nsACString& aIcon) {
+ nsIURI* iconUri = mIPCNotification.options().icon();
+ if (!iconUri) {
+ aIcon.Truncate();
+ return NS_OK;
+ }
+ iconUri->GetSpec(aIcon);
return NS_OK;
}
@@ -469,7 +475,13 @@ Result<IPCNotification, nsresult> NotificationStorageEntry::ToIPC(
MOZ_TRY(aEntry.GetLang(options.lang()));
MOZ_TRY(aEntry.GetBody(options.body()));
MOZ_TRY(aEntry.GetTag(options.tag()));
- MOZ_TRY(aEntry.GetIcon(options.icon()));
+
+ nsAutoCString iconUrl;
+ MOZ_TRY(aEntry.GetIcon(iconUrl));
+ if (!iconUrl.IsEmpty()) {
+ MOZ_TRY(NS_NewURI(getter_AddRefs(notification.options().icon()), iconUrl));
+ }
+
MOZ_TRY(aEntry.GetRequireInteraction(&options.requireInteraction()));
MOZ_TRY(aEntry.GetSilent(&options.silent()));
MOZ_TRY(aEntry.GetDataSerialized(options.dataSerialized()));