Bug 862395 - Part 4: Add preference for number of XUL alerts to show with requireInteraction set to true. r=baku

--HG--
extra : rebase_source : 6f4fa3ccd97193b5d6a552747af0fdf600514d39
extra : histedit_source : 81c60c10d3b65f95d41b69aee3a1c17d997ca3bf
This commit is contained in:
William Chen 2016-10-11 01:46:38 -07:00
parent f208316cdd
commit 9899d20949
3 changed files with 86 additions and 4 deletions

View File

@ -4690,6 +4690,7 @@ pref("notification.feature.enabled", false);
// Web Notification
pref("dom.webnotifications.enabled", true);
pref("dom.webnotifications.serviceworker.enabled", true);
pref("dom.webnotifications.requireinteraction.count", 3);
#ifdef NIGHTLY_BUILD
pref("dom.webnotifications.requireinteraction.enabled", true);
#else

View File

@ -46,6 +46,10 @@ nsXULAlertObserver::Observe(nsISupports* aSubject, const char* aTopic,
// be removed if it is the same window that is associated with this listener.
if (currentAlert == mAlertWindow) {
mXULAlerts->mNamedWindows.Remove(mAlertName);
if (mIsPersistent) {
mXULAlerts->PersistentAlertFinished();
}
}
}
@ -74,6 +78,21 @@ nsXULAlerts::GetInstance()
return instance.forget();
}
void
nsXULAlerts::PersistentAlertFinished()
{
MOZ_ASSERT(mPersistentAlertCount);
mPersistentAlertCount--;
// Show next pending persistent alert if any.
if (!mPendingPersistentAlerts.IsEmpty()) {
ShowAlertWithIconURI(mPendingPersistentAlerts[0].mAlert,
mPendingPersistentAlerts[0].mListener,
nullptr);
mPendingPersistentAlerts.RemoveElementAt(0);
}
}
NS_IMETHODIMP
nsXULAlerts::ShowAlertNotification(const nsAString& aImageUrl, const nsAString& aAlertTitle,
const nsAString& aAlertText, bool aAlertTextClickable,
@ -107,7 +126,49 @@ NS_IMETHODIMP
nsXULAlerts::ShowAlert(nsIAlertNotification* aAlert,
nsIObserver* aAlertListener)
{
return ShowAlertWithIconURI(aAlert, aAlertListener, nullptr);
nsAutoString name;
nsresult rv = aAlert->GetName(name);
NS_ENSURE_SUCCESS(rv, rv);
// If there is a pending alert with the same name in the list of
// pending alerts, replace it.
if (!mPendingPersistentAlerts.IsEmpty()) {
for (uint32_t i = 0; i < mPendingPersistentAlerts.Length(); i++) {
nsAutoString pendingAlertName;
nsCOMPtr<nsIAlertNotification> pendingAlert = mPendingPersistentAlerts[i].mAlert;
rv = pendingAlert->GetName(pendingAlertName);
NS_ENSURE_SUCCESS(rv, rv);
if (pendingAlertName.Equals(name)) {
nsAutoString cookie;
rv = pendingAlert->GetCookie(cookie);
NS_ENSURE_SUCCESS(rv, rv);
if (mPendingPersistentAlerts[i].mListener) {
rv = mPendingPersistentAlerts[i].mListener->Observe(nullptr, "alertfinished", cookie.get());
NS_ENSURE_SUCCESS(rv, rv);
}
mPendingPersistentAlerts[i].Init(aAlert, aAlertListener);
return NS_OK;
}
}
}
bool requireInteraction;
rv = aAlert->GetRequireInteraction(&requireInteraction);
NS_ENSURE_SUCCESS(rv, rv);
if (requireInteraction &&
!mNamedWindows.Contains(name) &&
static_cast<int32_t>(mPersistentAlertCount) >=
Preferences::GetInt("dom.webnotifications.requireinteraction.count", 0)) {
PendingAlert* pa = mPendingPersistentAlerts.AppendElement();
pa->Init(aAlert, aAlertListener);
return NS_OK;
} else {
return ShowAlertWithIconURI(aAlert, aAlertListener, nullptr);
}
}
NS_IMETHODIMP
@ -263,11 +324,15 @@ nsXULAlerts::ShowAlertWithIconURI(nsIAlertNotification* aAlert,
rv = argsArray->AppendElement(replacedWindow);
NS_ENSURE_SUCCESS(rv, rv);
if (requireInteraction) {
mPersistentAlertCount++;
}
// Add an observer (that wraps aAlertListener) to remove the window from
// mNamedWindows when it is closed.
nsCOMPtr<nsISupportsInterfacePointer> ifptr = do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
RefPtr<nsXULAlertObserver> alertObserver = new nsXULAlertObserver(this, name, aAlertListener);
RefPtr<nsXULAlertObserver> alertObserver = new nsXULAlertObserver(this, name, aAlertListener, requireInteraction);
nsCOMPtr<nsISupports> iSupports(do_QueryInterface(alertObserver));
ifptr->SetData(iSupports);
ifptr->SetDataIID(&NS_GET_IID(nsIObserver));

View File

@ -7,12 +7,24 @@
#define nsXULAlerts_h__
#include "nsCycleCollectionParticipant.h"
#include "nsDataHashtable.h"
#include "nsHashKeys.h"
#include "nsInterfaceHashtable.h"
#include "mozIDOMWindow.h"
#include "nsIObserver.h"
struct PendingAlert
{
void Init(nsIAlertNotification* aAlert, nsIObserver* aListener)
{
mAlert = aAlert;
mListener = aListener;
}
nsCOMPtr<nsIAlertNotification> mAlert;
nsCOMPtr<nsIObserver> mListener;
};
class nsXULAlerts : public nsIAlertsService,
public nsIAlertsDoNotDisturb,
public nsIAlertsIconURI
@ -32,8 +44,11 @@ public:
protected:
virtual ~nsXULAlerts() {}
void PersistentAlertFinished();
nsInterfaceHashtable<nsStringHashKey, mozIDOMWindowProxy> mNamedWindows;
uint32_t mPersistentAlertCount = 0;
nsTArray<PendingAlert> mPendingPersistentAlerts;
bool mDoNotDisturb = false;
};
@ -49,9 +64,9 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS(nsXULAlertObserver)
nsXULAlertObserver(nsXULAlerts* aXULAlerts, const nsAString& aAlertName,
nsIObserver* aObserver)
nsIObserver* aObserver, bool aIsPersistent)
: mXULAlerts(aXULAlerts), mAlertName(aAlertName),
mObserver(aObserver) {}
mObserver(aObserver), mIsPersistent(aIsPersistent) {}
void SetAlertWindow(mozIDOMWindowProxy* aWindow) { mAlertWindow = aWindow; }
@ -62,6 +77,7 @@ protected:
nsString mAlertName;
nsCOMPtr<mozIDOMWindowProxy> mAlertWindow;
nsCOMPtr<nsIObserver> mObserver;
bool mIsPersistent;
};
#endif /* nsXULAlerts_h__ */