2 * Copyright (C) 2010 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "bindings/core/v8/Dictionary.h"
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"
62 Dictionary::Dictionary()
67 Dictionary::Dictionary(const v8::Handle<v8::Value>& options, v8::Isolate* isolate)
74 Dictionary::~Dictionary()
78 Dictionary& Dictionary::operator=(const Dictionary& optionsObject)
80 m_options = optionsObject.m_options;
81 m_isolate = optionsObject.m_isolate;
85 Dictionary Dictionary::createEmpty(v8::Isolate* isolate)
87 return Dictionary(v8::Object::New(isolate), isolate);
90 bool Dictionary::isObject() const
92 return !isUndefinedOrNull() && m_options->IsObject();
95 bool Dictionary::isUndefinedOrNull() const
97 if (m_options.IsEmpty())
99 return blink::isUndefinedOrNull(m_options);
102 bool Dictionary::hasProperty(const String& key) const
104 if (isUndefinedOrNull())
106 v8::Local<v8::Object> options = m_options->ToObject();
107 ASSERT(!options.IsEmpty());
110 ASSERT(m_isolate == v8::Isolate::GetCurrent());
111 v8::Handle<v8::String> v8Key = v8String(m_isolate, key);
112 if (!options->Has(v8Key))
118 bool Dictionary::getKey(const String& key, v8::Local<v8::Value>& value) const
120 if (isUndefinedOrNull())
122 v8::Local<v8::Object> options = m_options->ToObject();
123 ASSERT(!options.IsEmpty());
126 ASSERT(m_isolate == v8::Isolate::GetCurrent());
127 v8::Handle<v8::String> v8Key = v8String(m_isolate, key);
128 if (!options->Has(v8Key))
130 value = options->Get(v8Key);
136 bool Dictionary::get(const String& key, v8::Local<v8::Value>& value) const
138 return getKey(key, value);
141 bool Dictionary::getWithUndefinedOrNullCheck(const String& key, String& value) const
143 v8::Local<v8::Value> v8Value;
144 if (!getKey(key, v8Value) || blink::isUndefinedOrNull(v8Value))
147 TOSTRING_DEFAULT(V8StringResource<>, stringValue, v8Value, false);
152 bool Dictionary::getWithUndefinedOrNullCheck(const String& key, RefPtrWillBeMember<Element>& value) const
154 v8::Local<v8::Value> v8Value;
155 if (!getKey(key, v8Value) || blink::isUndefinedOrNull(v8Value))
158 value = V8Element::toImplWithTypeCheck(m_isolate, v8Value);
162 bool Dictionary::getWithUndefinedOrNullCheck(const String& key, RefPtrWillBeMember<Path2D>& value) const
164 v8::Local<v8::Value> v8Value;
165 if (!getKey(key, v8Value) || blink::isUndefinedOrNull(v8Value))
168 value = V8Path2D::toImplWithTypeCheck(m_isolate, v8Value);
172 bool Dictionary::get(const String& key, Dictionary& value) const
174 v8::Local<v8::Value> v8Value;
175 if (!getKey(key, v8Value))
178 if (v8Value->IsObject()) {
180 ASSERT(m_isolate == v8::Isolate::GetCurrent());
181 value = Dictionary(v8Value, m_isolate);
187 bool Dictionary::set(const String& key, const v8::Handle<v8::Value>& value)
189 if (isUndefinedOrNull())
191 v8::Local<v8::Object> options = m_options->ToObject();
192 ASSERT(!options.IsEmpty());
194 return options->Set(v8String(m_isolate, key), value);
197 bool Dictionary::set(const String& key, const String& value)
199 return set(key, v8String(m_isolate, value));
202 bool Dictionary::set(const String& key, unsigned value)
204 return set(key, v8::Integer::NewFromUnsigned(m_isolate, value));
207 bool Dictionary::set(const String& key, const Dictionary& value)
209 return set(key, value.v8Value());
212 bool Dictionary::convert(ConversionContext& context, const String& key, Dictionary& value) const
214 ConversionContextScope scope(context);
216 v8::Local<v8::Value> v8Value;
217 if (!getKey(key, v8Value))
220 if (v8Value->IsObject())
221 return get(key, value);
223 if (context.isNullable() && blink::isUndefinedOrNull(v8Value))
226 context.throwTypeError(ExceptionMessages::incorrectPropertyType(key, "does not have a Dictionary type."));
230 bool Dictionary::getOwnPropertiesAsStringHashMap(HashMap<String, String>& hashMap) const
235 v8::Handle<v8::Object> options = m_options->ToObject();
236 if (options.IsEmpty())
239 v8::Local<v8::Array> properties = options->GetOwnPropertyNames();
240 if (properties.IsEmpty())
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))
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);
257 bool Dictionary::getOwnPropertyNames(Vector<String>& names) const
262 v8::Handle<v8::Object> options = m_options->ToObject();
263 if (options.IsEmpty())
266 v8::Local<v8::Array> properties = options->GetOwnPropertyNames();
267 if (properties.IsEmpty())
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))
273 TOSTRING_DEFAULT(V8StringResource<>, stringKey, key, false);
274 names.append(stringKey);
280 void Dictionary::ConversionContext::resetPerPropertyContext()
284 m_isNullable = false;
285 m_propertyTypeName = "";
289 Dictionary::ConversionContext& Dictionary::ConversionContext::setConversionType(const String& typeName, bool isNullable)
293 m_isNullable = isNullable;
294 m_propertyTypeName = typeName;
299 void Dictionary::ConversionContext::throwTypeError(const String& detail)
301 exceptionState().throwTypeError(detail);