mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1114554 - Patch 4 - ServiceWorkerRegistration.getNotifications() on main thread. r=wchen
This commit is contained in:
parent
40af10ec0b
commit
c82f6f8cc8
@ -4,7 +4,7 @@
|
||||
|
||||
#include "domstubs.idl"
|
||||
|
||||
[scriptable, uuid(9f1c43b9-f01b-4c87-ad3d-1a86520c2159)]
|
||||
[scriptable, uuid(c1622232-259c-43b0-b52e-89c39dcd9796)]
|
||||
interface nsINotificationStorageCallback : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -28,7 +28,8 @@ interface nsINotificationStorageCallback : nsISupports
|
||||
in DOMString tag,
|
||||
in DOMString icon,
|
||||
in DOMString data,
|
||||
in DOMString behavior);
|
||||
in DOMString behavior,
|
||||
in DOMString serviceWorkerRegistrationID);
|
||||
|
||||
/**
|
||||
* Callback function used to notify C++ the we have returned
|
||||
@ -41,7 +42,7 @@ interface nsINotificationStorageCallback : nsISupports
|
||||
/**
|
||||
* Interface for notification persistence layer.
|
||||
*/
|
||||
[scriptable, uuid(2f8f84b7-70b5-4673-98d8-fd3f9f8e0e5c)]
|
||||
[scriptable, uuid(17f85e52-fe57-440e-9ba1-5c312ca02b95)]
|
||||
interface nsINotificationStorage : nsISupports
|
||||
{
|
||||
|
||||
@ -61,6 +62,10 @@ interface nsINotificationStorage : nsISupports
|
||||
* Stored in the database to avoid re-computing
|
||||
* it. Built from origin and tag or id depending
|
||||
* whether there is a tag defined.
|
||||
* @param registrationID: Opaque string that identifies the service worker
|
||||
* registration this Notification is associated with.
|
||||
* May be empty. Only set for Notifications created by
|
||||
* showNotification().
|
||||
*/
|
||||
void put(in DOMString origin,
|
||||
in DOMString id,
|
||||
@ -72,7 +77,8 @@ interface nsINotificationStorage : nsISupports
|
||||
in DOMString icon,
|
||||
in DOMString alertName,
|
||||
in DOMString data,
|
||||
in DOMString behavior);
|
||||
in DOMString behavior,
|
||||
in DOMString serviceWorkerRegistrationID);
|
||||
|
||||
/**
|
||||
* Retrieve a list of notifications.
|
||||
|
@ -56,17 +56,21 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(NotificationStorageCallback)
|
||||
|
||||
NotificationStorageCallback(const GlobalObject& aGlobal, nsPIDOMWindow* aWindow, Promise* aPromise)
|
||||
NotificationStorageCallback(nsIGlobalObject* aWindow, const nsAString& aScope,
|
||||
Promise* aPromise)
|
||||
: mCount(0),
|
||||
mGlobal(aGlobal.Get()),
|
||||
mWindow(aWindow),
|
||||
mPromise(aPromise)
|
||||
mPromise(aPromise),
|
||||
mScope(aScope)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aWindow);
|
||||
MOZ_ASSERT(aPromise);
|
||||
JSContext* cx = aGlobal.Context();
|
||||
JSAutoCompartment ac(cx, mGlobal);
|
||||
mNotifications = JS_NewArrayObject(cx, 0);
|
||||
AutoJSAPI jsapi;
|
||||
DebugOnly<bool> ok = jsapi.Init(aWindow);
|
||||
MOZ_ASSERT(ok);
|
||||
// Created in the compartment of the window.
|
||||
mNotifications = JS_NewArrayObject(jsapi.cx(), 0);
|
||||
HoldData();
|
||||
}
|
||||
|
||||
@ -79,10 +83,17 @@ public:
|
||||
const nsAString& aIcon,
|
||||
const nsAString& aData,
|
||||
const nsAString& aBehavior,
|
||||
const nsAString& aServiceWorkerRegistrationID,
|
||||
JSContext* aCx) override
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(!aID.IsEmpty());
|
||||
|
||||
// Skip scopes that don't match when called from getNotifications().
|
||||
if (!mScope.IsEmpty() && !mScope.Equals(aServiceWorkerRegistrationID)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RootedDictionary<NotificationOptions> options(aCx);
|
||||
options.mDir = Notification::StringToDirection(nsString(aDir));
|
||||
options.mLang = aLang;
|
||||
@ -91,7 +102,6 @@ public:
|
||||
options.mIcon = aIcon;
|
||||
options.mMozbehavior.Init(aBehavior);
|
||||
nsRefPtr<Notification> notification;
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mWindow);
|
||||
notification = Notification::CreateInternal(aID,
|
||||
aTitle,
|
||||
options);
|
||||
@ -102,10 +112,14 @@ public:
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
notification->SetScope(aServiceWorkerRegistrationID);
|
||||
|
||||
notification->SetStoredState(true);
|
||||
|
||||
JSAutoCompartment ac(aCx, mGlobal);
|
||||
JS::Rooted<JSObject*> element(aCx, notification->WrapObject(aCx, nullptr));
|
||||
AutoJSAPI jsapi;
|
||||
DebugOnly<bool> ok = jsapi.Init(mWindow, aCx);
|
||||
MOZ_ASSERT(ok);
|
||||
|
||||
NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
|
||||
|
||||
JS::Rooted<JSObject*> notifications(aCx, mNotifications);
|
||||
@ -117,7 +131,10 @@ public:
|
||||
|
||||
NS_IMETHOD Done(JSContext* aCx) override
|
||||
{
|
||||
JSAutoCompartment ac(aCx, mGlobal);
|
||||
AutoJSAPI jsapi;
|
||||
DebugOnly<bool> ok = jsapi.Init(mWindow, aCx);
|
||||
MOZ_ASSERT(ok);
|
||||
|
||||
JS::Rooted<JS::Value> result(aCx, JS::ObjectValue(*mNotifications));
|
||||
mPromise->MaybeResolve(aCx, result);
|
||||
return NS_OK;
|
||||
@ -136,16 +153,15 @@ private:
|
||||
|
||||
void DropData()
|
||||
{
|
||||
mGlobal = nullptr;
|
||||
mNotifications = nullptr;
|
||||
mozilla::DropJSObjects(this);
|
||||
}
|
||||
|
||||
uint32_t mCount;
|
||||
JS::Heap<JSObject *> mGlobal;
|
||||
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||
nsCOMPtr<nsIGlobalObject> mWindow;
|
||||
nsRefPtr<Promise> mPromise;
|
||||
JS::Heap<JSObject *> mNotifications;
|
||||
const nsString mScope;
|
||||
};
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(NotificationStorageCallback)
|
||||
@ -158,7 +174,6 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(NotificationStorageCallback)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(NotificationStorageCallback)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mGlobal)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mNotifications)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
@ -750,6 +765,7 @@ Notification::ConstructFromFields(
|
||||
const nsAString& aTag,
|
||||
const nsAString& aIcon,
|
||||
const nsAString& aData,
|
||||
const nsAString& aScope,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aGlobal);
|
||||
@ -778,6 +794,8 @@ Notification::ConstructFromFields(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
notification->SetScope(aScope);
|
||||
|
||||
return notification.forget();
|
||||
}
|
||||
|
||||
@ -824,7 +842,8 @@ Notification::PersistNotification()
|
||||
mIconUrl,
|
||||
alertName,
|
||||
dataString,
|
||||
behavior);
|
||||
behavior,
|
||||
mScope);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
@ -1206,9 +1225,11 @@ public:
|
||||
const nsAString& aIcon,
|
||||
const nsAString& aData,
|
||||
const nsAString& aBehavior,
|
||||
const nsAString& aServiceWorkerRegistrationID,
|
||||
JSContext* aCx) override
|
||||
{
|
||||
MOZ_ASSERT(!aID.IsEmpty());
|
||||
MOZ_ASSERT(mScope.Equals(aServiceWorkerRegistrationID));
|
||||
|
||||
AssertIsOnMainThread();
|
||||
|
||||
@ -1621,18 +1642,14 @@ Notification::ResolveIconAndSoundURL(nsString& iconUrl, nsString& soundUrl)
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
Notification::Get(const GlobalObject& aGlobal,
|
||||
Notification::Get(nsPIDOMWindow* aWindow,
|
||||
const GetNotificationOptions& aFilter,
|
||||
const nsAString& aScope,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
nsCOMPtr<nsIGlobalObject> global =
|
||||
do_QueryInterface(aGlobal.GetAsSupports());
|
||||
MOZ_ASSERT(global);
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(global);
|
||||
MOZ_ASSERT(window);
|
||||
MOZ_ASSERT(aWindow);
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
|
||||
nsCOMPtr<nsIDocument> doc = aWindow->GetExtantDoc();
|
||||
if (!doc) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
@ -1644,13 +1661,14 @@ Notification::Get(const GlobalObject& aGlobal,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aWindow);
|
||||
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINotificationStorageCallback> callback =
|
||||
new NotificationStorageCallback(aGlobal, window, promise);
|
||||
new NotificationStorageCallback(global, aScope, promise);
|
||||
|
||||
nsRefPtr<NotificationGetRunnable> r =
|
||||
new NotificationGetRunnable(origin, aFilter.mTag, callback);
|
||||
@ -1663,6 +1681,20 @@ Notification::Get(const GlobalObject& aGlobal,
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
Notification::Get(const GlobalObject& aGlobal,
|
||||
const GetNotificationOptions& aFilter,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
nsCOMPtr<nsIGlobalObject> global =
|
||||
do_QueryInterface(aGlobal.GetAsSupports());
|
||||
MOZ_ASSERT(global);
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(global);
|
||||
|
||||
return Get(window, aFilter, EmptyString(), aRv);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
Notification::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
|
@ -157,6 +157,7 @@ public:
|
||||
const nsAString& aTag,
|
||||
const nsAString& aIcon,
|
||||
const nsAString& aData,
|
||||
const nsAString& aScope,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void GetID(nsAString& aRetval) {
|
||||
@ -214,6 +215,12 @@ public:
|
||||
static NotificationPermission GetPermission(const GlobalObject& aGlobal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<Promise>
|
||||
Get(nsPIDOMWindow* aWindow,
|
||||
const GetNotificationOptions& aFilter,
|
||||
const nsAString& aScope,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<Promise> Get(const GlobalObject& aGlobal,
|
||||
const GetNotificationOptions& aFilter,
|
||||
ErrorResult& aRv);
|
||||
|
@ -84,7 +84,7 @@ NotificationStorage.prototype = {
|
||||
},
|
||||
|
||||
put: function(origin, id, title, dir, lang, body, tag, icon, alertName,
|
||||
data, behavior) {
|
||||
data, behavior, serviceWorkerRegistrationID) {
|
||||
if (DEBUG) { debug("PUT: " + origin + " " + id + ": " + title); }
|
||||
var notification = {
|
||||
id: id,
|
||||
@ -98,7 +98,8 @@ NotificationStorage.prototype = {
|
||||
timestamp: new Date().getTime(),
|
||||
origin: origin,
|
||||
data: data,
|
||||
mozbehavior: behavior
|
||||
mozbehavior: behavior,
|
||||
serviceWorkerRegistrationID: serviceWorkerRegistrationID,
|
||||
};
|
||||
|
||||
this._notifications[id] = notification;
|
||||
@ -140,9 +141,9 @@ NotificationStorage.prototype = {
|
||||
this.searchID = id;
|
||||
this.originalCallback = originalCallback;
|
||||
var self = this;
|
||||
this.handle = function(id, title, dir, lang, body, tag, icon, data, behavior) {
|
||||
this.handle = function(id, title, dir, lang, body, tag, icon, data, behavior, serviceWorkerRegistrationID) {
|
||||
if (id == this.searchID) {
|
||||
self.originalCallback.handle(id, title, dir, lang, body, tag, icon, data, behavior);
|
||||
self.originalCallback.handle(id, title, dir, lang, body, tag, icon, data, behavior, serviceWorkerRegistrationID);
|
||||
}
|
||||
};
|
||||
this.done = function() {
|
||||
@ -244,7 +245,8 @@ NotificationStorage.prototype = {
|
||||
notification.tag,
|
||||
notification.icon,
|
||||
notification.data,
|
||||
notification.mozbehavior),
|
||||
notification.mozbehavior,
|
||||
notification.serviceWorkerRegistrationID),
|
||||
Ci.nsIThread.DISPATCH_NORMAL);
|
||||
} catch (e) {
|
||||
if (DEBUG) { debug("Error calling callback handle: " + e); }
|
||||
|
@ -2295,6 +2295,7 @@ class SendNotificationClickEventRunnable final : public WorkerRunnable
|
||||
const nsString mIcon;
|
||||
const nsString mData;
|
||||
const nsString mBehavior;
|
||||
const nsString mScope;
|
||||
|
||||
public:
|
||||
SendNotificationClickEventRunnable(
|
||||
@ -2308,7 +2309,8 @@ public:
|
||||
const nsAString& aTag,
|
||||
const nsAString& aIcon,
|
||||
const nsAString& aData,
|
||||
const nsAString& aBehavior)
|
||||
const nsAString& aBehavior,
|
||||
const nsAString& aScope)
|
||||
: WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount)
|
||||
, mServiceWorker(aServiceWorker)
|
||||
, mID(aID)
|
||||
@ -2320,6 +2322,7 @@ public:
|
||||
, mIcon(aIcon)
|
||||
, mData(aData)
|
||||
, mBehavior(aBehavior)
|
||||
, mScope(aScope)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
@ -2335,7 +2338,9 @@ public:
|
||||
|
||||
ErrorResult result;
|
||||
nsRefPtr<Notification> notification =
|
||||
Notification::ConstructFromFields(aWorkerPrivate->GlobalScope(), mID, mTitle, mDir, mLang, mBody, mTag, mIcon, mData, result);
|
||||
Notification::ConstructFromFields(aWorkerPrivate->GlobalScope(), mID,
|
||||
mTitle, mDir, mLang, mBody, mTag, mIcon,
|
||||
mData, mScope, result);
|
||||
if (NS_WARN_IF(result.Failed())) {
|
||||
return false;
|
||||
}
|
||||
@ -2383,7 +2388,11 @@ ServiceWorkerManager::SendNotificationClickEvent(const nsACString& aOriginSuffix
|
||||
new nsMainThreadPtrHolder<ServiceWorker>(serviceWorker));
|
||||
|
||||
nsRefPtr<SendNotificationClickEventRunnable> r =
|
||||
new SendNotificationClickEventRunnable(serviceWorker->GetWorkerPrivate(), serviceWorkerHandle, aID, aTitle, aDir, aLang, aBody, aTag, aIcon, aData, aBehavior);
|
||||
new SendNotificationClickEventRunnable(serviceWorker->GetWorkerPrivate(),
|
||||
serviceWorkerHandle, aID, aTitle,
|
||||
aDir, aLang, aBody, aTag, aIcon,
|
||||
aData, aBehavior,
|
||||
NS_ConvertUTF8toUTF16(aScope));
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init();
|
||||
|
@ -637,8 +637,9 @@ ServiceWorkerRegistrationMainThread::ShowNotification(JSContext* aCx,
|
||||
already_AddRefed<Promise>
|
||||
ServiceWorkerRegistrationMainThread::GetNotifications(const GetNotificationOptions& aOptions, ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(false);
|
||||
return nullptr;
|
||||
AssertIsOnMainThread();
|
||||
nsCOMPtr<nsPIDOMWindow> window = GetOwner();
|
||||
return Notification::Get(window, aOptions, mScope, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<PushManager>
|
||||
|
Loading…
Reference in New Issue
Block a user