summaryrefslogtreecommitdiffstats
path: root/WebCore/notifications/Notification.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/notifications/Notification.cpp')
-rw-r--r--WebCore/notifications/Notification.cpp234
1 files changed, 234 insertions, 0 deletions
diff --git a/WebCore/notifications/Notification.cpp b/WebCore/notifications/Notification.cpp
new file mode 100644
index 0000000..266392b
--- /dev/null
+++ b/WebCore/notifications/Notification.cpp
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(NOTIFICATIONS)
+
+#include "Notification.h"
+#include "NotificationContents.h"
+
+#include "Document.h"
+#include "EventNames.h"
+#include "WorkerContext.h"
+
+namespace WebCore {
+
+Notification::Notification(const String& url, ScriptExecutionContext* context, ExceptionCode& ec, NotificationPresenter* provider)
+ : ActiveDOMObject(context, this)
+ , m_isHTML(true)
+ , m_isShowing(false)
+ , m_presenter(provider)
+{
+ if (m_presenter->checkPermission(context->securityOrigin()) != NotificationPresenter::PERMISSION_ALLOWED) {
+ ec = SECURITY_ERR;
+ return;
+ }
+
+ m_notificationURL = context->completeURL(url);
+ if (url.isEmpty() || !m_notificationURL.isValid()) {
+ ec = SYNTAX_ERR;
+ return;
+ }
+}
+
+Notification::Notification(const NotificationContents& contents, ScriptExecutionContext* context, ExceptionCode& ec, NotificationPresenter* provider)
+ : ActiveDOMObject(context, this)
+ , m_isHTML(false)
+ , m_contents(contents)
+ , m_isShowing(false)
+ , m_presenter(provider)
+{
+ if (m_presenter->checkPermission(context->securityOrigin()) != NotificationPresenter::PERMISSION_ALLOWED) {
+ ec = SECURITY_ERR;
+ return;
+ }
+
+ KURL icon = context->completeURL(contents.icon());
+ if (!icon.isEmpty() && !icon.isValid()) {
+ ec = SYNTAX_ERR;
+ return;
+ }
+}
+
+Notification::~Notification()
+{
+ m_presenter->notificationObjectDestroyed(this);
+}
+
+void Notification::show()
+{
+ // prevent double-showing
+ if (!m_isShowing)
+ m_isShowing = m_presenter->show(this);
+}
+
+void Notification::cancel()
+{
+ if (m_isShowing)
+ m_presenter->cancel(this);
+}
+
+EventListener* Notification::ondisplay() const
+{
+ return getAttributeEventListener("display");
+}
+
+void Notification::setOndisplay(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener("display", eventListener);
+}
+
+EventListener* Notification::onerror() const
+{
+ return getAttributeEventListener(eventNames().errorEvent);
+}
+
+void Notification::setOnerror(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().errorEvent, eventListener);
+}
+
+EventListener* Notification::onclose() const
+{
+ return getAttributeEventListener(eventNames().closeEvent);
+}
+
+void Notification::setOnclose(PassRefPtr<EventListener> eventListener)
+{
+ setAttributeEventListener(eventNames().closeEvent, eventListener);
+}
+
+EventListener* Notification::getAttributeEventListener(const AtomicString& eventType) const
+{
+ const RegisteredEventListenerVector& listeners = m_eventListeners;
+ size_t size = listeners.size();
+ for (size_t i = 0; i < size; ++i) {
+ const RegisteredEventListener& r = *listeners[i];
+ if (r.eventType() == eventType && r.listener()->isAttribute())
+ return r.listener();
+ }
+ return 0;
+}
+
+void Notification::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener)
+{
+ clearAttributeEventListener(eventType);
+ if (listener)
+ addEventListener(eventType, listener, false);
+}
+
+void Notification::clearAttributeEventListener(const AtomicString& eventType)
+{
+ RegisteredEventListenerVector* listeners = &m_eventListeners;
+ size_t size = listeners->size();
+ for (size_t i = 0; i < size; ++i) {
+ RegisteredEventListener& r = *listeners->at(i);
+ if (r.eventType() != eventType || !r.listener()->isAttribute())
+ continue;
+
+ r.setRemoved(true);
+ listeners->remove(i);
+ return;
+ }
+}
+
+void Notification::dispatchDisplayEvent()
+{
+ RefPtr<Event> event = Event::create("display", false, true);
+ ExceptionCode ec = 0;
+ dispatchEvent(event.release(), ec);
+ ASSERT(!ec);
+}
+
+void Notification::dispatchErrorEvent()
+{
+ RefPtr<Event> event = Event::create(eventNames().errorEvent, false, true);
+ ExceptionCode ec = 0;
+ dispatchEvent(event.release(), ec);
+ ASSERT(!ec);
+}
+
+void Notification::dispatchCloseEvent()
+{
+ RefPtr<Event> event = Event::create(eventNames().closeEvent, false, true);
+ ExceptionCode ec = 0;
+ dispatchEvent(event.release(), ec);
+ ASSERT(!ec);
+}
+
+void Notification::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
+{
+ RefPtr<RegisteredEventListener> registeredListener = RegisteredEventListener::create(eventType, listener, useCapture);
+ m_eventListeners.append(registeredListener);
+}
+
+void Notification::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
+{
+ size_t size = m_eventListeners.size();
+ for (size_t i = 0; i < size; ++i) {
+ RegisteredEventListener& r = *m_eventListeners[i];
+ if (r.eventType() == eventType && r.listener() == listener && r.useCapture() == useCapture) {
+ r.setRemoved(true);
+ m_eventListeners.remove(i);
+ return;
+ }
+ }
+}
+
+void Notification::handleEvent(PassRefPtr<Event> event, bool useCapture)
+{
+ RegisteredEventListenerVector listenersCopy = m_eventListeners;
+ size_t size = listenersCopy.size();
+ for (size_t i = 0; i < size; ++i) {
+ RegisteredEventListener& r = *listenersCopy[i];
+ if (r.eventType() == event->type() && r.useCapture() == useCapture && !r.removed())
+ r.listener()->handleEvent(event.get());
+ }
+}
+
+bool Notification::dispatchEvent(PassRefPtr<Event> inEvent, ExceptionCode&)
+{
+ RefPtr<Event> event(inEvent);
+
+ event->setEventPhase(Event::AT_TARGET);
+ event->setCurrentTarget(this);
+
+ handleEvent(event.get(), true);
+ if (!event->propagationStopped()) {
+ handleEvent(event.get(), false);
+ }
+
+ return !event->defaultPrevented();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(NOTIFICATIONS)