NotificationCenter.cpp [plain text]
#include "config.h"
#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
#include "NotificationCenter.h"
#include "Notification.h"
#include "ScriptExecutionContext.h"
#include "SecurityOrigin.h"
namespace WebCore {
Ref<NotificationCenter> NotificationCenter::create(ScriptExecutionContext* context, NotificationClient* client)
{
auto notificationCenter = adoptRef(*new NotificationCenter(context, client));
notificationCenter->suspendIfNeeded();
return notificationCenter;
}
NotificationCenter::NotificationCenter(ScriptExecutionContext* context, NotificationClient* client)
: ActiveDOMObject(context)
, m_client(client)
, m_timer([this]() { timerFired(); })
{
}
#if ENABLE(LEGACY_NOTIFICATIONS)
RefPtr<Notification> NotificationCenter::createNotification(const String& iconURI, const String& title, const String& body, ExceptionCode& ec)
{
if (!m_client) {
ec = INVALID_STATE_ERR;
return nullptr;
}
return Notification::create(title, body, iconURI, scriptExecutionContext(), ec, this);
}
int NotificationCenter::checkPermission()
{
if (!m_client || !scriptExecutionContext())
return NotificationClient::PermissionDenied;
switch (scriptExecutionContext()->securityOrigin()->canShowNotifications()) {
case SecurityOrigin::AlwaysAllow:
return NotificationClient::PermissionAllowed;
case SecurityOrigin::AlwaysDeny:
return NotificationClient::PermissionDenied;
case SecurityOrigin::Ask:
return m_client->checkPermission(scriptExecutionContext());
}
ASSERT_NOT_REACHED();
return m_client->checkPermission(scriptExecutionContext());
}
void NotificationCenter::requestPermission(const RefPtr<VoidCallback>& callback)
{
if (!m_client || !scriptExecutionContext())
return;
switch (scriptExecutionContext()->securityOrigin()->canShowNotifications()) {
case SecurityOrigin::AlwaysAllow:
case SecurityOrigin::AlwaysDeny:
if (m_callbacks.isEmpty()) {
ref(); m_timer.startOneShot(0);
}
m_callbacks.append([callback]() {
if (callback)
callback->handleEvent();
});
return;
case SecurityOrigin::Ask:
m_client->requestPermission(scriptExecutionContext(), callback.get());
return;
}
ASSERT_NOT_REACHED();
m_client->requestPermission(scriptExecutionContext(), callback.get());
}
#endif
void NotificationCenter::stop()
{
if (!m_client)
return;
auto& client = *std::exchange(m_client, nullptr);
Ref<NotificationCenter> protector(*this);
if (!m_callbacks.isEmpty())
deref();
m_timer.stop();
m_callbacks.clear();
client.cancelRequestsForPermission(scriptExecutionContext());
client.clearNotifications(scriptExecutionContext());
}
const char* NotificationCenter::activeDOMObjectName() const
{
return "NotificationCenter";
}
bool NotificationCenter::canSuspendForPageCache() const
{
return m_callbacks.isEmpty() && (!m_client || !m_client->hasPendingPermissionRequests(scriptExecutionContext()));
}
void NotificationCenter::timerFired()
{
ASSERT(m_client);
auto callbacks = WTF::move(m_callbacks);
for (auto& callback : callbacks)
callback();
deref(); }
}
#endif // ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)