• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "bindings/core/v8/Dictionary.h"
28 
29 #include "bindings/core/v8/ArrayValue.h"
30 #include "bindings/core/v8/ExceptionMessages.h"
31 #include "bindings/core/v8/ExceptionState.h"
32 #include "bindings/core/v8/V8Binding.h"
33 #include "bindings/core/v8/V8DOMError.h"
34 #include "bindings/core/v8/V8Element.h"
35 #include "bindings/core/v8/V8EventTarget.h"
36 #include "bindings/core/v8/V8MediaKeyError.h"
37 #include "bindings/core/v8/V8MessagePort.h"
38 #include "bindings/core/v8/V8Path2D.h"
39 #include "bindings/core/v8/V8Storage.h"
40 #include "bindings/core/v8/V8TextTrack.h"
41 #include "bindings/core/v8/V8VoidCallback.h"
42 #include "bindings/core/v8/V8Window.h"
43 #include "bindings/core/v8/custom/V8ArrayBufferViewCustom.h"
44 #include "bindings/core/v8/custom/V8Uint8ArrayCustom.h"
45 #include "bindings/modules/v8/V8Gamepad.h"
46 #include "bindings/modules/v8/V8Headers.h"
47 #include "bindings/modules/v8/V8IDBKeyRange.h"
48 #include "bindings/modules/v8/V8MIDIPort.h"
49 #include "bindings/modules/v8/V8MediaStream.h"
50 #include "bindings/modules/v8/V8SpeechRecognitionResult.h"
51 #include "bindings/modules/v8/V8SpeechRecognitionResultList.h"
52 #include "core/html/track/TrackBase.h"
53 #include "modules/gamepad/Gamepad.h"
54 #include "modules/indexeddb/IDBKeyRange.h"
55 #include "modules/mediastream/MediaStream.h"
56 #include "modules/speech/SpeechRecognitionResult.h"
57 #include "modules/speech/SpeechRecognitionResultList.h"
58 #include "wtf/MathExtras.h"
59 
60 namespace blink {
61 
Dictionary()62 Dictionary::Dictionary()
63     : m_isolate(0)
64 {
65 }
66 
Dictionary(const v8::Handle<v8::Value> & options,v8::Isolate * isolate)67 Dictionary::Dictionary(const v8::Handle<v8::Value>& options, v8::Isolate* isolate)
68     : m_options(options)
69     , m_isolate(isolate)
70 {
71     ASSERT(m_isolate);
72 }
73 
~Dictionary()74 Dictionary::~Dictionary()
75 {
76 }
77 
operator =(const Dictionary & optionsObject)78 Dictionary& Dictionary::operator=(const Dictionary& optionsObject)
79 {
80     m_options = optionsObject.m_options;
81     m_isolate = optionsObject.m_isolate;
82     return *this;
83 }
84 
createEmpty(v8::Isolate * isolate)85 Dictionary Dictionary::createEmpty(v8::Isolate* isolate)
86 {
87     return Dictionary(v8::Object::New(isolate), isolate);
88 }
89 
isObject() const90 bool Dictionary::isObject() const
91 {
92     return !isUndefinedOrNull() && m_options->IsObject();
93 }
94 
isUndefinedOrNull() const95 bool Dictionary::isUndefinedOrNull() const
96 {
97     if (m_options.IsEmpty())
98         return true;
99     return blink::isUndefinedOrNull(m_options);
100 }
101 
hasProperty(const String & key) const102 bool Dictionary::hasProperty(const String& key) const
103 {
104     if (isUndefinedOrNull())
105         return false;
106     v8::Local<v8::Object> options = m_options->ToObject();
107     ASSERT(!options.IsEmpty());
108 
109     ASSERT(m_isolate);
110     ASSERT(m_isolate == v8::Isolate::GetCurrent());
111     v8::Handle<v8::String> v8Key = v8String(m_isolate, key);
112     if (!options->Has(v8Key))
113         return false;
114 
115     return true;
116 }
117 
getKey(const String & key,v8::Local<v8::Value> & value) const118 bool Dictionary::getKey(const String& key, v8::Local<v8::Value>& value) const
119 {
120     if (isUndefinedOrNull())
121         return false;
122     v8::Local<v8::Object> options = m_options->ToObject();
123     ASSERT(!options.IsEmpty());
124 
125     ASSERT(m_isolate);
126     ASSERT(m_isolate == v8::Isolate::GetCurrent());
127     v8::Handle<v8::String> v8Key = v8String(m_isolate, key);
128     if (!options->Has(v8Key))
129         return false;
130     value = options->Get(v8Key);
131     if (value.IsEmpty())
132         return false;
133     return true;
134 }
135 
get(const String & key,v8::Local<v8::Value> & value) const136 bool Dictionary::get(const String& key, v8::Local<v8::Value>& value) const
137 {
138     return getKey(key, value);
139 }
140 
getWithUndefinedOrNullCheck(const String & key,String & value) const141 bool Dictionary::getWithUndefinedOrNullCheck(const String& key, String& value) const
142 {
143     v8::Local<v8::Value> v8Value;
144     if (!getKey(key, v8Value) || blink::isUndefinedOrNull(v8Value))
145         return false;
146 
147     TOSTRING_DEFAULT(V8StringResource<>, stringValue, v8Value, false);
148     value = stringValue;
149     return true;
150 }
151 
getWithUndefinedOrNullCheck(const String & key,RefPtrWillBeMember<Element> & value) const152 bool Dictionary::getWithUndefinedOrNullCheck(const String& key, RefPtrWillBeMember<Element>& value) const
153 {
154     v8::Local<v8::Value> v8Value;
155     if (!getKey(key, v8Value) || blink::isUndefinedOrNull(v8Value))
156         return false;
157 
158     value = V8Element::toImplWithTypeCheck(m_isolate, v8Value);
159     return true;
160 }
161 
getWithUndefinedOrNullCheck(const String & key,RefPtrWillBeMember<Path2D> & value) const162 bool Dictionary::getWithUndefinedOrNullCheck(const String& key, RefPtrWillBeMember<Path2D>& value) const
163 {
164     v8::Local<v8::Value> v8Value;
165     if (!getKey(key, v8Value) || blink::isUndefinedOrNull(v8Value))
166         return false;
167 
168     value = V8Path2D::toImplWithTypeCheck(m_isolate, v8Value);
169     return true;
170 }
171 
get(const String & key,Dictionary & value) const172 bool Dictionary::get(const String& key, Dictionary& value) const
173 {
174     v8::Local<v8::Value> v8Value;
175     if (!getKey(key, v8Value))
176         return false;
177 
178     if (v8Value->IsObject()) {
179         ASSERT(m_isolate);
180         ASSERT(m_isolate == v8::Isolate::GetCurrent());
181         value = Dictionary(v8Value, m_isolate);
182     }
183 
184     return true;
185 }
186 
set(const String & key,const v8::Handle<v8::Value> & value)187 bool Dictionary::set(const String& key, const v8::Handle<v8::Value>& value)
188 {
189     if (isUndefinedOrNull())
190         return false;
191     v8::Local<v8::Object> options = m_options->ToObject();
192     ASSERT(!options.IsEmpty());
193 
194     return options->Set(v8String(m_isolate, key), value);
195 }
196 
set(const String & key,const String & value)197 bool Dictionary::set(const String& key, const String& value)
198 {
199     return set(key, v8String(m_isolate, value));
200 }
201 
set(const String & key,unsigned value)202 bool Dictionary::set(const String& key, unsigned value)
203 {
204     return set(key, v8::Integer::NewFromUnsigned(m_isolate, value));
205 }
206 
set(const String & key,const Dictionary & value)207 bool Dictionary::set(const String& key, const Dictionary& value)
208 {
209     return set(key, value.v8Value());
210 }
211 
convert(ConversionContext & context,const String & key,Dictionary & value) const212 bool Dictionary::convert(ConversionContext& context, const String& key, Dictionary& value) const
213 {
214     ConversionContextScope scope(context);
215 
216     v8::Local<v8::Value> v8Value;
217     if (!getKey(key, v8Value))
218         return true;
219 
220     if (v8Value->IsObject())
221         return get(key, value);
222 
223     if (context.isNullable() && blink::isUndefinedOrNull(v8Value))
224         return true;
225 
226     context.throwTypeError(ExceptionMessages::incorrectPropertyType(key, "does not have a Dictionary type."));
227     return false;
228 }
229 
getOwnPropertiesAsStringHashMap(HashMap<String,String> & hashMap) const230 bool Dictionary::getOwnPropertiesAsStringHashMap(HashMap<String, String>& hashMap) const
231 {
232     if (!isObject())
233         return false;
234 
235     v8::Handle<v8::Object> options = m_options->ToObject();
236     if (options.IsEmpty())
237         return false;
238 
239     v8::Local<v8::Array> properties = options->GetOwnPropertyNames();
240     if (properties.IsEmpty())
241         return true;
242     for (uint32_t i = 0; i < properties->Length(); ++i) {
243         v8::Local<v8::String> key = properties->Get(i)->ToString();
244         if (!options->Has(key))
245             continue;
246 
247         v8::Local<v8::Value> value = options->Get(key);
248         TOSTRING_DEFAULT(V8StringResource<>, stringKey, key, false);
249         TOSTRING_DEFAULT(V8StringResource<>, stringValue, value, false);
250         if (!static_cast<const String&>(stringKey).isEmpty())
251             hashMap.set(stringKey, stringValue);
252     }
253 
254     return true;
255 }
256 
getOwnPropertyNames(Vector<String> & names) const257 bool Dictionary::getOwnPropertyNames(Vector<String>& names) const
258 {
259     if (!isObject())
260         return false;
261 
262     v8::Handle<v8::Object> options = m_options->ToObject();
263     if (options.IsEmpty())
264         return false;
265 
266     v8::Local<v8::Array> properties = options->GetOwnPropertyNames();
267     if (properties.IsEmpty())
268         return true;
269     for (uint32_t i = 0; i < properties->Length(); ++i) {
270         v8::Local<v8::String> key = properties->Get(i)->ToString();
271         if (!options->Has(key))
272             continue;
273         TOSTRING_DEFAULT(V8StringResource<>, stringKey, key, false);
274         names.append(stringKey);
275     }
276 
277     return true;
278 }
279 
resetPerPropertyContext()280 void Dictionary::ConversionContext::resetPerPropertyContext()
281 {
282     if (m_dirty) {
283         m_dirty = false;
284         m_isNullable = false;
285         m_propertyTypeName = "";
286     }
287 }
288 
setConversionType(const String & typeName,bool isNullable)289 Dictionary::ConversionContext& Dictionary::ConversionContext::setConversionType(const String& typeName, bool isNullable)
290 {
291     ASSERT(!m_dirty);
292     m_dirty = true;
293     m_isNullable = isNullable;
294     m_propertyTypeName = typeName;
295 
296     return *this;
297 }
298 
throwTypeError(const String & detail)299 void Dictionary::ConversionContext::throwTypeError(const String& detail)
300 {
301     exceptionState().throwTypeError(detail);
302 }
303 
304 } // namespace blink
305