#include "V8IDBKeyRange.h"
#include "V8MIDIPort.h"
#include "V8MediaKeyError.h"
+#include "V8MessagePort.h"
#include "V8SpeechRecognitionError.h"
#include "V8SpeechRecognitionResult.h"
#include "V8SpeechRecognitionResultList.h"
#include "V8VoidCallback.h"
#include "V8Window.h"
#include "bindings/v8/ArrayValue.h"
+#include "bindings/v8/ExceptionMessages.h"
+#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8Utilities.h"
#include "bindings/v8/custom/V8ArrayBufferViewCustom.h"
{
}
-Dictionary::Dictionary(const v8::Local<v8::Value>& options, v8::Isolate* isolate)
+Dictionary::Dictionary(const v8::Handle<v8::Value>& options, v8::Isolate* isolate)
: m_options(options)
, m_isolate(isolate)
{
return WebCore::isUndefinedOrNull(m_options);
}
+bool Dictionary::hasProperty(const String& key) const
+{
+ if (isUndefinedOrNull())
+ return false;
+ v8::Local<v8::Object> options = m_options->ToObject();
+ ASSERT(!options.IsEmpty());
+
+ ASSERT(m_isolate);
+ ASSERT(m_isolate == v8::Isolate::GetCurrent());
+ v8::Handle<v8::String> v8Key = v8String(m_isolate, key);
+ if (!options->Has(v8Key))
+ return false;
+
+ return true;
+}
+
bool Dictionary::getKey(const String& key, v8::Local<v8::Value>& value) const
{
if (isUndefinedOrNull())
ASSERT(m_isolate);
ASSERT(m_isolate == v8::Isolate::GetCurrent());
- v8::Handle<v8::String> v8Key = v8String(key, m_isolate);
+ v8::Handle<v8::String> v8Key = v8String(m_isolate, key);
if (!options->Has(v8Key))
return false;
value = options->Get(v8Key);
return true;
}
+bool Dictionary::convert(ConversionContext& context, const String& key, bool& value) const
+{
+ ConversionContextScope scope(context);
+ get(key, value);
+ return true;
+}
+
bool Dictionary::get(const String& key, int32_t& value) const
{
v8::Local<v8::Value> v8Value;
}
hasValue = true;
- v8::Local<v8::Number> v8Number = v8Value->ToNumber();
+ V8TRYCATCH_RETURN(v8::Local<v8::Number>, v8Number, v8Value->ToNumber(), false);
if (v8Number.IsEmpty())
return false;
value = v8Number->Value();
return get(key, value, unused);
}
-bool Dictionary::get(const String& key, String& value) const
+bool Dictionary::convert(ConversionContext& context, const String& key, double& value) const
+{
+ ConversionContextScope scope(context);
+
+ bool hasValue = false;
+ if (!get(key, value, hasValue) && hasValue) {
+ context.throwTypeError(ExceptionMessages::incorrectPropertyType(key, "is not of type 'double'."));
+ return false;
+ }
+ return true;
+}
+
+template<typename StringType>
+inline bool Dictionary::getStringType(const String& key, StringType& value) const
{
v8::Local<v8::Value> v8Value;
if (!getKey(key, v8Value))
return true;
}
+bool Dictionary::get(const String& key, String& value) const
+{
+ return getStringType(key, value);
+}
+
+bool Dictionary::get(const String& key, AtomicString& value) const
+{
+ return getStringType(key, value);
+}
+
+bool Dictionary::convert(ConversionContext& context, const String& key, String& value) const
+{
+ ConversionContextScope scope(context);
+
+ v8::Local<v8::Value> v8Value;
+ if (!getKey(key, v8Value))
+ return true;
+
+ V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringValue, v8Value, false);
+ value = stringValue;
+ return true;
+}
+
bool Dictionary::get(const String& key, ScriptValue& value) const
{
v8::Local<v8::Value> v8Value;
return true;
}
+bool Dictionary::convert(ConversionContext& context, const String& key, ScriptValue& value) const
+{
+ ConversionContextScope scope(context);
+
+ get(key, value);
+ return true;
+}
+
bool Dictionary::get(const String& key, unsigned short& value) const
{
v8::Local<v8::Value> v8Value;
if (!getKey(key, v8Value))
return false;
- v8::Local<v8::Number> v8Number = v8Value->ToNumber();
+ V8TRYCATCH_RETURN(v8::Local<v8::Number>, v8Number, v8Value->ToNumber(), false);
if (v8Number.IsEmpty())
return false;
double d = v8Number->Value();
// We need to handle a DOMWindow specially, because a DOMWindow wrapper
// exists on a prototype chain of v8Value.
- value = 0;
- if (v8Value->IsObject()) {
- v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
- v8::Handle<v8::Object> window = wrapper->FindInstanceInPrototypeChain(V8Window::GetTemplate(m_isolate, worldTypeInMainThread(m_isolate)));
- if (!window.IsEmpty())
- value = V8Window::toNative(window);
- }
+ value = toDOMWindow(v8Value, m_isolate);
return true;
}
-bool Dictionary::get(const String& key, RefPtr<Storage>& value) const
+bool Dictionary::get(const String& key, RefPtrWillBeRawPtr<Storage>& value) const
{
v8::Local<v8::Value> v8Value;
if (!getKey(key, v8Value))
return false;
value = 0;
- if (V8Storage::HasInstance(v8Value, m_isolate, worldType(m_isolate)))
+ if (V8Storage::hasInstance(v8Value, m_isolate))
value = V8Storage::toNative(v8::Handle<v8::Object>::Cast(v8Value));
return true;
}
ASSERT(m_isolate);
ASSERT(m_isolate == v8::Isolate::GetCurrent());
- return getMessagePortArray(v8Value, key, value, m_isolate);
+ if (WebCore::isUndefinedOrNull(v8Value))
+ return true;
+ bool success = false;
+ value = toRefPtrNativeArray<MessagePort, V8MessagePort>(v8Value, key, m_isolate, &success);
+ return success;
+}
+
+bool Dictionary::convert(ConversionContext& context, const String& key, MessagePortArray& value) const
+{
+ ConversionContextScope scope(context);
+
+ v8::Local<v8::Value> v8Value;
+ if (!getKey(key, v8Value))
+ return true;
+
+ return get(key, value);
}
bool Dictionary::get(const String& key, HashSet<AtomicString>& value) const
ASSERT(m_isolate == v8::Isolate::GetCurrent());
v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(v8Value);
for (size_t i = 0; i < v8Array->Length(); ++i) {
- v8::Local<v8::Value> indexedValue = v8Array->Get(v8::Integer::New(i, m_isolate));
+ v8::Local<v8::Value> indexedValue = v8Array->Get(v8::Integer::New(m_isolate, i));
V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringValue, indexedValue, false);
value.add(stringValue);
}
return true;
}
-bool Dictionary::getWithUndefinedOrNullCheck(const String& key, String& value) const
+bool Dictionary::convert(ConversionContext& context, const String& key, HashSet<AtomicString>& value) const
{
+ ConversionContextScope scope(context);
+
v8::Local<v8::Value> v8Value;
- if (!getKey(key, v8Value) || v8Value->IsNull() || v8Value->IsUndefined())
- return false;
+ if (!getKey(key, v8Value))
+ return true;
- if (WebCore::isUndefinedOrNull(v8Value)) {
- value = String();
+ if (context.isNullable() && WebCore::isUndefinedOrNull(v8Value))
return true;
+
+ if (!v8Value->IsArray()) {
+ context.throwTypeError(ExceptionMessages::notASequenceTypeProperty(key));
+ return false;
}
+ return get(key, value);
+}
+
+bool Dictionary::getWithUndefinedOrNullCheck(const String& key, String& value) const
+{
+ v8::Local<v8::Value> v8Value;
+ if (!getKey(key, v8Value) || WebCore::isUndefinedOrNull(v8Value))
+ return false;
+
V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringValue, v8Value, false);
value = stringValue;
return true;
return false;
value = 0;
- if (V8Uint8Array::HasInstance(v8Value, m_isolate, worldType(m_isolate)))
+ if (V8Uint8Array::hasInstance(v8Value, m_isolate))
value = V8Uint8Array::toNative(v8::Handle<v8::Object>::Cast(v8Value));
return true;
}
return false;
value = 0;
- if (V8ArrayBufferView::HasInstance(v8Value, m_isolate, worldType(m_isolate)))
+ if (V8ArrayBufferView::hasInstance(v8Value, m_isolate))
value = V8ArrayBufferView::toNative(v8::Handle<v8::Object>::Cast(v8Value));
return true;
}
return false;
value = 0;
- if (V8MIDIPort::HasInstance(v8Value, m_isolate, worldType(m_isolate)))
+ if (V8MIDIPort::hasInstance(v8Value, m_isolate))
value = V8MIDIPort::toNative(v8::Handle<v8::Object>::Cast(v8Value));
return true;
}
return false;
value = 0;
- if (V8MediaKeyError::HasInstance(v8Value, m_isolate, worldType(m_isolate)))
+ if (V8MediaKeyError::hasInstance(v8Value, m_isolate))
value = V8MediaKeyError::toNative(v8::Handle<v8::Object>::Cast(v8Value));
return true;
}
// FIXME: this will need to be changed so it can also return an AudioTrack or a VideoTrack once
// we add them.
- v8::Handle<v8::Object> track = wrapper->FindInstanceInPrototypeChain(V8TextTrack::GetTemplate(m_isolate, worldType(m_isolate)));
+ v8::Handle<v8::Object> track = wrapper->FindInstanceInPrototypeChain(V8TextTrack::domTemplate(m_isolate, worldType(m_isolate)));
if (!track.IsEmpty())
source = V8TextTrack::toNative(track);
}
return false;
value = 0;
- if (V8SpeechRecognitionError::HasInstance(v8Value, m_isolate, worldType(m_isolate)))
+ if (V8SpeechRecognitionError::hasInstance(v8Value, m_isolate))
value = V8SpeechRecognitionError::toNative(v8::Handle<v8::Object>::Cast(v8Value));
return true;
}
-bool Dictionary::get(const String& key, RefPtr<SpeechRecognitionResult>& value) const
+bool Dictionary::get(const String& key, RefPtrWillBeRawPtr<SpeechRecognitionResult>& value) const
{
v8::Local<v8::Value> v8Value;
if (!getKey(key, v8Value))
return false;
value = 0;
- if (V8SpeechRecognitionResult::HasInstance(v8Value, m_isolate, worldType(m_isolate)))
+ if (V8SpeechRecognitionResult::hasInstance(v8Value, m_isolate))
value = V8SpeechRecognitionResult::toNative(v8::Handle<v8::Object>::Cast(v8Value));
return true;
}
-bool Dictionary::get(const String& key, RefPtr<SpeechRecognitionResultList>& value) const
+bool Dictionary::get(const String& key, RefPtrWillBeRawPtr<SpeechRecognitionResultList>& value) const
{
v8::Local<v8::Value> v8Value;
if (!getKey(key, v8Value))
return false;
value = 0;
- if (V8SpeechRecognitionResultList::HasInstance(v8Value, m_isolate, worldType(m_isolate)))
+ if (V8SpeechRecognitionResultList::hasInstance(v8Value, m_isolate))
value = V8SpeechRecognitionResultList::toNative(v8::Handle<v8::Object>::Cast(v8Value));
return true;
}
return false;
value = 0;
- if (V8MediaStream::HasInstance(v8Value, m_isolate, worldType(m_isolate)))
+ if (V8MediaStream::hasInstance(v8Value, m_isolate))
value = V8MediaStream::toNative(v8::Handle<v8::Object>::Cast(v8Value));
return true;
}
// exists on a prototype chain of v8Value.
if (v8Value->IsObject()) {
v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
- v8::Handle<v8::Object> window = wrapper->FindInstanceInPrototypeChain(V8Window::GetTemplate(m_isolate, worldTypeInMainThread(m_isolate)));
+ v8::Handle<v8::Object> window = wrapper->FindInstanceInPrototypeChain(V8Window::domTemplate(m_isolate, worldTypeInMainThread(m_isolate)));
if (!window.IsEmpty()) {
value = toWrapperTypeInfo(window)->toEventTarget(window);
return true;
return true;
}
+bool Dictionary::convert(ConversionContext& context, const String& key, Dictionary& value) const
+{
+ ConversionContextScope scope(context);
+
+ v8::Local<v8::Value> v8Value;
+ if (!getKey(key, v8Value))
+ return true;
+
+ if (v8Value->IsObject())
+ return get(key, value);
+
+ if (context.isNullable() && WebCore::isUndefinedOrNull(v8Value))
+ return true;
+
+ context.throwTypeError(ExceptionMessages::incorrectPropertyType(key, "does not have a Dictionary type."));
+ return false;
+}
+
bool Dictionary::get(const String& key, Vector<String>& value) const
{
v8::Local<v8::Value> v8Value;
v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(v8Value);
for (size_t i = 0; i < v8Array->Length(); ++i) {
- v8::Local<v8::Value> indexedValue = v8Array->Get(v8::Uint32::New(i, m_isolate));
+ v8::Local<v8::Value> indexedValue = v8Array->Get(v8::Uint32::New(m_isolate, i));
V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringValue, indexedValue, false);
value.append(stringValue);
}
return true;
}
+bool Dictionary::convert(ConversionContext& context, const String& key, Vector<String>& value) const
+{
+ ConversionContextScope scope(context);
+
+ v8::Local<v8::Value> v8Value;
+ if (!getKey(key, v8Value))
+ return true;
+
+ if (context.isNullable() && WebCore::isUndefinedOrNull(v8Value))
+ return true;
+
+ if (!v8Value->IsArray()) {
+ context.throwTypeError(ExceptionMessages::notASequenceTypeProperty(key));
+ return false;
+ }
+
+ return get(key, value);
+}
+
bool Dictionary::get(const String& key, ArrayValue& value) const
{
v8::Local<v8::Value> v8Value;
return true;
}
+bool Dictionary::convert(ConversionContext& context, const String& key, ArrayValue& value) const
+{
+ ConversionContextScope scope(context);
+
+ v8::Local<v8::Value> v8Value;
+ if (!getKey(key, v8Value))
+ return true;
+
+ if (context.isNullable() && WebCore::isUndefinedOrNull(v8Value))
+ return true;
+
+ if (!v8Value->IsArray()) {
+ context.throwTypeError(ExceptionMessages::notASequenceTypeProperty(key));
+ return false;
+ }
+
+ return get(key, value);
+}
+
bool Dictionary::get(const String& key, RefPtr<DOMError>& value) const
{
v8::Local<v8::Value> v8Value;
DOMError* error = 0;
if (v8Value->IsObject()) {
v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
- v8::Handle<v8::Object> domError = wrapper->FindInstanceInPrototypeChain(V8DOMError::GetTemplate(m_isolate, worldType(m_isolate)));
+ v8::Handle<v8::Object> domError = wrapper->FindInstanceInPrototypeChain(V8DOMError::domTemplate(m_isolate, worldType(m_isolate)));
if (!domError.IsEmpty())
error = V8DOMError::toNative(domError);
}
return true;
}
-bool Dictionary::get(const String& key, RefPtr<VoidCallback>& value) const
+bool Dictionary::get(const String& key, OwnPtr<VoidCallback>& value) const
{
v8::Local<v8::Value> v8Value;
if (!getKey(key, v8Value))
if (!v8Value->IsFunction())
return false;
- value = V8VoidCallback::create(v8Value, getExecutionContext());
+ value = V8VoidCallback::create(v8::Handle<v8::Function>::Cast(v8Value), currentExecutionContext(m_isolate));
return true;
}
return true;
}
+void Dictionary::ConversionContext::resetPerPropertyContext()
+{
+ if (m_dirty) {
+ m_dirty = false;
+ m_isNullable = false;
+ m_propertyTypeName = "";
+ }
+}
+
+Dictionary::ConversionContext& Dictionary::ConversionContext::setConversionType(const String& typeName, bool isNullable)
+{
+ ASSERT(!m_dirty);
+ m_dirty = true;
+ m_isNullable = isNullable;
+ m_propertyTypeName = typeName;
+
+ return *this;
+}
+
+void Dictionary::ConversionContext::throwTypeError(const String& detail)
+{
+ if (forConstructor()) {
+ exceptionState().throwTypeError(detail);
+ } else {
+ ASSERT(!methodName().isEmpty());
+ exceptionState().throwTypeError(ExceptionMessages::failedToExecute(interfaceName(), methodName(), detail));
+ }
+}
+
} // namespace WebCore