1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
2 /* vim: set ts=2 sw=2 et tw=79: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
8 * A header for declaring various things that binding implementation headers
9 * might need. The idea is to make binding implementation headers safe to
10 * include anywhere without running into include hell like we do with
13 #ifndef mozilla_dom_BindingDeclarations_h__
14 #define mozilla_dom_BindingDeclarations_h__
16 #include "nsStringGlue.h"
18 #include "js/RootingAPI.h"
19 #include "mozilla/Maybe.h"
22 #include "nsAutoPtr.h" // for nsRefPtr member variables
23 #include "mozilla/dom/DOMString.h"
24 #include "mozilla/dom/OwningNonNull.h"
31 // Struct that serves as a base class for all dictionaries. Particularly useful
32 // so we can use IsBaseOf to detect dictionary template arguments.
36 bool ParseJSON(JSContext
* aCx
, const nsAString
& aJSON
,
37 JS::MutableHandle
<JS::Value
> aVal
);
39 bool StringifyToJSON(JSContext
* aCx
,
40 JS::MutableHandle
<JS::Value
> aValue
,
43 // aString is expected to actually be an nsAString*. Should only be
44 // called from StringifyToJSON.
45 static bool AppendJSONToString(const jschar
* aJSONData
, uint32_t aDataLength
,
49 // Struct that serves as a base class for all typed arrays and array buffers and
50 // array buffer views. Particularly useful so we can use IsBaseOf to detect
51 // typed array/buffer/view template arguments.
52 struct AllTypedArraysBase
{
55 // Struct that serves as a base class for all owning unions.
56 // Particularly useful so we can use IsBaseOf to detect owning union
57 // template arguments.
58 struct AllOwningUnionBase
{
67 class MOZ_STACK_CLASS GlobalObject
70 GlobalObject(JSContext
* aCx
, JSObject
* aObject
);
74 return mGlobalJSObject
;
77 nsISupports
* GetAsSupports() const;
79 // The context that this returns is not guaranteed to be in the compartment of
80 // the object returned from Get(), in fact it's generally in the caller's
82 JSContext
* Context() const
93 JS::Rooted
<JSObject
*> mGlobalJSObject
;
95 mutable nsISupports
* mGlobalObject
;
96 mutable nsCOMPtr
<nsISupports
> mGlobalObjectRef
;
99 // Class for representing optional arguments.
100 template<typename T
, typename InternalType
>
107 explicit Optional_base(const T
& aValue
)
109 mImpl
.emplace(aValue
);
112 template<typename T1
, typename T2
>
113 explicit Optional_base(const T1
& aValue1
, const T2
& aValue2
)
115 mImpl
.emplace(aValue1
, aValue2
);
118 bool WasPassed() const
120 return mImpl
.isSome();
123 // Return InternalType here so we can work with it usefully.
124 InternalType
& Construct()
131 InternalType
& Construct(const T1
&t1
)
137 template <class T1
, class T2
>
138 InternalType
& Construct(const T1
&t1
, const T2
&t2
)
140 mImpl
.emplace(t1
, t2
);
149 const T
& Value() const
154 // Return InternalType here so we can work with it usefully.
155 InternalType
& Value()
160 // And an explicit way to get the InternalType even if we're const.
161 const InternalType
& InternalValue() const
166 // If we ever decide to add conversion operators for optional arrays
167 // like the ones Nullable has, we'll need to ensure that Maybe<> has
168 // the boolean before the actual data.
171 // Forbid copy-construction and assignment
172 Optional_base(const Optional_base
& other
) MOZ_DELETE
;
173 const Optional_base
&operator=(const Optional_base
&other
) MOZ_DELETE
;
176 Maybe
<InternalType
> mImpl
;
180 class Optional
: public Optional_base
<T
, T
>
184 Optional_base
<T
, T
>()
187 explicit Optional(const T
& aValue
) :
188 Optional_base
<T
, T
>(aValue
)
193 class Optional
<JS::Handle
<T
> > :
194 public Optional_base
<JS::Handle
<T
>, JS::Rooted
<T
> >
198 Optional_base
<JS::Handle
<T
>, JS::Rooted
<T
> >()
201 explicit Optional(JSContext
* cx
) :
202 Optional_base
<JS::Handle
<T
>, JS::Rooted
<T
> >()
207 Optional(JSContext
* cx
, const T
& aValue
) :
208 Optional_base
<JS::Handle
<T
>, JS::Rooted
<T
> >(cx
, aValue
)
211 // Override the const Value() to return the right thing so we're not
212 // returning references to temporaries.
213 JS::Handle
<T
> Value() const
218 // And we have to override the non-const one too, since we're
219 // shadowing the one on the superclass.
220 JS::Rooted
<T
>& Value()
226 // A specialization of Optional for JSObject* to make sure that when someone
227 // calls Construct() on it we will pre-initialized the JSObject* to nullptr so
228 // it can be traced safely.
230 class Optional
<JSObject
*> : public Optional_base
<JSObject
*, JSObject
*>
234 Optional_base
<JSObject
*, JSObject
*>()
237 explicit Optional(JSObject
* aValue
) :
238 Optional_base
<JSObject
*, JSObject
*>(aValue
)
241 // Don't allow us to have an uninitialized JSObject*
242 JSObject
*& Construct()
244 // The Android compiler sucks and thinks we're trying to construct
245 // a JSObject* from an int if we don't cast here. :(
246 return Optional_base
<JSObject
*, JSObject
*>::Construct(
247 static_cast<JSObject
*>(nullptr));
251 JSObject
*& Construct(const T1
& t1
)
253 return Optional_base
<JSObject
*, JSObject
*>::Construct(t1
);
257 // A specialization of Optional for JS::Value to make sure no one ever uses it.
259 class Optional
<JS::Value
>
262 Optional() MOZ_DELETE
;
264 explicit Optional(JS::Value aValue
) MOZ_DELETE
;
267 // A specialization of Optional for NonNull that lets us get a T& from Value()
268 template<typename U
> class NonNull
;
270 class Optional
<NonNull
<T
> > : public Optional_base
<T
, NonNull
<T
> >
273 // We want our Value to actually return a non-const reference, even
274 // if we're const. At least for things that are normally pointer
278 return *this->mImpl
->get();
281 // And we have to override the non-const one too, since we're
282 // shadowing the one on the superclass.
289 // A specialization of Optional for OwningNonNull that lets us get a
292 class Optional
<OwningNonNull
<T
> > : public Optional_base
<T
, OwningNonNull
<T
> >
295 // We want our Value to actually return a non-const reference, even
296 // if we're const. At least for things that are normally pointer
300 return *this->mImpl
->get();
303 // And we have to override the non-const one too, since we're
304 // shadowing the one on the superclass.
305 OwningNonNull
<T
>& Value()
311 // Specialization for strings.
312 // XXXbz we can't pull in FakeString here, because it depends on internal
313 // strings. So we just have to forward-declare it and reimplement its
316 namespace binding_detail
{
318 } // namespace binding_detail
321 class Optional
<nsAString
>
324 Optional() : mPassed(false) {}
326 bool WasPassed() const
331 void operator=(const nsAString
* str
)
338 // If this code ever goes away, remove the comment pointing to it in the
339 // FakeString class in BindingUtils.h.
340 void operator=(const binding_detail::FakeString
* str
)
343 mStr
= reinterpret_cast<const nsString
*>(str
);
347 const nsAString
& Value() const
349 MOZ_ASSERT(WasPassed());
354 // Forbid copy-construction and assignment
355 Optional(const Optional
& other
) MOZ_DELETE
;
356 const Optional
&operator=(const Optional
&other
) MOZ_DELETE
;
359 const nsAString
* mStr
;
372 // This is no worse than get() in terms of const handling.
373 operator T
&() const {
375 MOZ_ASSERT(ptr
, "NonNull<T> was set to null");
379 operator T
*() const {
381 MOZ_ASSERT(ptr
, "NonNull<T> was set to null");
385 void operator=(T
* t
) {
394 void operator=(U
* t
) {
395 ptr
= t
->ToAStringPtr();
411 MOZ_ASSERT(ptr
, "NonNull<T> was set to null");
415 // Make us work with smart-ptr helpers that expect a get()
429 // Class for representing sequences in arguments. We use a non-auto array
430 // because that allows us to use sequences of sequences and the like. This
431 // needs to be fallible because web content controls the length of the array,
432 // and can easily try to create very large lengths.
434 class Sequence
: public FallibleTArray
<T
>
437 Sequence() : FallibleTArray
<T
>()
441 inline nsWrapperCache
*
442 GetWrapperCache(nsWrapperCache
* cache
)
447 inline nsWrapperCache
*
448 GetWrapperCache(void* p
)
453 // Helper template for smart pointers to resolve ambiguity between
454 // GetWrappeCache(void*) and GetWrapperCache(const ParentObject&).
455 template <template <typename
> class SmartPtr
, typename T
>
456 inline nsWrapperCache
*
457 GetWrapperCache(const SmartPtr
<T
>& aObject
)
459 return GetWrapperCache(aObject
.get());
462 struct ParentObject
{
464 ParentObject(T
* aObject
) :
466 mWrapperCache(GetWrapperCache(aObject
)),
470 template<class T
, template<typename
> class SmartPtr
>
471 ParentObject(const SmartPtr
<T
>& aObject
) :
472 mObject(aObject
.get()),
473 mWrapperCache(GetWrapperCache(aObject
.get())),
477 ParentObject(nsISupports
* aObject
, nsWrapperCache
* aCache
) :
479 mWrapperCache(aCache
),
483 nsISupports
* const mObject
;
484 nsWrapperCache
* const mWrapperCache
;
489 } // namespace mozilla
491 #endif // mozilla_dom_BindingDeclarations_h__