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