diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/Modules/notifications/Notification.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/Modules/notifications/Notification.cpp')
-rw-r--r-- | Source/WebCore/Modules/notifications/Notification.cpp | 156 |
1 files changed, 82 insertions, 74 deletions
diff --git a/Source/WebCore/Modules/notifications/Notification.cpp b/Source/WebCore/Modules/notifications/Notification.cpp index 20cc0c309..1e02ce1cf 100644 --- a/Source/WebCore/Modules/notifications/Notification.cpp +++ b/Source/WebCore/Modules/notifications/Notification.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2009 Google Inc. All rights reserved. - * Copyright (C) 2009, 2011, 2012 Apple Inc. All rights reserved. + * Copyright (C) 2009, 2011, 2012, 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -37,60 +37,46 @@ #include "DOMWindow.h" #include "DOMWindowNotifications.h" -#include "Dictionary.h" #include "Document.h" -#include "ErrorEvent.h" +#include "Event.h" #include "EventNames.h" +#include "ExceptionCode.h" #include "NotificationCenter.h" -#include "NotificationClient.h" #include "NotificationController.h" #include "NotificationPermissionCallback.h" -#include "ResourceRequest.h" -#include "ResourceResponse.h" -#include "ThreadableLoader.h" +#include "VoidCallback.h" #include "WindowFocusAllowedIndicator.h" -#include "WorkerGlobalScope.h" namespace WebCore { -Notification::Notification() - : ActiveDOMObject(0) -{ -} - #if ENABLE(LEGACY_NOTIFICATIONS) -Notification::Notification(const String& title, const String& body, const String& iconURI, ScriptExecutionContext* context, ExceptionCode& ec, PassRefPtr<NotificationCenter> provider) - : ActiveDOMObject(context) + +Notification::Notification(const String& title, const String& body, URL&& iconURL, ScriptExecutionContext& context, NotificationCenter& notificationCenter) + : ActiveDOMObject(&context) + , m_icon(WTFMove(iconURL)) , m_title(title) , m_body(body) - , m_state(Idle) - , m_notificationCenter(provider) + , m_notificationCenter(¬ificationCenter) { - if (m_notificationCenter->checkPermission() != NotificationClient::PermissionAllowed) { - ec = SECURITY_ERR; - return; - } - - m_icon = iconURI.isEmpty() ? URL() : scriptExecutionContext()->completeURL(iconURI); - if (!m_icon.isEmpty() && !m_icon.isValid()) { - ec = SYNTAX_ERR; - return; - } } + #endif #if ENABLE(NOTIFICATIONS) -Notification::Notification(ScriptExecutionContext& context, const String& title) - : ActiveDOMObject(&context) + +Notification::Notification(Document& document, const String& title) + : ActiveDOMObject(&document) , m_title(title) , m_state(Idle) - , m_taskTimer(adoptPtr(new Timer<Notification>(this, &Notification::taskTimerFired))) + , m_notificationCenter(DOMWindowNotifications::webkitNotifications(*document.domWindow())) + , m_taskTimer(std::make_unique<Timer>([this] () { show(); })) { - m_notificationCenter = DOMWindowNotifications::webkitNotifications(toDocument(context).domWindow()); - + // FIXME: Seems that m_notificationCenter can be null so should not be changed from RefPtr to Ref. + // But the rest of the code in this class isn't trying to handle that case. ASSERT(m_notificationCenter->client()); m_taskTimer->startOneShot(0); } + #endif Notification::~Notification() @@ -98,36 +84,57 @@ Notification::~Notification() } #if ENABLE(LEGACY_NOTIFICATIONS) -PassRefPtr<Notification> Notification::create(const String& title, const String& body, const String& iconURI, ScriptExecutionContext* context, ExceptionCode& ec, PassRefPtr<NotificationCenter> provider) + +ExceptionOr<Ref<Notification>> Notification::create(const String& title, const String& body, const String& iconURL, ScriptExecutionContext& context, NotificationCenter& provider) { - RefPtr<Notification> notification(adoptRef(new Notification(title, body, iconURI, context, ec, provider))); - notification->suspendIfNeeded(); - return notification.release(); + if (provider.checkPermission() != NotificationClient::PermissionAllowed) + return Exception { SECURITY_ERR }; + + URL completedIconURL = iconURL.isEmpty() ? URL() : context.completeURL(iconURL); + if (!completedIconURL.isEmpty() && !completedIconURL.isValid()) + return Exception { SYNTAX_ERR }; + + auto notification = adoptRef(*new Notification(title, body, WTFMove(completedIconURL), context, provider)); + notification.get().suspendIfNeeded(); + return WTFMove(notification); } + #endif #if ENABLE(NOTIFICATIONS) -PassRefPtr<Notification> Notification::create(ScriptExecutionContext& context, const String& title, const Dictionary& options) -{ - RefPtr<Notification> notification(adoptRef(new Notification(context, title))); - String argument; - if (options.get("body", argument)) - notification->setBody(argument); - if (options.get("tag", argument)) - notification->setTag(argument); - if (options.get("lang", argument)) - notification->setLang(argument); - if (options.get("dir", argument)) - notification->setDir(argument); - if (options.get("icon", argument)) { - URL iconURI = argument.isEmpty() ? URL() : context.completeURL(argument); - if (!iconURI.isEmpty() && iconURI.isValid()) - notification->setIconURL(iconURI); + +static String directionString(Notification::Direction direction) +{ + // FIXME: Storing this as a string is not the right way to do it. + // FIXME: Seems highly unlikely that this does the right thing for Auto. + switch (direction) { + case Notification::Direction::Auto: + return ASCIILiteral("auto"); + case Notification::Direction::Ltr: + return ASCIILiteral("ltr"); + case Notification::Direction::Rtl: + return ASCIILiteral("rtl"); } + ASSERT_NOT_REACHED(); + return { }; +} - notification->suspendIfNeeded(); - return notification.release(); +Ref<Notification> Notification::create(Document& context, const String& title, const Options& options) +{ + auto notification = adoptRef(*new Notification(context, title)); + notification.get().m_body = options.body; + notification.get().m_tag = options.tag; + notification.get().m_lang = options.lang; + notification.get().m_direction = directionString(options.dir); + if (!options.icon.isEmpty()) { + auto iconURL = context.completeURL(options.icon); + if (iconURL.isValid()) + notification.get().m_icon = iconURL; + } + notification.get().suspendIfNeeded(); + return notification; } + #endif void Notification::show() @@ -135,9 +142,10 @@ void Notification::show() // prevent double-showing if (m_state == Idle && m_notificationCenter->client()) { #if ENABLE(NOTIFICATIONS) - if (!toDocument(scriptExecutionContext())->page()) + auto* page = downcast<Document>(*scriptExecutionContext()).page(); + if (!page) return; - if (NotificationController::from(toDocument(scriptExecutionContext())->page())->client()->checkPermission(scriptExecutionContext()) != NotificationClient::PermissionAllowed) { + if (NotificationController::from(page)->client().checkPermission(scriptExecutionContext()) != NotificationClient::PermissionAllowed) { dispatchErrorEvent(); return; } @@ -170,6 +178,17 @@ void Notification::contextDestroyed() m_notificationCenter->client()->notificationObjectDestroyed(this); } +const char* Notification::activeDOMObjectName() const +{ + return "Notification"; +} + +bool Notification::canSuspendForDocumentSuspension() const +{ + // We can suspend if the Notification is not shown yet or after it is closed. + return m_state == Idle || m_state == Closed; +} + void Notification::finalize() { if (m_state == Closed) @@ -201,23 +220,13 @@ void Notification::dispatchErrorEvent() } #if ENABLE(NOTIFICATIONS) -void Notification::taskTimerFired(Timer<Notification>& timer) -{ - ASSERT(scriptExecutionContext()->isDocument()); - ASSERT_UNUSED(timer, &timer == m_taskTimer.get()); - show(); -} -#endif - -#if ENABLE(NOTIFICATIONS) -const String Notification::permission(ScriptExecutionContext* context) +String Notification::permission(Document& document) { - ASSERT(toDocument(context)->page()); - return permissionString(NotificationController::from(toDocument(context)->page())->client()->checkPermission(context)); + return permissionString(NotificationController::from(document.page())->client().checkPermission(&document)); } -const String Notification::permissionString(NotificationClient::Permission permission) +String Notification::permissionString(NotificationClient::Permission permission) { switch (permission) { case NotificationClient::PermissionAllowed: @@ -227,16 +236,15 @@ const String Notification::permissionString(NotificationClient::Permission permi case NotificationClient::PermissionNotAllowed: return ASCIILiteral("default"); } - ASSERT_NOT_REACHED(); - return String(); + return { }; } -void Notification::requestPermission(ScriptExecutionContext* context, PassRefPtr<NotificationPermissionCallback> callback) +void Notification::requestPermission(Document& document, RefPtr<NotificationPermissionCallback>&& callback) { - ASSERT(toDocument(context)->page()); - NotificationController::from(toDocument(context)->page())->client()->requestPermission(context, callback); + NotificationController::from(document.page())->client().requestPermission(&document, WTFMove(callback)); } + #endif } // namespace WebCore |