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