Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / 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 "bindings/v8/Dictionary.h"
28
29 #include "V8DOMError.h"
30 #include "V8EventTarget.h"
31 #include "V8IDBKeyRange.h"
32 #include "V8MIDIPort.h"
33 #include "V8MediaKeyError.h"
34 #include "V8MessagePort.h"
35 #include "V8SpeechRecognitionError.h"
36 #include "V8SpeechRecognitionResult.h"
37 #include "V8SpeechRecognitionResultList.h"
38 #include "V8Storage.h"
39 #include "V8VoidCallback.h"
40 #include "V8Window.h"
41 #include "bindings/v8/ArrayValue.h"
42 #include "bindings/v8/ExceptionMessages.h"
43 #include "bindings/v8/ExceptionState.h"
44 #include "bindings/v8/V8Binding.h"
45 #include "bindings/v8/V8Utilities.h"
46 #include "bindings/v8/custom/V8ArrayBufferViewCustom.h"
47 #include "bindings/v8/custom/V8Uint8ArrayCustom.h"
48 #include "modules/indexeddb/IDBKeyRange.h"
49 #include "modules/speech/SpeechRecognitionError.h"
50 #include "modules/speech/SpeechRecognitionResult.h"
51 #include "modules/speech/SpeechRecognitionResultList.h"
52 #include "wtf/MathExtras.h"
53
54 #include "V8TextTrack.h"
55 #include "core/html/track/TrackBase.h"
56
57 #include "V8MediaStream.h"
58 #include "modules/mediastream/MediaStream.h"
59
60 namespace WebCore {
61
62 Dictionary::Dictionary()
63     : m_isolate(0)
64 {
65 }
66
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
74 Dictionary::~Dictionary()
75 {
76 }
77
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
85 bool Dictionary::isObject() const
86 {
87     return !isUndefinedOrNull() && m_options->IsObject();
88 }
89
90 bool Dictionary::isUndefinedOrNull() const
91 {
92     if (m_options.IsEmpty())
93         return true;
94     return WebCore::isUndefinedOrNull(m_options);
95 }
96
97 bool Dictionary::hasProperty(const String& key) const
98 {
99     if (isUndefinedOrNull())
100         return false;
101     v8::Local<v8::Object> options = m_options->ToObject();
102     ASSERT(!options.IsEmpty());
103
104     ASSERT(m_isolate);
105     ASSERT(m_isolate == v8::Isolate::GetCurrent());
106     v8::Handle<v8::String> v8Key = v8String(m_isolate, key);
107     if (!options->Has(v8Key))
108         return false;
109
110     return true;
111 }
112
113 bool Dictionary::getKey(const String& key, v8::Local<v8::Value>& value) const
114 {
115     if (isUndefinedOrNull())
116         return false;
117     v8::Local<v8::Object> options = m_options->ToObject();
118     ASSERT(!options.IsEmpty());
119
120     ASSERT(m_isolate);
121     ASSERT(m_isolate == v8::Isolate::GetCurrent());
122     v8::Handle<v8::String> v8Key = v8String(m_isolate, key);
123     if (!options->Has(v8Key))
124         return false;
125     value = options->Get(v8Key);
126     if (value.IsEmpty())
127         return false;
128     return true;
129 }
130
131 bool Dictionary::get(const String& key, v8::Local<v8::Value>& value) const
132 {
133     return getKey(key, value);
134 }
135
136 bool Dictionary::get(const String& key, bool& value) const
137 {
138     v8::Local<v8::Value> v8Value;
139     if (!getKey(key, v8Value))
140         return false;
141
142     v8::Local<v8::Boolean> v8Bool = v8Value->ToBoolean();
143     if (v8Bool.IsEmpty())
144         return false;
145     value = v8Bool->Value();
146     return true;
147 }
148
149 bool Dictionary::convert(ConversionContext& context, const String& key, bool& value) const
150 {
151     ConversionContextScope scope(context);
152     get(key, value);
153     return true;
154 }
155
156 bool Dictionary::get(const String& key, int32_t& value) const
157 {
158     v8::Local<v8::Value> v8Value;
159     if (!getKey(key, v8Value))
160         return false;
161
162     v8::Local<v8::Int32> v8Int32 = v8Value->ToInt32();
163     if (v8Int32.IsEmpty())
164         return false;
165     value = v8Int32->Value();
166     return true;
167 }
168
169 bool Dictionary::get(const String& key, double& value, bool& hasValue) const
170 {
171     v8::Local<v8::Value> v8Value;
172     if (!getKey(key, v8Value)) {
173         hasValue = false;
174         return false;
175     }
176
177     hasValue = true;
178     V8TRYCATCH_RETURN(v8::Local<v8::Number>, v8Number, v8Value->ToNumber(), false);
179     if (v8Number.IsEmpty())
180         return false;
181     value = v8Number->Value();
182     return true;
183 }
184
185 bool Dictionary::get(const String& key, double& value) const
186 {
187     bool unused;
188     return get(key, value, unused);
189 }
190
191 bool Dictionary::convert(ConversionContext& context, const String& key, double& value) const
192 {
193     ConversionContextScope scope(context);
194
195     bool hasValue = false;
196     if (!get(key, value, hasValue) && hasValue) {
197         context.throwTypeError(ExceptionMessages::incorrectPropertyType(key, "is not of type 'double'."));
198         return false;
199     }
200     return true;
201 }
202
203 template<typename StringType>
204 inline bool Dictionary::getStringType(const String& key, StringType& value) const
205 {
206     v8::Local<v8::Value> v8Value;
207     if (!getKey(key, v8Value))
208         return false;
209
210     V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringValue, v8Value, false);
211     value = stringValue;
212     return true;
213 }
214
215 bool Dictionary::get(const String& key, String& value) const
216 {
217     return getStringType(key, value);
218 }
219
220 bool Dictionary::get(const String& key, AtomicString& value) const
221 {
222     return getStringType(key, value);
223 }
224
225 bool Dictionary::convert(ConversionContext& context, const String& key, String& value) const
226 {
227     ConversionContextScope scope(context);
228
229     v8::Local<v8::Value> v8Value;
230     if (!getKey(key, v8Value))
231         return true;
232
233     V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringValue, v8Value, false);
234     value = stringValue;
235     return true;
236 }
237
238 bool Dictionary::get(const String& key, ScriptValue& value) const
239 {
240     v8::Local<v8::Value> v8Value;
241     if (!getKey(key, v8Value))
242         return false;
243
244     value = ScriptValue(v8Value, m_isolate);
245     return true;
246 }
247
248 bool Dictionary::convert(ConversionContext& context, const String& key, ScriptValue& value) const
249 {
250     ConversionContextScope scope(context);
251
252     get(key, value);
253     return true;
254 }
255
256 bool Dictionary::get(const String& key, unsigned short& value) const
257 {
258     v8::Local<v8::Value> v8Value;
259     if (!getKey(key, v8Value))
260         return false;
261
262     v8::Local<v8::Int32> v8Int32 = v8Value->ToInt32();
263     if (v8Int32.IsEmpty())
264         return false;
265     value = static_cast<unsigned short>(v8Int32->Value());
266     return true;
267 }
268
269 bool Dictionary::get(const String& key, short& value) const
270 {
271     v8::Local<v8::Value> v8Value;
272     if (!getKey(key, v8Value))
273         return false;
274
275     v8::Local<v8::Int32> v8Int32 = v8Value->ToInt32();
276     if (v8Int32.IsEmpty())
277         return false;
278     value = static_cast<short>(v8Int32->Value());
279     return true;
280 }
281
282 bool Dictionary::get(const String& key, unsigned& value) const
283 {
284     v8::Local<v8::Value> v8Value;
285     if (!getKey(key, v8Value))
286         return false;
287
288     v8::Local<v8::Int32> v8Int32 = v8Value->ToInt32();
289     if (v8Int32.IsEmpty())
290         return false;
291     value = static_cast<unsigned>(v8Int32->Value());
292     return true;
293 }
294
295 bool Dictionary::get(const String& key, unsigned long& value) const
296 {
297     v8::Local<v8::Value> v8Value;
298     if (!getKey(key, v8Value))
299         return false;
300
301     v8::Local<v8::Integer> v8Integer = v8Value->ToInteger();
302     if (v8Integer.IsEmpty())
303         return false;
304     value = static_cast<unsigned long>(v8Integer->Value());
305     return true;
306 }
307
308 bool Dictionary::get(const String& key, unsigned long long& value) const
309 {
310     v8::Local<v8::Value> v8Value;
311     if (!getKey(key, v8Value))
312         return false;
313
314     V8TRYCATCH_RETURN(v8::Local<v8::Number>, v8Number, v8Value->ToNumber(), false);
315     if (v8Number.IsEmpty())
316         return false;
317     double d = v8Number->Value();
318     doubleToInteger(d, value);
319     return true;
320 }
321
322 bool Dictionary::get(const String& key, RefPtr<DOMWindow>& value) const
323 {
324     v8::Local<v8::Value> v8Value;
325     if (!getKey(key, v8Value))
326         return false;
327
328     // We need to handle a DOMWindow specially, because a DOMWindow wrapper
329     // exists on a prototype chain of v8Value.
330     value = toDOMWindow(v8Value, m_isolate);
331     return true;
332 }
333
334 bool Dictionary::get(const String& key, RefPtrWillBeRawPtr<Storage>& value) const
335 {
336     v8::Local<v8::Value> v8Value;
337     if (!getKey(key, v8Value))
338         return false;
339
340     value = 0;
341     if (V8Storage::hasInstance(v8Value, m_isolate))
342         value = V8Storage::toNative(v8::Handle<v8::Object>::Cast(v8Value));
343     return true;
344 }
345
346 bool Dictionary::get(const String& key, MessagePortArray& value) const
347 {
348     v8::Local<v8::Value> v8Value;
349     if (!getKey(key, v8Value))
350         return false;
351
352     ASSERT(m_isolate);
353     ASSERT(m_isolate == v8::Isolate::GetCurrent());
354     if (WebCore::isUndefinedOrNull(v8Value))
355         return true;
356     bool success = false;
357     value = toRefPtrNativeArray<MessagePort, V8MessagePort>(v8Value, key, m_isolate, &success);
358     return success;
359 }
360
361 bool Dictionary::convert(ConversionContext& context, const String& key, MessagePortArray& value) const
362 {
363     ConversionContextScope scope(context);
364
365     v8::Local<v8::Value> v8Value;
366     if (!getKey(key, v8Value))
367         return true;
368
369     return get(key, value);
370 }
371
372 bool Dictionary::get(const String& key, HashSet<AtomicString>& value) const
373 {
374     v8::Local<v8::Value> v8Value;
375     if (!getKey(key, v8Value))
376         return false;
377
378     // FIXME: Support array-like objects
379     if (!v8Value->IsArray())
380         return false;
381
382     ASSERT(m_isolate);
383     ASSERT(m_isolate == v8::Isolate::GetCurrent());
384     v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(v8Value);
385     for (size_t i = 0; i < v8Array->Length(); ++i) {
386         v8::Local<v8::Value> indexedValue = v8Array->Get(v8::Integer::New(m_isolate, i));
387         V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringValue, indexedValue, false);
388         value.add(stringValue);
389     }
390
391     return true;
392 }
393
394 bool Dictionary::convert(ConversionContext& context, const String& key, HashSet<AtomicString>& value) const
395 {
396     ConversionContextScope scope(context);
397
398     v8::Local<v8::Value> v8Value;
399     if (!getKey(key, v8Value))
400         return true;
401
402     if (context.isNullable() && WebCore::isUndefinedOrNull(v8Value))
403         return true;
404
405     if (!v8Value->IsArray()) {
406         context.throwTypeError(ExceptionMessages::notASequenceTypeProperty(key));
407         return false;
408     }
409
410     return get(key, value);
411 }
412
413 bool Dictionary::getWithUndefinedOrNullCheck(const String& key, String& value) const
414 {
415     v8::Local<v8::Value> v8Value;
416     if (!getKey(key, v8Value) || WebCore::isUndefinedOrNull(v8Value))
417         return false;
418
419     V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringValue, v8Value, false);
420     value = stringValue;
421     return true;
422 }
423
424 bool Dictionary::get(const String& key, RefPtr<Uint8Array>& value) const
425 {
426     v8::Local<v8::Value> v8Value;
427     if (!getKey(key, v8Value))
428         return false;
429
430     value = 0;
431     if (V8Uint8Array::hasInstance(v8Value, m_isolate))
432         value = V8Uint8Array::toNative(v8::Handle<v8::Object>::Cast(v8Value));
433     return true;
434 }
435
436 bool Dictionary::get(const String& key, RefPtr<ArrayBufferView>& value) const
437 {
438     v8::Local<v8::Value> v8Value;
439     if (!getKey(key, v8Value))
440         return false;
441
442     value = 0;
443     if (V8ArrayBufferView::hasInstance(v8Value, m_isolate))
444         value = V8ArrayBufferView::toNative(v8::Handle<v8::Object>::Cast(v8Value));
445     return true;
446 }
447
448 bool Dictionary::get(const String& key, RefPtr<MIDIPort>& value) const
449 {
450     v8::Local<v8::Value> v8Value;
451     if (!getKey(key, v8Value))
452         return false;
453
454     value = 0;
455     if (V8MIDIPort::hasInstance(v8Value, m_isolate))
456         value = V8MIDIPort::toNative(v8::Handle<v8::Object>::Cast(v8Value));
457     return true;
458 }
459
460 bool Dictionary::get(const String& key, RefPtr<MediaKeyError>& value) const
461 {
462     v8::Local<v8::Value> v8Value;
463     if (!getKey(key, v8Value))
464         return false;
465
466     value = 0;
467     if (V8MediaKeyError::hasInstance(v8Value, m_isolate))
468         value = V8MediaKeyError::toNative(v8::Handle<v8::Object>::Cast(v8Value));
469     return true;
470 }
471
472 bool Dictionary::get(const String& key, RefPtr<TrackBase>& value) const
473 {
474     v8::Local<v8::Value> v8Value;
475     if (!getKey(key, v8Value))
476         return false;
477
478     TrackBase* source = 0;
479     if (v8Value->IsObject()) {
480         v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
481
482         // FIXME: this will need to be changed so it can also return an AudioTrack or a VideoTrack once
483         // we add them.
484         v8::Handle<v8::Object> track = wrapper->FindInstanceInPrototypeChain(V8TextTrack::domTemplate(m_isolate, worldType(m_isolate)));
485         if (!track.IsEmpty())
486             source = V8TextTrack::toNative(track);
487     }
488     value = source;
489     return true;
490 }
491
492 bool Dictionary::get(const String& key, RefPtr<SpeechRecognitionError>& value) const
493 {
494     v8::Local<v8::Value> v8Value;
495     if (!getKey(key, v8Value))
496         return false;
497
498     value = 0;
499     if (V8SpeechRecognitionError::hasInstance(v8Value, m_isolate))
500         value = V8SpeechRecognitionError::toNative(v8::Handle<v8::Object>::Cast(v8Value));
501     return true;
502 }
503
504 bool Dictionary::get(const String& key, RefPtrWillBeRawPtr<SpeechRecognitionResult>& value) const
505 {
506     v8::Local<v8::Value> v8Value;
507     if (!getKey(key, v8Value))
508         return false;
509
510     value = 0;
511     if (V8SpeechRecognitionResult::hasInstance(v8Value, m_isolate))
512         value = V8SpeechRecognitionResult::toNative(v8::Handle<v8::Object>::Cast(v8Value));
513     return true;
514 }
515
516 bool Dictionary::get(const String& key, RefPtrWillBeRawPtr<SpeechRecognitionResultList>& value) const
517 {
518     v8::Local<v8::Value> v8Value;
519     if (!getKey(key, v8Value))
520         return false;
521
522     value = 0;
523     if (V8SpeechRecognitionResultList::hasInstance(v8Value, m_isolate))
524         value = V8SpeechRecognitionResultList::toNative(v8::Handle<v8::Object>::Cast(v8Value));
525     return true;
526 }
527
528 bool Dictionary::get(const String& key, RefPtr<MediaStream>& value) const
529 {
530     v8::Local<v8::Value> v8Value;
531     if (!getKey(key, v8Value))
532         return false;
533
534     value = 0;
535     if (V8MediaStream::hasInstance(v8Value, m_isolate))
536         value = V8MediaStream::toNative(v8::Handle<v8::Object>::Cast(v8Value));
537     return true;
538 }
539
540 bool Dictionary::get(const String& key, RefPtr<EventTarget>& value) const
541 {
542     v8::Local<v8::Value> v8Value;
543     if (!getKey(key, v8Value))
544         return false;
545
546     value = 0;
547     // We need to handle a DOMWindow specially, because a DOMWindow wrapper
548     // exists on a prototype chain of v8Value.
549     if (v8Value->IsObject()) {
550         v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
551         v8::Handle<v8::Object> window = wrapper->FindInstanceInPrototypeChain(V8Window::domTemplate(m_isolate, worldTypeInMainThread(m_isolate)));
552         if (!window.IsEmpty()) {
553             value = toWrapperTypeInfo(window)->toEventTarget(window);
554             return true;
555         }
556     }
557
558     if (V8DOMWrapper::isDOMWrapper(v8Value)) {
559         v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
560         value = toWrapperTypeInfo(wrapper)->toEventTarget(wrapper);
561     }
562     return true;
563 }
564
565 bool Dictionary::get(const String& key, Dictionary& value) const
566 {
567     v8::Local<v8::Value> v8Value;
568     if (!getKey(key, v8Value))
569         return false;
570
571     if (v8Value->IsObject()) {
572         ASSERT(m_isolate);
573         ASSERT(m_isolate == v8::Isolate::GetCurrent());
574         value = Dictionary(v8Value, m_isolate);
575     }
576
577     return true;
578 }
579
580 bool Dictionary::convert(ConversionContext& context, const String& key, Dictionary& value) const
581 {
582     ConversionContextScope scope(context);
583
584     v8::Local<v8::Value> v8Value;
585     if (!getKey(key, v8Value))
586         return true;
587
588     if (v8Value->IsObject())
589         return get(key, value);
590
591     if (context.isNullable() && WebCore::isUndefinedOrNull(v8Value))
592         return true;
593
594     context.throwTypeError(ExceptionMessages::incorrectPropertyType(key, "does not have a Dictionary type."));
595     return false;
596 }
597
598 bool Dictionary::get(const String& key, Vector<String>& value) const
599 {
600     v8::Local<v8::Value> v8Value;
601     if (!getKey(key, v8Value))
602         return false;
603
604     if (!v8Value->IsArray())
605         return false;
606
607     v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(v8Value);
608     for (size_t i = 0; i < v8Array->Length(); ++i) {
609         v8::Local<v8::Value> indexedValue = v8Array->Get(v8::Uint32::New(m_isolate, i));
610         V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringValue, indexedValue, false);
611         value.append(stringValue);
612     }
613
614     return true;
615 }
616
617 bool Dictionary::convert(ConversionContext& context, const String& key, Vector<String>& value) const
618 {
619     ConversionContextScope scope(context);
620
621     v8::Local<v8::Value> v8Value;
622     if (!getKey(key, v8Value))
623         return true;
624
625     if (context.isNullable() && WebCore::isUndefinedOrNull(v8Value))
626         return true;
627
628     if (!v8Value->IsArray()) {
629         context.throwTypeError(ExceptionMessages::notASequenceTypeProperty(key));
630         return false;
631     }
632
633     return get(key, value);
634 }
635
636 bool Dictionary::get(const String& key, ArrayValue& value) const
637 {
638     v8::Local<v8::Value> v8Value;
639     if (!getKey(key, v8Value))
640         return false;
641
642     if (!v8Value->IsArray())
643         return false;
644
645     ASSERT(m_isolate);
646     ASSERT(m_isolate == v8::Isolate::GetCurrent());
647     value = ArrayValue(v8::Local<v8::Array>::Cast(v8Value), m_isolate);
648     return true;
649 }
650
651 bool Dictionary::convert(ConversionContext& context, const String& key, ArrayValue& value) const
652 {
653     ConversionContextScope scope(context);
654
655     v8::Local<v8::Value> v8Value;
656     if (!getKey(key, v8Value))
657         return true;
658
659     if (context.isNullable() && WebCore::isUndefinedOrNull(v8Value))
660         return true;
661
662     if (!v8Value->IsArray()) {
663         context.throwTypeError(ExceptionMessages::notASequenceTypeProperty(key));
664         return false;
665     }
666
667     return get(key, value);
668 }
669
670 bool Dictionary::get(const String& key, RefPtr<DOMError>& value) const
671 {
672     v8::Local<v8::Value> v8Value;
673     if (!getKey(key, v8Value))
674         return false;
675
676     DOMError* error = 0;
677     if (v8Value->IsObject()) {
678         v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
679         v8::Handle<v8::Object> domError = wrapper->FindInstanceInPrototypeChain(V8DOMError::domTemplate(m_isolate, worldType(m_isolate)));
680         if (!domError.IsEmpty())
681             error = V8DOMError::toNative(domError);
682     }
683     value = error;
684     return true;
685 }
686
687 bool Dictionary::get(const String& key, OwnPtr<VoidCallback>& value) const
688 {
689     v8::Local<v8::Value> v8Value;
690     if (!getKey(key, v8Value))
691         return false;
692
693     if (!v8Value->IsFunction())
694         return false;
695
696     value = V8VoidCallback::create(v8::Handle<v8::Function>::Cast(v8Value), currentExecutionContext(m_isolate));
697     return true;
698 }
699
700 bool Dictionary::getOwnPropertiesAsStringHashMap(HashMap<String, String>& hashMap) const
701 {
702     if (!isObject())
703         return false;
704
705     v8::Handle<v8::Object> options = m_options->ToObject();
706     if (options.IsEmpty())
707         return false;
708
709     v8::Local<v8::Array> properties = options->GetOwnPropertyNames();
710     if (properties.IsEmpty())
711         return true;
712     for (uint32_t i = 0; i < properties->Length(); ++i) {
713         v8::Local<v8::String> key = properties->Get(i)->ToString();
714         if (!options->Has(key))
715             continue;
716
717         v8::Local<v8::Value> value = options->Get(key);
718         V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringKey, key, false);
719         V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringValue, value, false);
720         if (!static_cast<const String&>(stringKey).isEmpty())
721             hashMap.set(stringKey, stringValue);
722     }
723
724     return true;
725 }
726
727 bool Dictionary::getOwnPropertyNames(Vector<String>& names) const
728 {
729     if (!isObject())
730         return false;
731
732     v8::Handle<v8::Object> options = m_options->ToObject();
733     if (options.IsEmpty())
734         return false;
735
736     v8::Local<v8::Array> properties = options->GetOwnPropertyNames();
737     if (properties.IsEmpty())
738         return true;
739     for (uint32_t i = 0; i < properties->Length(); ++i) {
740         v8::Local<v8::String> key = properties->Get(i)->ToString();
741         if (!options->Has(key))
742             continue;
743         V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringKey, key, false);
744         names.append(stringKey);
745     }
746
747     return true;
748 }
749
750 void Dictionary::ConversionContext::resetPerPropertyContext()
751 {
752     if (m_dirty) {
753         m_dirty = false;
754         m_isNullable = false;
755         m_propertyTypeName = "";
756     }
757 }
758
759 Dictionary::ConversionContext& Dictionary::ConversionContext::setConversionType(const String& typeName, bool isNullable)
760 {
761     ASSERT(!m_dirty);
762     m_dirty = true;
763     m_isNullable = isNullable;
764     m_propertyTypeName = typeName;
765
766     return *this;
767 }
768
769 void Dictionary::ConversionContext::throwTypeError(const String& detail)
770 {
771     if (forConstructor()) {
772         exceptionState().throwTypeError(detail);
773     } else {
774         ASSERT(!methodName().isEmpty());
775         exceptionState().throwTypeError(ExceptionMessages::failedToExecute(interfaceName(), methodName(), detail));
776     }
777 }
778
779 } // namespace WebCore