1 /*
2 * Copyright (C) 2008, 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 #include "XMLHttpRequestUpload.h"
33
34 #include "ExceptionCode.h"
35 #include "V8Binding.h"
36 #include "V8CustomBinding.h"
37 #include "V8ObjectEventListener.h"
38 #include "V8Proxy.h"
39 #include "V8Utilities.h"
40 #include "XMLHttpRequest.h"
41
42 #include <wtf/Assertions.h>
43
44 namespace WebCore {
45
ACCESSOR_GETTER(XMLHttpRequestUploadOnabort)46 ACCESSOR_GETTER(XMLHttpRequestUploadOnabort)
47 {
48 INC_STATS("DOM.XMLHttpRequestUpload.onabort._get");
49 XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
50 if (xmlHttpRequestUpload->onabort()) {
51 V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onabort());
52 v8::Local<v8::Object> v8Listener = listener->getListenerObject();
53 return v8Listener;
54 }
55 return v8::Null();
56 }
57
ACCESSOR_SETTER(XMLHttpRequestUploadOnabort)58 ACCESSOR_SETTER(XMLHttpRequestUploadOnabort)
59 {
60 INC_STATS("DOM.XMLHttpRequestUpload.onabort._set");
61 XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
62 if (value->IsNull()) {
63 if (xmlHttpRequestUpload->onabort()) {
64 V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onabort());
65 v8::Local<v8::Object> v8Listener = listener->getListenerObject();
66 removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
67 }
68
69 // Clear the listener.
70 xmlHttpRequestUpload->setOnabort(0);
71 } else {
72 XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
73 V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
74 if (!proxy)
75 return;
76
77 RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
78 if (listener) {
79 xmlHttpRequestUpload->setOnabort(listener);
80 createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
81 }
82 }
83 }
84
ACCESSOR_GETTER(XMLHttpRequestUploadOnerror)85 ACCESSOR_GETTER(XMLHttpRequestUploadOnerror)
86 {
87 INC_STATS("DOM.XMLHttpRequestUpload.onerror._get");
88 XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
89 if (xmlHttpRequestUpload->onerror()) {
90 V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onerror());
91 v8::Local<v8::Object> v8Listener = listener->getListenerObject();
92 return v8Listener;
93 }
94 return v8::Null();
95 }
96
ACCESSOR_SETTER(XMLHttpRequestUploadOnerror)97 ACCESSOR_SETTER(XMLHttpRequestUploadOnerror)
98 {
99 INC_STATS("DOM.XMLHttpRequestUpload.onerror._set");
100 XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
101 if (value->IsNull()) {
102 if (xmlHttpRequestUpload->onerror()) {
103 V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onerror());
104 v8::Local<v8::Object> v8Listener = listener->getListenerObject();
105 removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
106 }
107
108 // Clear the listener.
109 xmlHttpRequestUpload->setOnerror(0);
110 } else {
111 XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
112 V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
113 if (!proxy)
114 return;
115
116 RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
117 if (listener) {
118 xmlHttpRequestUpload->setOnerror(listener);
119 createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
120 }
121 }
122 }
123
ACCESSOR_GETTER(XMLHttpRequestUploadOnload)124 ACCESSOR_GETTER(XMLHttpRequestUploadOnload)
125 {
126 INC_STATS("DOM.XMLHttpRequestUpload.onload._get");
127 XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
128 if (xmlHttpRequestUpload->onload()) {
129 V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onload());
130 v8::Local<v8::Object> v8Listener = listener->getListenerObject();
131 return v8Listener;
132 }
133 return v8::Null();
134 }
135
ACCESSOR_SETTER(XMLHttpRequestUploadOnload)136 ACCESSOR_SETTER(XMLHttpRequestUploadOnload)
137 {
138 INC_STATS("DOM.XMLHttpRequestUpload.onload._set");
139 XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
140 if (value->IsNull()) {
141 if (xmlHttpRequestUpload->onload()) {
142 V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onload());
143 v8::Local<v8::Object> v8Listener = listener->getListenerObject();
144 removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
145 }
146
147 // Clear the listener.
148 xmlHttpRequestUpload->setOnload(0);
149 } else {
150 XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
151 V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
152 if (!proxy)
153 return;
154
155 RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
156 if (listener) {
157 xmlHttpRequestUpload->setOnload(listener);
158 createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
159 }
160 }
161 }
162
ACCESSOR_GETTER(XMLHttpRequestUploadOnloadstart)163 ACCESSOR_GETTER(XMLHttpRequestUploadOnloadstart)
164 {
165 INC_STATS("DOM.XMLHttpRequestUpload.onloadstart._get");
166 XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
167 if (xmlHttpRequestUpload->onloadstart()) {
168 V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onloadstart());
169 v8::Local<v8::Object> v8Listener = listener->getListenerObject();
170 return v8Listener;
171 }
172 return v8::Null();
173 }
174
ACCESSOR_SETTER(XMLHttpRequestUploadOnloadstart)175 ACCESSOR_SETTER(XMLHttpRequestUploadOnloadstart)
176 {
177 INC_STATS("DOM.XMLHttpRequestUpload.onloadstart._set");
178 XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
179 if (value->IsNull()) {
180 if (xmlHttpRequestUpload->onloadstart()) {
181 V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onloadstart());
182 v8::Local<v8::Object> v8Listener = listener->getListenerObject();
183 removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
184 }
185
186 // Clear the listener.
187 xmlHttpRequestUpload->setOnloadstart(0);
188 } else {
189 XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
190 V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
191 if (!proxy)
192 return;
193
194 RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
195 if (listener) {
196 xmlHttpRequestUpload->setOnloadstart(listener);
197 createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
198 }
199 }
200 }
201
ACCESSOR_GETTER(XMLHttpRequestUploadOnprogress)202 ACCESSOR_GETTER(XMLHttpRequestUploadOnprogress)
203 {
204 INC_STATS("DOM.XMLHttpRequestUpload.onprogress._get");
205 XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
206 if (xmlHttpRequestUpload->onprogress()) {
207 V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onprogress());
208 v8::Local<v8::Object> v8Listener = listener->getListenerObject();
209 return v8Listener;
210 }
211 return v8::Null();
212 }
213
ACCESSOR_SETTER(XMLHttpRequestUploadOnprogress)214 ACCESSOR_SETTER(XMLHttpRequestUploadOnprogress)
215 {
216 INC_STATS("DOM.XMLHttpRequestUpload.onprogress._set");
217 XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
218 if (value->IsNull()) {
219 if (xmlHttpRequestUpload->onprogress()) {
220 V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onprogress());
221 v8::Local<v8::Object> v8Listener = listener->getListenerObject();
222 removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
223 }
224
225 // Clear the listener.
226 xmlHttpRequestUpload->setOnprogress(0);
227 } else {
228 XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
229 V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
230 if (!proxy)
231 return;
232
233 RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
234 if (listener) {
235 xmlHttpRequestUpload->setOnprogress(listener);
236 createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
237 }
238 }
239 }
240
CALLBACK_FUNC_DECL(XMLHttpRequestUploadAddEventListener)241 CALLBACK_FUNC_DECL(XMLHttpRequestUploadAddEventListener)
242 {
243 INC_STATS("DOM.XMLHttpRequestUpload.addEventListener()");
244 XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, args.Holder());
245
246 XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
247 V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
248 if (!proxy)
249 return v8::Undefined();
250
251 RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), args[1], false);
252 if (listener) {
253 String type = toWebCoreString(args[0]);
254 bool useCapture = args[2]->BooleanValue();
255 xmlHttpRequestUpload->addEventListener(type, listener, useCapture);
256
257 createHiddenDependency(args.Holder(), args[1], V8Custom::kXMLHttpRequestCacheIndex);
258 }
259 return v8::Undefined();
260 }
261
CALLBACK_FUNC_DECL(XMLHttpRequestUploadRemoveEventListener)262 CALLBACK_FUNC_DECL(XMLHttpRequestUploadRemoveEventListener)
263 {
264 INC_STATS("DOM.XMLHttpRequestUpload.removeEventListener()");
265 XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, args.Holder());
266
267 XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
268 V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
269 if (!proxy)
270 return v8::Undefined(); // Probably leaked.
271
272 RefPtr<EventListener> listener = proxy->objectListeners()->findWrapper(args[1], false);
273
274 if (listener) {
275 String type = toWebCoreString(args[0]);
276 bool useCapture = args[2]->BooleanValue();
277 xmlHttpRequestUpload->removeEventListener(type, listener.get(), useCapture);
278
279 removeHiddenDependency(args.Holder(), args[1], V8Custom::kXMLHttpRequestCacheIndex);
280 }
281
282 return v8::Undefined();
283 }
284
CALLBACK_FUNC_DECL(XMLHttpRequestUploadDispatchEvent)285 CALLBACK_FUNC_DECL(XMLHttpRequestUploadDispatchEvent)
286 {
287 INC_STATS("DOM.XMLHttpRequestUpload.dispatchEvent()");
288 return throwError(NOT_SUPPORTED_ERR);
289 }
290
291 } // namespace WebCore
292