dom/bindings/BindingDeclarations.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
michael@0 2 /* vim: set ts=2 sw=2 et tw=79: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 /**
michael@0 8 * A header for declaring various things that binding implementation headers
michael@0 9 * might need. The idea is to make binding implementation headers safe to
michael@0 10 * include anywhere without running into include hell like we do with
michael@0 11 * BindingUtils.h
michael@0 12 */
michael@0 13 #ifndef mozilla_dom_BindingDeclarations_h__
michael@0 14 #define mozilla_dom_BindingDeclarations_h__
michael@0 15
michael@0 16 #include "nsStringGlue.h"
michael@0 17 #include "js/Value.h"
michael@0 18 #include "js/RootingAPI.h"
michael@0 19 #include "mozilla/Maybe.h"
michael@0 20 #include "nsCOMPtr.h"
michael@0 21 #include "nsTArray.h"
michael@0 22 #include "nsAutoPtr.h" // for nsRefPtr member variables
michael@0 23 #include "mozilla/dom/DOMString.h"
michael@0 24 #include "mozilla/dom/OwningNonNull.h"
michael@0 25
michael@0 26 class nsWrapperCache;
michael@0 27
michael@0 28 namespace mozilla {
michael@0 29 namespace dom {
michael@0 30
michael@0 31 // Struct that serves as a base class for all dictionaries. Particularly useful
michael@0 32 // so we can use IsBaseOf to detect dictionary template arguments.
michael@0 33 struct DictionaryBase
michael@0 34 {
michael@0 35 protected:
michael@0 36 bool ParseJSON(JSContext* aCx, const nsAString& aJSON,
michael@0 37 JS::MutableHandle<JS::Value> aVal);
michael@0 38 };
michael@0 39
michael@0 40 // Struct that serves as a base class for all typed arrays and array buffers and
michael@0 41 // array buffer views. Particularly useful so we can use IsBaseOf to detect
michael@0 42 // typed array/buffer/view template arguments.
michael@0 43 struct AllTypedArraysBase {
michael@0 44 };
michael@0 45
michael@0 46 // Struct that serves as a base class for all owning unions.
michael@0 47 // Particularly useful so we can use IsBaseOf to detect owning union
michael@0 48 // template arguments.
michael@0 49 struct AllOwningUnionBase {
michael@0 50 };
michael@0 51
michael@0 52
michael@0 53 struct EnumEntry {
michael@0 54 const char* value;
michael@0 55 size_t length;
michael@0 56 };
michael@0 57
michael@0 58 class MOZ_STACK_CLASS GlobalObject
michael@0 59 {
michael@0 60 public:
michael@0 61 GlobalObject(JSContext* aCx, JSObject* aObject);
michael@0 62
michael@0 63 JSObject* Get() const
michael@0 64 {
michael@0 65 return mGlobalJSObject;
michael@0 66 }
michael@0 67
michael@0 68 nsISupports* GetAsSupports() const;
michael@0 69
michael@0 70 // The context that this returns is not guaranteed to be in the compartment of
michael@0 71 // the object returned from Get(), in fact it's generally in the caller's
michael@0 72 // compartment.
michael@0 73 JSContext* GetContext() const
michael@0 74 {
michael@0 75 return mCx;
michael@0 76 }
michael@0 77
michael@0 78 bool Failed() const
michael@0 79 {
michael@0 80 return !Get();
michael@0 81 }
michael@0 82
michael@0 83 protected:
michael@0 84 JS::Rooted<JSObject*> mGlobalJSObject;
michael@0 85 JSContext* mCx;
michael@0 86 mutable nsISupports* mGlobalObject;
michael@0 87 mutable nsCOMPtr<nsISupports> mGlobalObjectRef;
michael@0 88 };
michael@0 89
michael@0 90 // Class for representing optional arguments.
michael@0 91 template<typename T, typename InternalType>
michael@0 92 class Optional_base
michael@0 93 {
michael@0 94 public:
michael@0 95 Optional_base()
michael@0 96 {}
michael@0 97
michael@0 98 explicit Optional_base(const T& aValue)
michael@0 99 {
michael@0 100 mImpl.construct(aValue);
michael@0 101 }
michael@0 102
michael@0 103 template<typename T1, typename T2>
michael@0 104 explicit Optional_base(const T1& aValue1, const T2& aValue2)
michael@0 105 {
michael@0 106 mImpl.construct(aValue1, aValue2);
michael@0 107 }
michael@0 108
michael@0 109 bool WasPassed() const
michael@0 110 {
michael@0 111 return !mImpl.empty();
michael@0 112 }
michael@0 113
michael@0 114 // Return InternalType here so we can work with it usefully.
michael@0 115 InternalType& Construct()
michael@0 116 {
michael@0 117 mImpl.construct();
michael@0 118 return mImpl.ref();
michael@0 119 }
michael@0 120
michael@0 121 template <class T1>
michael@0 122 InternalType& Construct(const T1 &t1)
michael@0 123 {
michael@0 124 mImpl.construct(t1);
michael@0 125 return mImpl.ref();
michael@0 126 }
michael@0 127
michael@0 128 template <class T1, class T2>
michael@0 129 InternalType& Construct(const T1 &t1, const T2 &t2)
michael@0 130 {
michael@0 131 mImpl.construct(t1, t2);
michael@0 132 return mImpl.ref();
michael@0 133 }
michael@0 134
michael@0 135 void Reset()
michael@0 136 {
michael@0 137 if (WasPassed()) {
michael@0 138 mImpl.destroy();
michael@0 139 }
michael@0 140 }
michael@0 141
michael@0 142 const T& Value() const
michael@0 143 {
michael@0 144 return mImpl.ref();
michael@0 145 }
michael@0 146
michael@0 147 // Return InternalType here so we can work with it usefully.
michael@0 148 InternalType& Value()
michael@0 149 {
michael@0 150 return mImpl.ref();
michael@0 151 }
michael@0 152
michael@0 153 // And an explicit way to get the InternalType even if we're const.
michael@0 154 const InternalType& InternalValue() const
michael@0 155 {
michael@0 156 return mImpl.ref();
michael@0 157 }
michael@0 158
michael@0 159 // If we ever decide to add conversion operators for optional arrays
michael@0 160 // like the ones Nullable has, we'll need to ensure that Maybe<> has
michael@0 161 // the boolean before the actual data.
michael@0 162
michael@0 163 private:
michael@0 164 // Forbid copy-construction and assignment
michael@0 165 Optional_base(const Optional_base& other) MOZ_DELETE;
michael@0 166 const Optional_base &operator=(const Optional_base &other) MOZ_DELETE;
michael@0 167
michael@0 168 protected:
michael@0 169 Maybe<InternalType> mImpl;
michael@0 170 };
michael@0 171
michael@0 172 template<typename T>
michael@0 173 class Optional : public Optional_base<T, T>
michael@0 174 {
michael@0 175 public:
michael@0 176 Optional() :
michael@0 177 Optional_base<T, T>()
michael@0 178 {}
michael@0 179
michael@0 180 explicit Optional(const T& aValue) :
michael@0 181 Optional_base<T, T>(aValue)
michael@0 182 {}
michael@0 183 };
michael@0 184
michael@0 185 template<typename T>
michael@0 186 class Optional<JS::Handle<T> > :
michael@0 187 public Optional_base<JS::Handle<T>, JS::Rooted<T> >
michael@0 188 {
michael@0 189 public:
michael@0 190 Optional() :
michael@0 191 Optional_base<JS::Handle<T>, JS::Rooted<T> >()
michael@0 192 {}
michael@0 193
michael@0 194 Optional(JSContext* cx) :
michael@0 195 Optional_base<JS::Handle<T>, JS::Rooted<T> >()
michael@0 196 {
michael@0 197 this->Construct(cx);
michael@0 198 }
michael@0 199
michael@0 200 Optional(JSContext* cx, const T& aValue) :
michael@0 201 Optional_base<JS::Handle<T>, JS::Rooted<T> >(cx, aValue)
michael@0 202 {}
michael@0 203
michael@0 204 // Override the const Value() to return the right thing so we're not
michael@0 205 // returning references to temporaries.
michael@0 206 JS::Handle<T> Value() const
michael@0 207 {
michael@0 208 return this->mImpl.ref();
michael@0 209 }
michael@0 210
michael@0 211 // And we have to override the non-const one too, since we're
michael@0 212 // shadowing the one on the superclass.
michael@0 213 JS::Rooted<T>& Value()
michael@0 214 {
michael@0 215 return this->mImpl.ref();
michael@0 216 }
michael@0 217 };
michael@0 218
michael@0 219 // A specialization of Optional for JSObject* to make sure that when someone
michael@0 220 // calls Construct() on it we will pre-initialized the JSObject* to nullptr so
michael@0 221 // it can be traced safely.
michael@0 222 template<>
michael@0 223 class Optional<JSObject*> : public Optional_base<JSObject*, JSObject*>
michael@0 224 {
michael@0 225 public:
michael@0 226 Optional() :
michael@0 227 Optional_base<JSObject*, JSObject*>()
michael@0 228 {}
michael@0 229
michael@0 230 explicit Optional(JSObject* aValue) :
michael@0 231 Optional_base<JSObject*, JSObject*>(aValue)
michael@0 232 {}
michael@0 233
michael@0 234 // Don't allow us to have an uninitialized JSObject*
michael@0 235 JSObject*& Construct()
michael@0 236 {
michael@0 237 // The Android compiler sucks and thinks we're trying to construct
michael@0 238 // a JSObject* from an int if we don't cast here. :(
michael@0 239 return Optional_base<JSObject*, JSObject*>::Construct(
michael@0 240 static_cast<JSObject*>(nullptr));
michael@0 241 }
michael@0 242
michael@0 243 template <class T1>
michael@0 244 JSObject*& Construct(const T1& t1)
michael@0 245 {
michael@0 246 return Optional_base<JSObject*, JSObject*>::Construct(t1);
michael@0 247 }
michael@0 248 };
michael@0 249
michael@0 250 // A specialization of Optional for JS::Value to make sure no one ever uses it.
michael@0 251 template<>
michael@0 252 class Optional<JS::Value>
michael@0 253 {
michael@0 254 private:
michael@0 255 Optional() MOZ_DELETE;
michael@0 256
michael@0 257 explicit Optional(JS::Value aValue) MOZ_DELETE;
michael@0 258 };
michael@0 259
michael@0 260 // A specialization of Optional for NonNull that lets us get a T& from Value()
michael@0 261 template<typename U> class NonNull;
michael@0 262 template<typename T>
michael@0 263 class Optional<NonNull<T> > : public Optional_base<T, NonNull<T> >
michael@0 264 {
michael@0 265 public:
michael@0 266 // We want our Value to actually return a non-const reference, even
michael@0 267 // if we're const. At least for things that are normally pointer
michael@0 268 // types...
michael@0 269 T& Value() const
michael@0 270 {
michael@0 271 return *this->mImpl.ref().get();
michael@0 272 }
michael@0 273
michael@0 274 // And we have to override the non-const one too, since we're
michael@0 275 // shadowing the one on the superclass.
michael@0 276 NonNull<T>& Value()
michael@0 277 {
michael@0 278 return this->mImpl.ref();
michael@0 279 }
michael@0 280 };
michael@0 281
michael@0 282 // A specialization of Optional for OwningNonNull that lets us get a
michael@0 283 // T& from Value()
michael@0 284 template<typename T>
michael@0 285 class Optional<OwningNonNull<T> > : public Optional_base<T, OwningNonNull<T> >
michael@0 286 {
michael@0 287 public:
michael@0 288 // We want our Value to actually return a non-const reference, even
michael@0 289 // if we're const. At least for things that are normally pointer
michael@0 290 // types...
michael@0 291 T& Value() const
michael@0 292 {
michael@0 293 return *this->mImpl.ref().get();
michael@0 294 }
michael@0 295
michael@0 296 // And we have to override the non-const one too, since we're
michael@0 297 // shadowing the one on the superclass.
michael@0 298 OwningNonNull<T>& Value()
michael@0 299 {
michael@0 300 return this->mImpl.ref();
michael@0 301 }
michael@0 302 };
michael@0 303
michael@0 304 // Specialization for strings.
michael@0 305 // XXXbz we can't pull in FakeDependentString here, because it depends on
michael@0 306 // internal strings. So we just have to forward-declare it and reimplement its
michael@0 307 // ToAStringPtr.
michael@0 308
michael@0 309 namespace binding_detail {
michael@0 310 struct FakeDependentString;
michael@0 311 } // namespace binding_detail
michael@0 312
michael@0 313 template<>
michael@0 314 class Optional<nsAString>
michael@0 315 {
michael@0 316 public:
michael@0 317 Optional() : mPassed(false) {}
michael@0 318
michael@0 319 bool WasPassed() const
michael@0 320 {
michael@0 321 return mPassed;
michael@0 322 }
michael@0 323
michael@0 324 void operator=(const nsAString* str)
michael@0 325 {
michael@0 326 MOZ_ASSERT(str);
michael@0 327 mStr = str;
michael@0 328 mPassed = true;
michael@0 329 }
michael@0 330
michael@0 331 // If this code ever goes away, remove the comment pointing to it in the
michael@0 332 // FakeDependentString class in BindingUtils.h.
michael@0 333 void operator=(const binding_detail::FakeDependentString* str)
michael@0 334 {
michael@0 335 MOZ_ASSERT(str);
michael@0 336 mStr = reinterpret_cast<const nsDependentString*>(str);
michael@0 337 mPassed = true;
michael@0 338 }
michael@0 339
michael@0 340 const nsAString& Value() const
michael@0 341 {
michael@0 342 MOZ_ASSERT(WasPassed());
michael@0 343 return *mStr;
michael@0 344 }
michael@0 345
michael@0 346 private:
michael@0 347 // Forbid copy-construction and assignment
michael@0 348 Optional(const Optional& other) MOZ_DELETE;
michael@0 349 const Optional &operator=(const Optional &other) MOZ_DELETE;
michael@0 350
michael@0 351 bool mPassed;
michael@0 352 const nsAString* mStr;
michael@0 353 };
michael@0 354
michael@0 355 template<class T>
michael@0 356 class NonNull
michael@0 357 {
michael@0 358 public:
michael@0 359 NonNull()
michael@0 360 #ifdef DEBUG
michael@0 361 : inited(false)
michael@0 362 #endif
michael@0 363 {}
michael@0 364
michael@0 365 operator T&() {
michael@0 366 MOZ_ASSERT(inited);
michael@0 367 MOZ_ASSERT(ptr, "NonNull<T> was set to null");
michael@0 368 return *ptr;
michael@0 369 }
michael@0 370
michael@0 371 operator const T&() const {
michael@0 372 MOZ_ASSERT(inited);
michael@0 373 MOZ_ASSERT(ptr, "NonNull<T> was set to null");
michael@0 374 return *ptr;
michael@0 375 }
michael@0 376
michael@0 377 operator T*() {
michael@0 378 MOZ_ASSERT(inited);
michael@0 379 MOZ_ASSERT(ptr, "NonNull<T> was set to null");
michael@0 380 return ptr;
michael@0 381 }
michael@0 382
michael@0 383 void operator=(T* t) {
michael@0 384 ptr = t;
michael@0 385 MOZ_ASSERT(ptr);
michael@0 386 #ifdef DEBUG
michael@0 387 inited = true;
michael@0 388 #endif
michael@0 389 }
michael@0 390
michael@0 391 template<typename U>
michael@0 392 void operator=(U* t) {
michael@0 393 ptr = t->ToAStringPtr();
michael@0 394 MOZ_ASSERT(ptr);
michael@0 395 #ifdef DEBUG
michael@0 396 inited = true;
michael@0 397 #endif
michael@0 398 }
michael@0 399
michael@0 400 T** Slot() {
michael@0 401 #ifdef DEBUG
michael@0 402 inited = true;
michael@0 403 #endif
michael@0 404 return &ptr;
michael@0 405 }
michael@0 406
michael@0 407 T* Ptr() {
michael@0 408 MOZ_ASSERT(inited);
michael@0 409 MOZ_ASSERT(ptr, "NonNull<T> was set to null");
michael@0 410 return ptr;
michael@0 411 }
michael@0 412
michael@0 413 // Make us work with smart-ptr helpers that expect a get()
michael@0 414 T* get() const {
michael@0 415 MOZ_ASSERT(inited);
michael@0 416 MOZ_ASSERT(ptr);
michael@0 417 return ptr;
michael@0 418 }
michael@0 419
michael@0 420 protected:
michael@0 421 T* ptr;
michael@0 422 #ifdef DEBUG
michael@0 423 bool inited;
michael@0 424 #endif
michael@0 425 };
michael@0 426
michael@0 427 // Class for representing sequences in arguments. We use a non-auto array
michael@0 428 // because that allows us to use sequences of sequences and the like. This
michael@0 429 // needs to be fallible because web content controls the length of the array,
michael@0 430 // and can easily try to create very large lengths.
michael@0 431 template<typename T>
michael@0 432 class Sequence : public FallibleTArray<T>
michael@0 433 {
michael@0 434 public:
michael@0 435 Sequence() : FallibleTArray<T>()
michael@0 436 {}
michael@0 437 };
michael@0 438
michael@0 439 inline nsWrapperCache*
michael@0 440 GetWrapperCache(nsWrapperCache* cache)
michael@0 441 {
michael@0 442 return cache;
michael@0 443 }
michael@0 444
michael@0 445 inline nsWrapperCache*
michael@0 446 GetWrapperCache(void* p)
michael@0 447 {
michael@0 448 return nullptr;
michael@0 449 }
michael@0 450
michael@0 451 // Helper template for smart pointers to resolve ambiguity between
michael@0 452 // GetWrappeCache(void*) and GetWrapperCache(const ParentObject&).
michael@0 453 template <template <typename> class SmartPtr, typename T>
michael@0 454 inline nsWrapperCache*
michael@0 455 GetWrapperCache(const SmartPtr<T>& aObject)
michael@0 456 {
michael@0 457 return GetWrapperCache(aObject.get());
michael@0 458 }
michael@0 459
michael@0 460 struct ParentObject {
michael@0 461 template<class T>
michael@0 462 ParentObject(T* aObject) :
michael@0 463 mObject(aObject),
michael@0 464 mWrapperCache(GetWrapperCache(aObject)),
michael@0 465 mUseXBLScope(false)
michael@0 466 {}
michael@0 467
michael@0 468 template<class T, template<typename> class SmartPtr>
michael@0 469 ParentObject(const SmartPtr<T>& aObject) :
michael@0 470 mObject(aObject.get()),
michael@0 471 mWrapperCache(GetWrapperCache(aObject.get())),
michael@0 472 mUseXBLScope(false)
michael@0 473 {}
michael@0 474
michael@0 475 ParentObject(nsISupports* aObject, nsWrapperCache* aCache) :
michael@0 476 mObject(aObject),
michael@0 477 mWrapperCache(aCache),
michael@0 478 mUseXBLScope(false)
michael@0 479 {}
michael@0 480
michael@0 481 nsISupports* const mObject;
michael@0 482 nsWrapperCache* const mWrapperCache;
michael@0 483 bool mUseXBLScope;
michael@0 484 };
michael@0 485
michael@0 486 } // namespace dom
michael@0 487 } // namespace mozilla
michael@0 488
michael@0 489 #endif // mozilla_dom_BindingDeclarations_h__

mercurial