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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef PropertyBag_h
6 #define PropertyBag_h
7
8 #include "bindings/core/v8/ArrayValue.h"
9 #include "bindings/core/v8/ExceptionMessages.h"
10 #include "bindings/core/v8/ExceptionState.h"
11 #include "bindings/core/v8/Nullable.h"
12 #include "bindings/core/v8/PropertyBagTraits.h"
13 #include "bindings/core/v8/V8Binding.h"
14 #include "bindings/core/v8/V8MessagePort.h"
15 #include "bindings/core/v8/custom/V8ArrayBufferViewCustom.h"
16 #include "bindings/core/v8/custom/V8Uint8ArrayCustom.h"
17 #include "core/html/track/TrackBase.h"
18 #include "wtf/HashSet.h"
19 #include "wtf/Noncopyable.h"
20 #include "wtf/Vector.h"
21 #include "wtf/text/AtomicString.h"
22 #include "wtf/text/WTFString.h"
23 #include <v8.h>
24
25 namespace blink {
26
27 class ArrayValue;
28 class Dictionary;
29 class LocalDOMWindow;
30
31 // FIXME: Remove these specialization. Maybe the IDL compiler
32 // should generate them.
33 template <>
34 struct PropertyBagTraits<Uint8Array> {
35 typedef V8Uint8Array type;
36 };
37
38 template <>
39 struct PropertyBagTraits<ArrayBufferView> {
40 typedef V8ArrayBufferView type;
41 };
42
43 // PropertyBag is used by bindings layer to retrieve native values from
44 // a V8 object.
45 class PropertyBag {
46 WTF_MAKE_NONCOPYABLE(PropertyBag);
47 public:
48 enum PropertyNullable {
49 IsNullable,
50 IsNotNullable
51 };
52
53 PropertyBag(v8::Isolate* isolate, const v8::Handle<v8::Object>& object, Exce ptionState& exceptionState)
54 : m_isolate(isolate)
55 , m_object(object)
56 , m_exceptionState(exceptionState)
57 {
58 ASSERT(!m_object.IsEmpty());
59 }
60
61 bool hasProperty(const String& key) const
62 {
63 v8::Handle<v8::String> v8Key = v8String(m_isolate, key);
64 return m_object->Has(v8Key);
65 }
66
67 template <typename T>
68 bool get(const String& key, T& value, bool& hasValue, PropertyNullable nulla ble = IsNotNullable) const
69 {
70 hasValue = false;
71 v8::Handle<v8::String> v8Key = v8String(m_isolate, key);
72 v8::Local<v8::Value> v8Value = m_object->Get(v8Key);
73 if (v8Value.IsEmpty())
74 return false;
75
76 hasValue = true;
77 bool success;
78 if (nullable == IsNullable) {
79 // Try to get a value before isUndefinedOrNull() check
80 // because getInternal() may handle null/undefined.
81 success = getInternal(key, v8Value, value);
82 if (isUndefinedOrNull(v8Value)) {
83 m_exceptionState.clearException();
84 return true;
85 }
86 } else {
87 if (isUndefinedOrNull(v8Value))
88 return false;
89 success = getInternal(key, v8Value, value);
90 }
91
92 if (m_exceptionState.throwIfNeeded()) {
93 m_exceptionState.clearException();
94 return false;
95 }
96 return success;
97 }
98
99 template <typename T>
100 bool get(const String& key, T& value, PropertyNullable nullable = IsNotNulla ble) const
101 {
102 bool unused;
103 return get(key, value, unused, nullable);
104 }
105
106 // Similar to get() but returns true when the V8 object doesn't have the giv en key.
107 template <typename T>
108 bool convert(const String& key, T& value) const
109 {
110 v8::Handle<v8::String> v8Key = v8String(m_isolate, key);
111 v8::Local<v8::Value> v8Value = m_object->Get(v8Key);
112 if (v8Value.IsEmpty())
113 return true;
114 bool success = getInternal(key, v8Value, value);
115 if (isUndefinedOrNull(v8Value)) {
116 m_exceptionState.clearException();
117 return true;
118 }
119 return success;
120 }
121
122 template <typename T>
123 bool set(const String& key, const T& value)
124 {
125 // FIXME: Use the right creationContext.
126 v8::Handle<v8::Object> creationContext;
127 return m_object->Set(v8String(m_isolate, key), V8ValueTraits<T>::toV8Val ue(value, creationContext, m_isolate));
128 }
129
130 private:
131 // FIXME: Following specializations should be gone.
132 bool getInternal(const String&, v8::Handle<v8::Value>&, ArrayValue&) const;
133 bool getInternal(const String&, v8::Handle<v8::Value>&, RefPtrWillBeMember<L ocalDOMWindow>&) const;
134 bool getInternal(const String&, v8::Handle<v8::Value>&, MessagePortArray&) c onst;
135 bool getInternal(const String&, v8::Handle<v8::Value>&, HashSet<AtomicString >&) const;
136 bool getInternal(const String&, v8::Handle<v8::Value>&, RefPtrWillBeMember<T rackBase>&) const;
137 bool getInternal(const String&, v8::Handle<v8::Value>&, RefPtrWillBeMember<E ventTarget>&) const;
138
139 // 'any' type use this function.
140 bool getInternal(const String& key, v8::Handle<v8::Value>& v8Value, v8::Loca l<v8::Value>& value) const
141 {
142 value = v8Value;
143 return true;
144 }
145
146 // IDL interface types use this template.
147 template <template <typename> class PointerType, typename T>
148 bool getInternal(const String& key, v8::Handle<v8::Value>& v8Value, PointerT ype<T>& value) const
149 {
150 value = PropertyBagTraits<T>::type::toImplWithTypeCheck(m_isolate, v8Val ue);
151 return !!value;
152 }
153
154 // Container types use following templates.
155
156 template <typename T>
157 bool getInternal(const String& key, v8::Handle<v8::Value>& v8Value, Vector<T >& value) const
158 {
159 if (!v8Value->IsArray())
160 return false;
161 value = toImplArray<T>(v8Value, 0, m_isolate);
162 return true;
163 }
164
165 template <typename T>
166 bool getInternal(const String& key, v8::Handle<v8::Value>& v8Value, Nullable <T>& value) const
167 {
168 if (isUndefinedOrNull(v8Value))
169 return true;
170
171 T innerValue;
172 if (getInternal(key, v8Value, innerValue)) {
173 value.set(innerValue);
174 return true;
175 }
176 return false;
177 }
178
179 // Default template, primitive types use this template.
180 template <typename T>
181 bool getInternal(const String& key, v8::Handle<v8::Value>& v8Value, T& value ) const
182 {
183 value = NativeValueTraits<T>::nativeValueMayFail(m_isolate, v8Value, m_e xceptionState);
184 if (m_exceptionState.hadException())
185 return false;
186 return true;
187 }
188
189 v8::Isolate* m_isolate;
190 v8::Handle<v8::Object> m_object;
191 ExceptionState& m_exceptionState;
192
193 friend class Dictionary;
194 };
195
196 // FIXME: Reduce duplication. Maybe move to V8Binding.h?
197 template <typename T>
198 struct TypeErrorMessage {
199 static void throwTypeError(const String& key, const String& typeName, Except ionState& exceptionState)
200 {
201 exceptionState.throwTypeError(ExceptionMessages::incorrectPropertyType(k ey, "does not have a " + typeName + " type."));
202 }
203 };
204
205 template <typename T>
206 struct TypeErrorMessage<HashSet<T> > {
207 static void throwTypeError(const String& key, const String& typeName, Except ionState& exceptionState)
208 {
209 exceptionState.throwTypeError(ExceptionMessages::notASequenceTypePropert y(key));
210 }
211 };
212
213 template <typename T>
214 struct TypeErrorMessage<Vector<T> > {
215 static void throwTypeError(const String& key, const String& typeName, Except ionState& exceptionState)
216 {
217 exceptionState.throwTypeError(ExceptionMessages::notASequenceTypePropert y(key));
218 }
219 };
220
221 template <>
222 struct TypeErrorMessage<ArrayValue> {
223 static void throwTypeError(const String& key, const String& typeName, Except ionState& exceptionState)
224 {
225 exceptionState.throwTypeError(ExceptionMessages::notASequenceTypePropert y(key));
226 }
227 };
228
229 // FIXME: Separate into its own header file.
230 class EventInitInitializer {
231 public:
232 EventInitInitializer(const String& interfaceName, const PropertyBag& bag, Ex ceptionState& exceptionState)
233 : m_interfaceName(interfaceName)
234 , m_bag(bag)
235 , m_exceptionState(exceptionState)
236 {
237 }
238
239 template <typename T>
240 bool initializeProperty(const String& key, T& value, const String& typeName, PropertyBag::PropertyNullable nullable)
241 {
242 if (!m_bag.hasProperty(key))
243 return true;
244
245 if (m_bag.convert(key, value))
246 return true;
247
248 if (m_exceptionState.throwIfNeeded())
249 return false;
250
251 TypeErrorMessage<T>::throwTypeError(key, typeName, m_exceptionState);
252 return false;
253 }
254
255 // FIXME: unnecessary?
256 const String& interfaceName() const { return m_interfaceName; }
257
258 private:
259 const String m_interfaceName;
260 const PropertyBag& m_bag;
261 ExceptionState& m_exceptionState;
262 };
263
264 } // namespace blink
265
266 #endif // PropertyBag_h
OLDNEW
« 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