Rename OptionsObject to Dictionary
[WebKit-https.git] / Source / WebCore / bindings / v8 / Dictionary.cpp
1 /*
2  * Copyright (C) 2010 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
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "Dictionary.h"
28
29 #include "DOMStringList.h"
30 #include "V8Binding.h"
31 #include "V8DOMWindow.h"
32 #include "V8Storage.h"
33 #include "V8Utilities.h"
34 #include <wtf/MathExtras.h>
35
36 #if ENABLE(INDEXED_DATABASE)
37 #include "IDBKeyRange.h"
38 #include "V8IDBKeyRange.h"
39 #endif
40
41 #if ENABLE(VIDEO_TRACK)
42 #include "TrackBase.h"
43 #include "V8TextTrack.h"
44 #endif
45
46 #if ENABLE(SCRIPTED_SPEECH)
47 #include "SpeechRecognitionError.h"
48 #include "SpeechRecognitionResult.h"
49 #include "SpeechRecognitionResultList.h"
50 #include "V8SpeechRecognitionError.h"
51 #include "V8SpeechRecognitionResult.h"
52 #include "V8SpeechRecognitionResultList.h"
53 #endif
54
55 namespace WebCore {
56
57 Dictionary::Dictionary()
58 {
59 }
60
61 Dictionary::Dictionary(const v8::Local<v8::Value>& options)
62     : m_options(options)
63 {
64 }
65
66 Dictionary::~Dictionary()
67 {
68 }
69
70 Dictionary& Dictionary::operator=(const Dictionary& optionsObject)
71 {
72     m_options = optionsObject.m_options;
73     return *this;
74 }
75
76 bool Dictionary::isObject() const
77 {
78     return !isUndefinedOrNull() && m_options->IsObject();
79 }
80
81 bool Dictionary::isUndefinedOrNull() const
82 {
83     if (m_options.IsEmpty())
84         return true;
85     return WebCore::isUndefinedOrNull(m_options);
86 }
87
88 bool Dictionary::getKey(const String& key, v8::Local<v8::Value>& value) const
89 {
90     if (isUndefinedOrNull())
91         return false;
92     v8::Local<v8::Object> options = m_options->ToObject();
93     ASSERT(!options.IsEmpty());
94
95     v8::Handle<v8::String> v8Key = v8String(key);
96     if (!options->Has(v8Key))
97         return false;
98     value = options->Get(v8Key);
99     if (value.IsEmpty())
100         return false;
101     return true;
102 }
103
104 bool Dictionary::get(const String& key, bool& value) const
105 {
106     v8::Local<v8::Value> v8Value;
107     if (!getKey(key, v8Value))
108         return false;
109
110     v8::Local<v8::Boolean> v8Bool = v8Value->ToBoolean();
111     if (v8Bool.IsEmpty())
112         return false;
113     value = v8Bool->Value();
114     return true;
115 }
116
117 bool Dictionary::get(const String& key, int32_t& value) const
118 {
119     v8::Local<v8::Value> v8Value;
120     if (!getKey(key, v8Value))
121         return false;
122
123     v8::Local<v8::Int32> v8Int32 = v8Value->ToInt32();
124     if (v8Int32.IsEmpty())
125         return false;
126     value = v8Int32->Value();
127     return true;
128 }
129
130 bool Dictionary::get(const String& key, double& value) const
131 {
132     v8::Local<v8::Value> v8Value;
133     if (!getKey(key, v8Value))
134         return false;
135
136     v8::Local<v8::Number> v8Number = v8Value->ToNumber();
137     if (v8Number.IsEmpty())
138         return false;
139     value = v8Number->Value();
140     return true;
141 }
142
143 bool Dictionary::get(const String& key, String& value) const
144 {
145     v8::Local<v8::Value> v8Value;
146     if (!getKey(key, v8Value))
147         return false;
148
149     // FIXME: It is possible for this to throw in which case we'd be getting back
150     //        an empty string and returning true when we should be returning false.
151     //        See fast/dom/Geolocation/script-tests/argument-types.js for a similar
152     //        example.
153     value = v8ValueToWebCoreString(v8Value);
154     return true;
155 }
156
157 bool Dictionary::get(const String& key, ScriptValue& value) const
158 {
159     v8::Local<v8::Value> v8Value;
160     if (!getKey(key, v8Value))
161         return false;
162
163     value = ScriptValue(v8Value);
164     return true;
165 }
166
167 bool Dictionary::get(const String& key, unsigned short& value) const
168 {
169     v8::Local<v8::Value> v8Value;
170     if (!getKey(key, v8Value))
171         return false;
172
173     v8::Local<v8::Int32> v8Int32 = v8Value->ToInt32();
174     if (v8Int32.IsEmpty())
175         return false;
176     value = static_cast<unsigned short>(v8Int32->Value());
177     return true;
178 }
179
180 bool Dictionary::get(const String& key, short& value) const
181 {
182     v8::Local<v8::Value> v8Value;
183     if (!getKey(key, v8Value))
184         return false;
185
186     v8::Local<v8::Int32> v8Int32 = v8Value->ToInt32();
187     if (v8Int32.IsEmpty())
188         return false;
189     value = static_cast<short>(v8Int32->Value());
190     return true;
191 }
192
193 bool Dictionary::get(const String& key, unsigned& value) const
194 {
195     v8::Local<v8::Value> v8Value;
196     if (!getKey(key, v8Value))
197         return false;
198
199     v8::Local<v8::Int32> v8Int32 = v8Value->ToInt32();
200     if (v8Int32.IsEmpty())
201         return false;
202     value = static_cast<unsigned>(v8Int32->Value());
203     return true;
204 }
205
206 bool Dictionary::get(const String& key, unsigned long long& value) const
207 {
208     v8::Local<v8::Value> v8Value;
209     if (!getKey(key, v8Value))
210         return false;
211
212     v8::Local<v8::Number> v8Number = v8Value->ToNumber();
213     if (v8Number.IsEmpty())
214         return false;
215     double d = v8Number->Value();
216     doubleToInteger(d, value);
217     return true;
218 }
219
220 bool Dictionary::get(const String& key, RefPtr<DOMWindow>& value) const
221 {
222     v8::Local<v8::Value> v8Value;
223     if (!getKey(key, v8Value))
224         return false;
225
226     DOMWindow* source = 0;
227     if (v8Value->IsObject()) {
228         v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
229         v8::Handle<v8::Object> window = V8DOMWrapper::lookupDOMWrapper(V8DOMWindow::GetTemplate(), wrapper);
230         if (!window.IsEmpty())
231             source = V8DOMWindow::toNative(window);
232     }
233     value = source;
234     return true;
235 }
236
237 bool Dictionary::get(const String& key, RefPtr<Storage>& value) const
238 {
239     v8::Local<v8::Value> v8Value;
240     if (!getKey(key, v8Value))
241         return false;
242
243     Storage* source = 0;
244     if (v8Value->IsObject()) {
245         v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
246         v8::Handle<v8::Object> storage = V8DOMWrapper::lookupDOMWrapper(V8Storage::GetTemplate(), wrapper);
247         if (!storage.IsEmpty())
248             source = V8Storage::toNative(storage);
249     }
250     value = source;
251     return true;
252 }
253
254 bool Dictionary::get(const String& key, MessagePortArray& value) const
255 {
256     v8::Local<v8::Value> v8Value;
257     if (!getKey(key, v8Value))
258         return false;
259
260     return getMessagePortArray(v8Value, value);
261 }
262
263 bool Dictionary::get(const String& key, HashSet<AtomicString>& value) const
264 {
265     v8::Local<v8::Value> v8Value;
266     if (!getKey(key, v8Value))
267         return false;
268
269     // FIXME: Support array-like objects
270     if (!v8Value->IsArray())
271         return false;
272
273     v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(v8Value);
274     for (size_t i = 0; i < v8Array->Length(); ++i) {
275         v8::Local<v8::Value> indexedValue = v8Array->Get(v8::Integer::New(i));
276         value.add(v8ValueToWebCoreString(indexedValue));
277     }
278
279     return true;
280 }
281
282 bool Dictionary::getWithUndefinedOrNullCheck(const String& key, String& value) const
283 {
284     v8::Local<v8::Value> v8Value;
285     if (!getKey(key, v8Value) || v8Value->IsNull() || v8Value->IsUndefined())
286         return false;
287
288     // FIXME: It is possible for this to throw in which case we'd be getting back
289     //        an empty string and returning true when we should be returning false.
290     //        See fast/dom/Geolocation/script-tests/argument-types.js for a similar
291     //        example.
292     value = WebCore::isUndefinedOrNull(v8Value) ? String() : v8ValueToWebCoreString(v8Value);
293     return true;
294 }
295
296 #if ENABLE(VIDEO_TRACK)
297 bool Dictionary::get(const String& key, RefPtr<TrackBase>& value) const
298 {
299     v8::Local<v8::Value> v8Value;
300     if (!getKey(key, v8Value))
301         return false;
302
303     TrackBase* source = 0;
304     if (v8Value->IsObject()) {
305         v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
306
307         // FIXME: this will need to be changed so it can also return an AudioTrack or a VideoTrack once
308         // we add them.
309         v8::Handle<v8::Object> track = V8DOMWrapper::lookupDOMWrapper(V8TextTrack::GetTemplate(), wrapper);
310         if (!track.IsEmpty())
311             source = V8TextTrack::toNative(track);
312     }
313     value = source;
314     return true;
315 }
316 #endif
317
318 #if ENABLE(SCRIPTED_SPEECH)
319 bool Dictionary::get(const String& key, RefPtr<SpeechRecognitionError>& value) const
320 {
321     v8::Local<v8::Value> v8Value;
322     if (!getKey(key, v8Value))
323         return false;
324
325     SpeechRecognitionError* source = 0;
326     if (v8Value->IsObject()) {
327         v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
328         v8::Handle<v8::Object> speechRecognitionError = V8DOMWrapper::lookupDOMWrapper(V8SpeechRecognitionError::GetTemplate(), wrapper);
329         if (!speechRecognitionError.IsEmpty())
330             source = V8SpeechRecognitionError::toNative(speechRecognitionError);
331     }
332     value = source;
333     return true;
334 }
335
336 bool Dictionary::get(const String& key, RefPtr<SpeechRecognitionResult>& value) const
337 {
338     v8::Local<v8::Value> v8Value;
339     if (!getKey(key, v8Value))
340         return false;
341
342     SpeechRecognitionResult* source = 0;
343     if (v8Value->IsObject()) {
344         v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
345         v8::Handle<v8::Object> speechRecognitionResult = V8DOMWrapper::lookupDOMWrapper(V8SpeechRecognitionResult::GetTemplate(), wrapper);
346         if (!speechRecognitionResult.IsEmpty())
347             source = V8SpeechRecognitionResult::toNative(speechRecognitionResult);
348     }
349     value = source;
350     return true;
351 }
352
353 bool Dictionary::get(const String& key, RefPtr<SpeechRecognitionResultList>& value) const
354 {
355     v8::Local<v8::Value> v8Value;
356     if (!getKey(key, v8Value))
357         return false;
358
359     SpeechRecognitionResultList* source = 0;
360     if (v8Value->IsObject()) {
361         v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
362         v8::Handle<v8::Object> speechRecognitionResultList = V8DOMWrapper::lookupDOMWrapper(V8SpeechRecognitionResultList::GetTemplate(), wrapper);
363         if (!speechRecognitionResultList.IsEmpty())
364             source = V8SpeechRecognitionResultList::toNative(speechRecognitionResultList);
365     }
366     value = source;
367     return true;
368 }
369
370 #endif
371
372 } // namespace WebCore