Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(319)

Unified Diff: Source/bindings/core/v8/PropertyBag.h

Issue 534133002: [WIP] bindings: Introduce PropertyBag (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/bindings/core/v8/DictionaryHelperForCore.cpp ('k') | Source/bindings/core/v8/PropertyBag.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/bindings/core/v8/PropertyBag.h
diff --git a/Source/bindings/core/v8/PropertyBag.h b/Source/bindings/core/v8/PropertyBag.h
new file mode 100644
index 0000000000000000000000000000000000000000..80750e2976ec872e25c3dd5f7ff096b8c61133e5
--- /dev/null
+++ b/Source/bindings/core/v8/PropertyBag.h
@@ -0,0 +1,266 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PropertyBag_h
+#define PropertyBag_h
+
+#include "bindings/core/v8/ArrayValue.h"
+#include "bindings/core/v8/ExceptionMessages.h"
+#include "bindings/core/v8/ExceptionState.h"
+#include "bindings/core/v8/Nullable.h"
+#include "bindings/core/v8/PropertyBagTraits.h"
+#include "bindings/core/v8/V8Binding.h"
+#include "bindings/core/v8/V8MessagePort.h"
+#include "bindings/core/v8/custom/V8ArrayBufferViewCustom.h"
+#include "bindings/core/v8/custom/V8Uint8ArrayCustom.h"
+#include "core/html/track/TrackBase.h"
+#include "wtf/HashSet.h"
+#include "wtf/Noncopyable.h"
+#include "wtf/Vector.h"
+#include "wtf/text/AtomicString.h"
+#include "wtf/text/WTFString.h"
+#include <v8.h>
+
+namespace blink {
+
+class ArrayValue;
+class Dictionary;
+class LocalDOMWindow;
+
+// FIXME: Remove these specialization. Maybe the IDL compiler
+// should generate them.
+template <>
+struct PropertyBagTraits<Uint8Array> {
+ typedef V8Uint8Array type;
+};
+
+template <>
+struct PropertyBagTraits<ArrayBufferView> {
+ typedef V8ArrayBufferView type;
+};
+
+// PropertyBag is used by bindings layer to retrieve native values from
+// a V8 object.
+class PropertyBag {
+ WTF_MAKE_NONCOPYABLE(PropertyBag);
+public:
+ enum PropertyNullable {
+ IsNullable,
+ IsNotNullable
+ };
+
+ PropertyBag(v8::Isolate* isolate, const v8::Handle<v8::Object>& object, ExceptionState& exceptionState)
+ : m_isolate(isolate)
+ , m_object(object)
+ , m_exceptionState(exceptionState)
+ {
+ ASSERT(!m_object.IsEmpty());
+ }
+
+ bool hasProperty(const String& key) const
+ {
+ v8::Handle<v8::String> v8Key = v8String(m_isolate, key);
+ return m_object->Has(v8Key);
+ }
+
+ template <typename T>
+ bool get(const String& key, T& value, bool& hasValue, PropertyNullable nullable = IsNotNullable) const
+ {
+ hasValue = false;
+ v8::Handle<v8::String> v8Key = v8String(m_isolate, key);
+ v8::Local<v8::Value> v8Value = m_object->Get(v8Key);
+ if (v8Value.IsEmpty())
+ return false;
+
+ hasValue = true;
+ bool success;
+ if (nullable == IsNullable) {
+ // Try to get a value before isUndefinedOrNull() check
+ // because getInternal() may handle null/undefined.
+ success = getInternal(key, v8Value, value);
+ if (isUndefinedOrNull(v8Value)) {
+ m_exceptionState.clearException();
+ return true;
+ }
+ } else {
+ if (isUndefinedOrNull(v8Value))
+ return false;
+ success = getInternal(key, v8Value, value);
+ }
+
+ if (m_exceptionState.throwIfNeeded()) {
+ m_exceptionState.clearException();
+ return false;
+ }
+ return success;
+ }
+
+ template <typename T>
+ bool get(const String& key, T& value, PropertyNullable nullable = IsNotNullable) const
+ {
+ bool unused;
+ return get(key, value, unused, nullable);
+ }
+
+ // Similar to get() but returns true when the V8 object doesn't have the given key.
+ template <typename T>
+ bool convert(const String& key, T& value) const
+ {
+ v8::Handle<v8::String> v8Key = v8String(m_isolate, key);
+ v8::Local<v8::Value> v8Value = m_object->Get(v8Key);
+ if (v8Value.IsEmpty())
+ return true;
+ bool success = getInternal(key, v8Value, value);
+ if (isUndefinedOrNull(v8Value)) {
+ m_exceptionState.clearException();
+ return true;
+ }
+ return success;
+ }
+
+ template <typename T>
+ bool set(const String& key, const T& value)
+ {
+ // FIXME: Use the right creationContext.
+ v8::Handle<v8::Object> creationContext;
+ return m_object->Set(v8String(m_isolate, key), V8ValueTraits<T>::toV8Value(value, creationContext, m_isolate));
+ }
+
+private:
+ // FIXME: Following specializations should be gone.
+ bool getInternal(const String&, v8::Handle<v8::Value>&, ArrayValue&) const;
+ bool getInternal(const String&, v8::Handle<v8::Value>&, RefPtrWillBeMember<LocalDOMWindow>&) const;
+ bool getInternal(const String&, v8::Handle<v8::Value>&, MessagePortArray&) const;
+ bool getInternal(const String&, v8::Handle<v8::Value>&, HashSet<AtomicString>&) const;
+ bool getInternal(const String&, v8::Handle<v8::Value>&, RefPtrWillBeMember<TrackBase>&) const;
+ bool getInternal(const String&, v8::Handle<v8::Value>&, RefPtrWillBeMember<EventTarget>&) const;
+
+ // 'any' type use this function.
+ bool getInternal(const String& key, v8::Handle<v8::Value>& v8Value, v8::Local<v8::Value>& value) const
+ {
+ value = v8Value;
+ return true;
+ }
+
+ // IDL interface types use this template.
+ template <template <typename> class PointerType, typename T>
+ bool getInternal(const String& key, v8::Handle<v8::Value>& v8Value, PointerType<T>& value) const
+ {
+ value = PropertyBagTraits<T>::type::toImplWithTypeCheck(m_isolate, v8Value);
+ return !!value;
+ }
+
+ // Container types use following templates.
+
+ template <typename T>
+ bool getInternal(const String& key, v8::Handle<v8::Value>& v8Value, Vector<T>& value) const
+ {
+ if (!v8Value->IsArray())
+ return false;
+ value = toImplArray<T>(v8Value, 0, m_isolate);
+ return true;
+ }
+
+ template <typename T>
+ bool getInternal(const String& key, v8::Handle<v8::Value>& v8Value, Nullable<T>& value) const
+ {
+ if (isUndefinedOrNull(v8Value))
+ return true;
+
+ T innerValue;
+ if (getInternal(key, v8Value, innerValue)) {
+ value.set(innerValue);
+ return true;
+ }
+ return false;
+ }
+
+ // Default template, primitive types use this template.
+ template <typename T>
+ bool getInternal(const String& key, v8::Handle<v8::Value>& v8Value, T& value) const
+ {
+ value = NativeValueTraits<T>::nativeValueMayFail(m_isolate, v8Value, m_exceptionState);
+ if (m_exceptionState.hadException())
+ return false;
+ return true;
+ }
+
+ v8::Isolate* m_isolate;
+ v8::Handle<v8::Object> m_object;
+ ExceptionState& m_exceptionState;
+
+ friend class Dictionary;
+};
+
+// FIXME: Reduce duplication. Maybe move to V8Binding.h?
+template <typename T>
+struct TypeErrorMessage {
+ static void throwTypeError(const String& key, const String& typeName, ExceptionState& exceptionState)
+ {
+ exceptionState.throwTypeError(ExceptionMessages::incorrectPropertyType(key, "does not have a " + typeName + " type."));
+ }
+};
+
+template <typename T>
+struct TypeErrorMessage<HashSet<T> > {
+ static void throwTypeError(const String& key, const String& typeName, ExceptionState& exceptionState)
+ {
+ exceptionState.throwTypeError(ExceptionMessages::notASequenceTypeProperty(key));
+ }
+};
+
+template <typename T>
+struct TypeErrorMessage<Vector<T> > {
+ static void throwTypeError(const String& key, const String& typeName, ExceptionState& exceptionState)
+ {
+ exceptionState.throwTypeError(ExceptionMessages::notASequenceTypeProperty(key));
+ }
+};
+
+template <>
+struct TypeErrorMessage<ArrayValue> {
+ static void throwTypeError(const String& key, const String& typeName, ExceptionState& exceptionState)
+ {
+ exceptionState.throwTypeError(ExceptionMessages::notASequenceTypeProperty(key));
+ }
+};
+
+// FIXME: Separate into its own header file.
+class EventInitInitializer {
+public:
+ EventInitInitializer(const String& interfaceName, const PropertyBag& bag, ExceptionState& exceptionState)
+ : m_interfaceName(interfaceName)
+ , m_bag(bag)
+ , m_exceptionState(exceptionState)
+ {
+ }
+
+ template <typename T>
+ bool initializeProperty(const String& key, T& value, const String& typeName, PropertyBag::PropertyNullable nullable)
+ {
+ if (!m_bag.hasProperty(key))
+ return true;
+
+ if (m_bag.convert(key, value))
+ return true;
+
+ if (m_exceptionState.throwIfNeeded())
+ return false;
+
+ TypeErrorMessage<T>::throwTypeError(key, typeName, m_exceptionState);
+ return false;
+ }
+
+ // FIXME: unnecessary?
+ const String& interfaceName() const { return m_interfaceName; }
+
+private:
+ const String m_interfaceName;
+ const PropertyBag& m_bag;
+ ExceptionState& m_exceptionState;
+};
+
+} // namespace blink
+
+#endif // PropertyBag_h
« no previous file with comments | « Source/bindings/core/v8/DictionaryHelperForCore.cpp ('k') | Source/bindings/core/v8/PropertyBag.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698