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 28#include "bindings/core/v8/ArrayValue.h" 29#include "bindings/core/v8/DictionaryHelperForBindings.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 "core/html/track/TrackBase.h" 46#include "wtf/MathExtras.h" 47 48namespace blink { 49 50template <> 51bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, v8::Local<v8::Value>& value) 52{ 53 return dictionary.get(key, value); 54} 55 56template <> 57bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, Dictionary& value) 58{ 59 return dictionary.get(key, value); 60} 61 62template <> 63bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, bool& value) 64{ 65 v8::Local<v8::Value> v8Value; 66 if (!dictionary.get(key, v8Value)) 67 return false; 68 69 v8::Local<v8::Boolean> v8Bool = v8Value->ToBoolean(); 70 if (v8Bool.IsEmpty()) 71 return false; 72 value = v8Bool->Value(); 73 return true; 74} 75 76template <> 77bool DictionaryHelper::convert(const Dictionary& dictionary, Dictionary::ConversionContext& context, const String& key, bool& value) 78{ 79 Dictionary::ConversionContextScope scope(context); 80 DictionaryHelper::get(dictionary, key, value); 81 return true; 82} 83 84template <> 85bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, int32_t& value) 86{ 87 v8::Local<v8::Value> v8Value; 88 if (!dictionary.get(key, v8Value)) 89 return false; 90 91 v8::Local<v8::Int32> v8Int32 = v8Value->ToInt32(); 92 if (v8Int32.IsEmpty()) 93 return false; 94 value = v8Int32->Value(); 95 return true; 96} 97 98template <> 99bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, double& value, bool& hasValue) 100{ 101 v8::Local<v8::Value> v8Value; 102 if (!dictionary.get(key, v8Value)) { 103 hasValue = false; 104 return false; 105 } 106 107 hasValue = true; 108 TONATIVE_DEFAULT(v8::Local<v8::Number>, v8Number, v8Value->ToNumber(), false); 109 if (v8Number.IsEmpty()) 110 return false; 111 value = v8Number->Value(); 112 return true; 113} 114 115template <> 116bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, double& value) 117{ 118 bool unused; 119 return DictionaryHelper::get(dictionary, key, value, unused); 120} 121 122template <> 123bool DictionaryHelper::convert(const Dictionary& dictionary, Dictionary::ConversionContext& context, const String& key, double& value) 124{ 125 Dictionary::ConversionContextScope scope(context); 126 127 bool hasValue = false; 128 if (!DictionaryHelper::get(dictionary, key, value, hasValue) && hasValue) { 129 context.throwTypeError(ExceptionMessages::incorrectPropertyType(key, "is not of type 'double'.")); 130 return false; 131 } 132 return true; 133} 134 135template<typename StringType> 136bool getStringType(const Dictionary& dictionary, const String& key, StringType& value) 137{ 138 v8::Local<v8::Value> v8Value; 139 if (!dictionary.get(key, v8Value)) 140 return false; 141 142 TOSTRING_DEFAULT(V8StringResource<>, stringValue, v8Value, false); 143 value = stringValue; 144 return true; 145} 146 147template <> 148bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, String& value) 149{ 150 return getStringType(dictionary, key, value); 151} 152 153template <> 154bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, AtomicString& value) 155{ 156 return getStringType(dictionary, key, value); 157} 158 159template <> 160bool DictionaryHelper::convert(const Dictionary& dictionary, Dictionary::ConversionContext& context, const String& key, String& value) 161{ 162 Dictionary::ConversionContextScope scope(context); 163 164 v8::Local<v8::Value> v8Value; 165 if (!dictionary.get(key, v8Value)) 166 return true; 167 168 TOSTRING_DEFAULT(V8StringResource<>, stringValue, v8Value, false); 169 value = stringValue; 170 return true; 171} 172 173template <> 174bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, ScriptValue& value) 175{ 176 v8::Local<v8::Value> v8Value; 177 if (!dictionary.get(key, v8Value)) 178 return false; 179 180 value = ScriptValue(ScriptState::current(dictionary.isolate()), v8Value); 181 return true; 182} 183 184template <> 185bool DictionaryHelper::convert(const Dictionary& dictionary, Dictionary::ConversionContext& context, const String& key, ScriptValue& value) 186{ 187 Dictionary::ConversionContextScope scope(context); 188 189 DictionaryHelper::get(dictionary, key, value); 190 return true; 191} 192 193template<typename NumericType> 194bool getNumericType(const Dictionary& dictionary, const String& key, NumericType& value) 195{ 196 v8::Local<v8::Value> v8Value; 197 if (!dictionary.get(key, v8Value)) 198 return false; 199 200 v8::Local<v8::Int32> v8Int32 = v8Value->ToInt32(); 201 if (v8Int32.IsEmpty()) 202 return false; 203 value = static_cast<NumericType>(v8Int32->Value()); 204 return true; 205} 206 207template <> 208bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, short& value) 209{ 210 return getNumericType<short>(dictionary, key, value); 211} 212 213template <> 214bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, unsigned short& value) 215{ 216 return getNumericType<unsigned short>(dictionary, key, value); 217} 218 219template <> 220bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, unsigned& value) 221{ 222 return getNumericType<unsigned>(dictionary, key, value); 223} 224 225template <> 226bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, unsigned long& value) 227{ 228 v8::Local<v8::Value> v8Value; 229 if (!dictionary.get(key, v8Value)) 230 return false; 231 232 v8::Local<v8::Integer> v8Integer = v8Value->ToInteger(); 233 if (v8Integer.IsEmpty()) 234 return false; 235 value = static_cast<unsigned long>(v8Integer->Value()); 236 return true; 237} 238 239template <> 240bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, unsigned long long& value) 241{ 242 v8::Local<v8::Value> v8Value; 243 if (!dictionary.get(key, v8Value)) 244 return false; 245 246 TONATIVE_DEFAULT(v8::Local<v8::Number>, v8Number, v8Value->ToNumber(), false); 247 if (v8Number.IsEmpty()) 248 return false; 249 double d = v8Number->Value(); 250 doubleToInteger(d, value); 251 return true; 252} 253 254template <> 255bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, RefPtrWillBeMember<LocalDOMWindow>& value) 256{ 257 v8::Local<v8::Value> v8Value; 258 if (!dictionary.get(key, v8Value)) 259 return false; 260 261 // We need to handle a DOMWindow specially, because a DOMWindow wrapper 262 // exists on a prototype chain of v8Value. 263 value = toDOMWindow(v8Value, dictionary.isolate()); 264 return true; 265} 266 267template <> 268bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, HashSet<AtomicString>& value) 269{ 270 v8::Local<v8::Value> v8Value; 271 if (!dictionary.get(key, v8Value)) 272 return false; 273 274 // FIXME: Support array-like objects 275 if (!v8Value->IsArray()) 276 return false; 277 278 ASSERT(dictionary.isolate()); 279 ASSERT(dictionary.isolate() == v8::Isolate::GetCurrent()); 280 v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(v8Value); 281 for (size_t i = 0; i < v8Array->Length(); ++i) { 282 v8::Local<v8::Value> indexedValue = v8Array->Get(v8::Integer::New(dictionary.isolate(), i)); 283 TOSTRING_DEFAULT(V8StringResource<>, stringValue, indexedValue, false); 284 value.add(stringValue); 285 } 286 287 return true; 288} 289 290template <> 291bool DictionaryHelper::convert(const Dictionary& dictionary, Dictionary::ConversionContext& context, const String& key, HashSet<AtomicString>& value) 292{ 293 Dictionary::ConversionContextScope scope(context); 294 295 v8::Local<v8::Value> v8Value; 296 if (!dictionary.get(key, v8Value)) 297 return true; 298 299 if (context.isNullable() && blink::isUndefinedOrNull(v8Value)) 300 return true; 301 302 if (!v8Value->IsArray()) { 303 context.throwTypeError(ExceptionMessages::notASequenceTypeProperty(key)); 304 return false; 305 } 306 307 return DictionaryHelper::get(dictionary, key, value); 308} 309 310template <> 311bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, RefPtrWillBeMember<TrackBase>& value) 312{ 313 v8::Local<v8::Value> v8Value; 314 if (!dictionary.get(key, v8Value)) 315 return false; 316 317 TrackBase* source = 0; 318 if (v8Value->IsObject()) { 319 v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value); 320 321 // FIXME: this will need to be changed so it can also return an AudioTrack or a VideoTrack once 322 // we add them. 323 v8::Handle<v8::Object> track = V8TextTrack::findInstanceInPrototypeChain(wrapper, dictionary.isolate()); 324 if (!track.IsEmpty()) 325 source = V8TextTrack::toImpl(track); 326 } 327 value = source; 328 return true; 329} 330 331template <> 332bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, RefPtrWillBeMember<EventTarget>& value) 333{ 334 v8::Local<v8::Value> v8Value; 335 if (!dictionary.get(key, v8Value)) 336 return false; 337 338 value = nullptr; 339 // We need to handle a LocalDOMWindow specially, because a LocalDOMWindow wrapper 340 // exists on a prototype chain of v8Value. 341 if (v8Value->IsObject()) { 342 v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value); 343 v8::Handle<v8::Object> window = V8Window::findInstanceInPrototypeChain(wrapper, dictionary.isolate()); 344 if (!window.IsEmpty()) { 345 value = toWrapperTypeInfo(window)->toEventTarget(window); 346 return true; 347 } 348 } 349 350 if (V8DOMWrapper::isDOMWrapper(v8Value)) { 351 v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value); 352 value = toWrapperTypeInfo(wrapper)->toEventTarget(wrapper); 353 } 354 return true; 355} 356 357template <> 358bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, Vector<String>& value) 359{ 360 v8::Local<v8::Value> v8Value; 361 if (!dictionary.get(key, v8Value)) 362 return false; 363 364 if (!v8Value->IsArray()) 365 return false; 366 367 v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(v8Value); 368 for (size_t i = 0; i < v8Array->Length(); ++i) { 369 v8::Local<v8::Value> indexedValue = v8Array->Get(v8::Uint32::New(dictionary.isolate(), i)); 370 TOSTRING_DEFAULT(V8StringResource<>, stringValue, indexedValue, false); 371 value.append(stringValue); 372 } 373 374 return true; 375} 376 377template <> 378bool DictionaryHelper::convert(const Dictionary& dictionary, Dictionary::ConversionContext& context, const String& key, Vector<String>& value) 379{ 380 Dictionary::ConversionContextScope scope(context); 381 382 v8::Local<v8::Value> v8Value; 383 if (!dictionary.get(key, v8Value)) 384 return true; 385 386 if (context.isNullable() && blink::isUndefinedOrNull(v8Value)) 387 return true; 388 389 if (!v8Value->IsArray()) { 390 context.throwTypeError(ExceptionMessages::notASequenceTypeProperty(key)); 391 return false; 392 } 393 394 return DictionaryHelper::get(dictionary, key, value); 395} 396 397template <> 398bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, ArrayValue& value) 399{ 400 v8::Local<v8::Value> v8Value; 401 if (!dictionary.get(key, v8Value)) 402 return false; 403 404 if (!v8Value->IsArray()) 405 return false; 406 407 ASSERT(dictionary.isolate()); 408 ASSERT(dictionary.isolate() == v8::Isolate::GetCurrent()); 409 value = ArrayValue(v8::Local<v8::Array>::Cast(v8Value), dictionary.isolate()); 410 return true; 411} 412 413template <> 414bool DictionaryHelper::convert(const Dictionary& dictionary, Dictionary::ConversionContext& context, const String& key, ArrayValue& value) 415{ 416 Dictionary::ConversionContextScope scope(context); 417 418 v8::Local<v8::Value> v8Value; 419 if (!dictionary.get(key, v8Value)) 420 return true; 421 422 if (context.isNullable() && blink::isUndefinedOrNull(v8Value)) 423 return true; 424 425 if (!v8Value->IsArray()) { 426 context.throwTypeError(ExceptionMessages::notASequenceTypeProperty(key)); 427 return false; 428 } 429 430 return DictionaryHelper::get(dictionary, key, value); 431} 432 433template <> 434struct DictionaryHelperTraits<Uint8Array> { 435 typedef V8Uint8Array type; 436}; 437 438template <> 439struct DictionaryHelperTraits<ArrayBufferView> { 440 typedef V8ArrayBufferView type; 441}; 442 443template <> 444struct DictionaryHelperTraits<MediaKeyError> { 445 typedef V8MediaKeyError type; 446}; 447 448template <> 449struct DictionaryHelperTraits<DOMError> { 450 typedef V8DOMError type; 451}; 452 453template <> 454struct DictionaryHelperTraits<Storage> { 455 typedef V8Storage type; 456}; 457 458template <> 459struct DictionaryHelperTraits<Element> { 460 typedef V8Element type; 461}; 462 463template <> 464struct DictionaryHelperTraits<Path2D> { 465 typedef V8Path2D type; 466}; 467 468template bool DictionaryHelper::get(const Dictionary&, const String& key, RefPtr<Uint8Array>& value); 469template bool DictionaryHelper::get(const Dictionary&, const String& key, RefPtr<ArrayBufferView>& value); 470template bool DictionaryHelper::get(const Dictionary&, const String& key, RefPtrWillBeMember<MediaKeyError>& value); 471template bool DictionaryHelper::get(const Dictionary&, const String& key, RefPtrWillBeMember<DOMError>& value); 472template bool DictionaryHelper::get(const Dictionary&, const String& key, RefPtrWillBeMember<Storage>& value); 473template bool DictionaryHelper::get(const Dictionary&, const String& key, RefPtrWillBeMember<Element>& value); 474template bool DictionaryHelper::get(const Dictionary&, const String& key, RawPtr<Element>& value); 475template bool DictionaryHelper::get(const Dictionary&, const String& key, RefPtrWillBeMember<Path2D>& value); 476template bool DictionaryHelper::get(const Dictionary&, const String& key, RawPtr<Path2D>& value); 477 478template <typename T> 479struct IntegralTypeTraits { 480}; 481 482template <> 483struct IntegralTypeTraits<uint8_t> { 484 static inline uint8_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState) 485 { 486 return toUInt8(value, configuration, exceptionState); 487 } 488 static const String typeName() { return "UInt8"; } 489}; 490 491template <> 492struct IntegralTypeTraits<int8_t> { 493 static inline int8_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState) 494 { 495 return toInt8(value, configuration, exceptionState); 496 } 497 static const String typeName() { return "Int8"; } 498}; 499 500template <> 501struct IntegralTypeTraits<unsigned short> { 502 static inline uint16_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState) 503 { 504 return toUInt16(value, configuration, exceptionState); 505 } 506 static const String typeName() { return "UInt16"; } 507}; 508 509template <> 510struct IntegralTypeTraits<short> { 511 static inline int16_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState) 512 { 513 return toInt16(value, configuration, exceptionState); 514 } 515 static const String typeName() { return "Int16"; } 516}; 517 518template <> 519struct IntegralTypeTraits<unsigned> { 520 static inline uint32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState) 521 { 522 return toUInt32(value, configuration, exceptionState); 523 } 524 static const String typeName() { return "UInt32"; } 525}; 526 527template <> 528struct IntegralTypeTraits<unsigned long> { 529 static inline uint32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState) 530 { 531 return toUInt32(value, configuration, exceptionState); 532 } 533 static const String typeName() { return "UInt32"; } 534}; 535 536template <> 537struct IntegralTypeTraits<int> { 538 static inline int32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState) 539 { 540 return toInt32(value, configuration, exceptionState); 541 } 542 static const String typeName() { return "Int32"; } 543}; 544 545template <> 546struct IntegralTypeTraits<long> { 547 static inline int32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState) 548 { 549 return toInt32(value, configuration, exceptionState); 550 } 551 static const String typeName() { return "Int32"; } 552}; 553 554template <> 555struct IntegralTypeTraits<unsigned long long> { 556 static inline unsigned long long toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState) 557 { 558 return toUInt64(value, configuration, exceptionState); 559 } 560 static const String typeName() { return "UInt64"; } 561}; 562 563template <> 564struct IntegralTypeTraits<long long> { 565 static inline long long toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState) 566 { 567 return toInt64(value, configuration, exceptionState); 568 } 569 static const String typeName() { return "Int64"; } 570}; 571 572template<typename T> 573bool DictionaryHelper::convert(const Dictionary& dictionary, Dictionary::ConversionContext& context, const String& key, T& value) 574{ 575 Dictionary::ConversionContextScope scope(context); 576 577 v8::Local<v8::Value> v8Value; 578 if (!dictionary.get(key, v8Value)) 579 return true; 580 581 value = IntegralTypeTraits<T>::toIntegral(v8Value, NormalConversion, context.exceptionState()); 582 if (context.exceptionState().throwIfNeeded()) 583 return false; 584 585 return true; 586} 587 588template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, uint8_t& value); 589template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, int8_t& value); 590template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, unsigned short& value); 591template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, short& value); 592template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, unsigned& value); 593template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, unsigned long& value); 594template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, int& value); 595template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, long& value); 596template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, long long& value); 597template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, unsigned long long& value); 598 599template<typename T> 600bool DictionaryHelper::convert(const Dictionary& dictionary, Dictionary::ConversionContext& context, const String& key, Nullable<T>& value) 601{ 602 Dictionary::ConversionContextScope scope(context); 603 604 v8::Local<v8::Value> v8Value; 605 if (!dictionary.get(key, v8Value)) 606 return true; 607 608 if (context.isNullable() && blink::isUndefinedOrNull(v8Value)) { 609 value = Nullable<T>(); 610 return true; 611 } 612 613 T converted = IntegralTypeTraits<T>::toIntegral(v8Value, NormalConversion, context.exceptionState()); 614 615 if (context.exceptionState().throwIfNeeded()) 616 return false; 617 618 value = Nullable<T>(converted); 619 return true; 620} 621 622template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, Nullable<uint8_t>& value); 623template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, Nullable<int8_t>& value); 624template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, Nullable<unsigned short>& value); 625template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, Nullable<short>& value); 626template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, Nullable<unsigned>& value); 627template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, Nullable<unsigned long>& value); 628template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, Nullable<int>& value); 629template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, Nullable<long>& value); 630template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, Nullable<long long>& value); 631template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, Nullable<unsigned long long>& value); 632 633template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, RefPtrWillBeMember<LocalDOMWindow>& value); 634template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, RefPtrWillBeMember<Storage>& value); 635template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, RefPtr<Uint8Array>& value); 636template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, RefPtr<ArrayBufferView>& value); 637template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, RefPtrWillBeMember<MediaKeyError>& value); 638template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, RefPtrWillBeMember<TrackBase>& value); 639template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, RefPtrWillBeMember<EventTarget>& value); 640 641template <> 642bool DictionaryHelper::convert(const Dictionary& dictionary, Dictionary::ConversionContext& context, const String& key, MessagePortArray& value) 643{ 644 Dictionary::ConversionContextScope scope(context); 645 646 v8::Local<v8::Value> v8Value; 647 if (!dictionary.get(key, v8Value)) 648 return true; 649 650 ASSERT(dictionary.isolate()); 651 ASSERT(dictionary.isolate() == v8::Isolate::GetCurrent()); 652 653 if (isUndefinedOrNull(v8Value)) 654 return true; 655 656 value = toRefPtrWillBeMemberNativeArray<MessagePort, V8MessagePort>(v8Value, key, dictionary.isolate(), context.exceptionState()); 657 658 if (context.exceptionState().throwIfNeeded()) 659 return false; 660 661 return true; 662} 663 664} // namespace blink 665