1/*
2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include "config.h"
32
33#if ENABLE(NOTIFICATIONS)
34
35#include "v8_binding.h"
36#include "v8_custom.h"
37#include "v8_proxy.h"
38
39#include "NotImplemented.h"
40#include "Notification.h"
41#include "WorkerContext.h"
42#include "WorkerContextExecutionProxy.h"
43#include "V8Binding.h"
44#include "V8CustomEventListener.h"
45#include "V8Utilities.h"
46
47namespace WebCore {
48
49ACCESSOR_GETTER(NotificationOndisplay)
50{
51 INC_STATS(L"DOM.Notification.ondisplay._get");
52 Notification* notif = V8Proxy::ToNativeObject<Notification>(V8ClassIndex::NOTIFICATION, info.Holder());
53 if (notif->ondisplay()) {
54 V8EventListener* listener = static_cast<V8EventListener*>(notif->ondisplay());
55 v8::Local<v8::Object> v8Listener = listener->getListenerObject();
56 return v8Listener;
57 }
58 return v8::Undefined();
59}
60
61ACCESSOR_SETTER(NotificationOndisplay)
62{
63 INC_STATS(L"DOM.Notification.ondisplay._set");
64 Notification* notif = V8Proxy::ToNativeObject<Notification>(V8ClassIndex::NOTIFICATION, info.Holder());
65 V8EventListener* oldListener = static_cast<V8EventListener*>(notif->ondisplay());
66 if (value->IsNull()) {
67 if (oldListener) {
68 v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
69 removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kNotificationRequestCacheIndex);
70 }
71
72 // Clear the listener
73 notif->setOndisplay(0);
74 } else {
75 RefPtr<EventListener> listener =
76 static_cast<WorkerContext*>(notif->scriptExecutionContext())->script()->proxy()->findOrCreateEventListener(
77 v8::Local<v8::Object>::Cast(value), false, false);
78 if (listener) {
79 if (oldListener) {
80 v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
81 removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kNotificationRequestCacheIndex);
82 }
83
84 notif->setOndisplay(listener);
85 createHiddenDependency(info.Holder(), value, V8Custom::kNotificationRequestCacheIndex);
86 }
87 }
88}
89
90ACCESSOR_GETTER(NotificationOnerror)
91{
92 INC_STATS(L"DOM.Notification.onerror._get");
93 Notification* notif = V8Proxy::ToNativeObject<Notification>(V8ClassIndex::NOTIFICATION, info.Holder());
94 if (notif->onerror()) {
95 V8EventListener* listener = static_cast<V8EventListener*>(notif->onerror());
96 v8::Local<v8::Object> v8Listener = listener->getListenerObject();
97 return v8Listener;
98 }
99 return v8::Undefined();
100}
101
102ACCESSOR_SETTER(NotificationOnerror)
103{
104 INC_STATS(L"DOM.Notification.onerror._set");
105 Notification* notif = V8Proxy::ToNativeObject<Notification>(V8ClassIndex::NOTIFICATION, info.Holder());
106 V8EventListener* oldListener = static_cast<V8EventListener*>(notif->onerror());
107 if (value->IsNull()) {
108 if (oldListener) {
109 v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
110 removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kNotificationRequestCacheIndex);
111 }
112
113 // Clear the listener
114 notif->setOnerror(0);
115 } else {
116 RefPtr<V8EventListener> listener =
117 static_cast<WorkerContext*>(notif->scriptExecutionContext())->script()->proxy()->findOrCreateEventListener(
118 v8::Local<v8::Object>::Cast(value), false, false);
119 if (listener) {
120 if (oldListener) {
121 v8::Local<v8::Object> oldV8Listener =
122 oldListener->getListenerObject();
123 removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kNotificationRequestCacheIndex);
124 }
125
126 notif->setOnerror(listener);
127 createHiddenDependency(info.Holder(), value, V8Custom::kNotificationRequestCacheIndex);
128 }
129 }
130}
131
132ACCESSOR_GETTER(NotificationOnclose)
133{
134 INC_STATS(L"DOM.Notification.onclose._get");
135 Notification* notif = V8Proxy::ToNativeObject<Notification>(V8ClassIndex::NOTIFICATION, info.Holder());
136 if (notif->onclose()) {
137 V8EventListener* listener = static_cast<V8EventListener*>(notif->onclose());
138 v8::Local<v8::Object> v8Listener = listener->getListenerObject();
139 return v8Listener;
140 }
141 return v8::Undefined();
142}
143
144ACCESSOR_SETTER(NotificationOnclose)
145{
146 INC_STATS(L"DOM.Notification.onclose._set");
147 Notification* notif = V8Proxy::ToNativeObject<Notification>(V8ClassIndex::NOTIFICATION, info.Holder());
148 V8EventListener* oldListener = static_cast<V8EventListener*>(notif->onclose());
149 if (value->IsNull()) {
150 if (oldListener) {
151 v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
152 removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kNotificationRequestCacheIndex);
153 }
154
155 // Clear the listener
156 notif->setOnclose(0);
157 } else {
158 RefPtr<V8EventListener> listener =
159 static_cast<WorkerContext*>(notif->scriptExecutionContext())->script()->proxy()->findOrCreateEventListener(
160 v8::Local<v8::Object>::Cast(value), false, false);
161 if (listener) {
162 if (oldListener) {
163 v8::Local<v8::Object> oldV8Listener =
164 oldListener->getListenerObject();
165 removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kNotificationRequestCacheIndex);
166 }
167
168 notif->setOnclose(listener);
169 createHiddenDependency(info.Holder(), value, V8Custom::kNotificationRequestCacheIndex);
170 }
171 }
172}
173
174CALLBACK_FUNC_DECL(NotificationsCreateHTMLNotification)
175{
176 INC_STATS(L"DOM.Notifications.CreateHTMLNotification()");
177 Notifications* notifInterface = V8Proxy::ToNativeObject<Notifications>(V8ClassIndex::NOTIFICATIONS, args.Holder());
178
179 ExceptionCode ec;
180 String url = toWebCoreString(args[0]);
181 RefPtr<Notification> notif = Notification::create(url, notifInterface->context(), ec, notifInterface->provider());
182
183 return WorkerContextExecutionProxy::ToV8Object(V8ClassIndex::NOTIFICATION, notif.get());
184}
185
186CALLBACK_FUNC_DECL(NotificationsCreateNotification)
187{
188 INC_STATS(L"DOM.Notifications.CreateNotification()");
189 return v8::Undefined();
190}
191
192CALLBACK_FUNC_DECL(NotificationShow)
193{
194 INC_STATS(L"DOM.Notification.Show()");
195 Notification* notif = V8Proxy::ToNativeObject<Notification>(V8ClassIndex::NOTIFICATION, args.Holder());
196 notif->show();
197
198 return v8::Undefined();
199}
200
201CALLBACK_FUNC_DECL(NotificationCancel)
202{
203 INC_STATS(L"DOM.Notification.Cancel()");
204 Notification* notif = V8Proxy::ToNativeObject<Notification>(V8ClassIndex::NOTIFICATION, args.Holder());
205 notif->cancel();
206
207 return v8::Undefined();
208}
209
210} // namespace WebCore
211
212#endif // ENABLE(NOTIFICATIONS)