Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dom/bindings/KeyframeEffectBinding.cpp
Line
Count
Source (jump to first uncovered line)
1
/* THIS FILE IS AUTOGENERATED FROM KeyframeEffect.webidl BY Codegen.py - DO NOT EDIT */
2
3
#include "AnimationEffectBinding.h"
4
#include "AtomList.h"
5
#include "KeyframeEffectBinding.h"
6
#include "WrapperFactory.h"
7
#include "jsapi.h"
8
#include "mozilla/FloatingPoint.h"
9
#include "mozilla/OwningNonNull.h"
10
#include "mozilla/Preferences.h"
11
#include "mozilla/dom/BindingUtils.h"
12
#include "mozilla/dom/CSSPseudoElement.h"
13
#include "mozilla/dom/DOMJSClass.h"
14
#include "mozilla/dom/Element.h"
15
#include "mozilla/dom/KeyframeEffect.h"
16
#include "mozilla/dom/NonRefcountedDOMObject.h"
17
#include "mozilla/dom/Nullable.h"
18
#include "mozilla/dom/PrimitiveConversions.h"
19
#include "mozilla/dom/ScriptSettings.h"
20
#include "mozilla/dom/SimpleGlobalObject.h"
21
#include "mozilla/dom/UnionConversions.h"
22
#include "mozilla/dom/XrayExpandoClass.h"
23
#include "nsContentUtils.h"
24
#include "nsDocument.h"
25
26
namespace mozilla {
27
namespace dom {
28
29
namespace binding_detail {}; // Just to make sure it's known as a namespace
30
using namespace mozilla::dom::binding_detail;
31
32
33
namespace IterationCompositeOperationValues {
34
extern const EnumEntry strings[3] = {
35
  {"replace", 7},
36
  {"accumulate", 10},
37
  { nullptr, 0 }
38
};
39
} // namespace IterationCompositeOperationValues
40
41
bool
42
ToJSValue(JSContext* aCx, IterationCompositeOperation aArgument, JS::MutableHandle<JS::Value> aValue)
43
0
{
44
0
  MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(IterationCompositeOperationValues::strings));
45
0
  JSString* resultStr =
46
0
    JS_NewStringCopyN(aCx, IterationCompositeOperationValues::strings[uint32_t(aArgument)].value,
47
0
                      IterationCompositeOperationValues::strings[uint32_t(aArgument)].length);
48
0
  if (!resultStr) {
49
0
    return false;
50
0
  }
51
0
  aValue.setString(resultStr);
52
0
  return true;
53
0
}
54
55
56
void
57
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningElementOrCSSPseudoElement& aUnion, const char* aName, uint32_t aFlags)
58
0
{
59
0
  if (aUnion.IsElement()) {
60
0
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsElement(), "mElement", aFlags);
61
0
  } else if (aUnion.IsCSSPseudoElement()) {
62
0
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsCSSPseudoElement(), "mCSSPseudoElement", aFlags);
63
0
  }
64
0
}
65
66
67
void
68
ImplCycleCollectionUnlink(OwningElementOrCSSPseudoElement& aUnion)
69
0
{
70
0
  aUnion.Uninit();
71
0
}
72
73
74
75
AnimationPropertyValueDetails::AnimationPropertyValueDetails()
76
0
{
77
0
  // Safe to pass a null context if we pass a null value
78
0
  Init(nullptr, JS::NullHandleValue);
79
0
}
80
81
82
83
bool
84
AnimationPropertyValueDetails::InitIds(JSContext* cx, AnimationPropertyValueDetailsAtoms* atomsCache)
85
0
{
86
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
87
0
88
0
  // Initialize these in reverse order so that any failure leaves the first one
89
0
  // uninitialized.
90
0
  if (!atomsCache->value_id.init(cx, "value") ||
91
0
      !atomsCache->offset_id.init(cx, "offset") ||
92
0
      !atomsCache->easing_id.init(cx, "easing") ||
93
0
      !atomsCache->composite_id.init(cx, "composite")) {
94
0
    return false;
95
0
  }
96
0
  return true;
97
0
}
98
99
bool
100
AnimationPropertyValueDetails::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
101
0
{
102
0
  // Passing a null JSContext is OK only if we're initing from null,
103
0
  // Since in that case we will not have to do any property gets
104
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
105
0
  // checkers by static analysis tools
106
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
107
0
  AnimationPropertyValueDetailsAtoms* atomsCache = nullptr;
108
0
  if (cx) {
109
0
    atomsCache = GetAtomCache<AnimationPropertyValueDetailsAtoms>(cx);
110
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
111
0
      return false;
112
0
    }
113
0
  }
114
0
115
0
  if (!IsConvertibleToDictionary(val)) {
116
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
117
0
  }
118
0
119
0
  bool isNull = val.isNullOrUndefined();
120
0
  // We only need these if !isNull, in which case we have |cx|.
121
0
  Maybe<JS::Rooted<JSObject *> > object;
122
0
  Maybe<JS::Rooted<JS::Value> > temp;
123
0
  if (!isNull) {
124
0
    MOZ_ASSERT(cx);
125
0
    object.emplace(cx, &val.toObject());
126
0
    temp.emplace(cx);
127
0
  }
128
0
  if (!isNull) {
129
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->composite_id, temp.ptr())) {
130
0
      return false;
131
0
    }
132
0
  }
133
0
  if (!isNull && !temp->isUndefined()) {
134
0
    {
135
0
      int index;
136
0
      if (!FindEnumStringIndex<true>(cx, temp.ref(), CompositeOperationValues::strings, "CompositeOperation", "'composite' member of AnimationPropertyValueDetails", &index)) {
137
0
        return false;
138
0
      }
139
0
      MOZ_ASSERT(index >= 0);
140
0
      mComposite = static_cast<CompositeOperation>(index);
141
0
    }
142
0
    mIsAnyMemberPresent = true;
143
0
  } else if (cx) {
144
0
    // Don't error out if we have no cx.  In that
145
0
    // situation the caller is default-constructing us and we'll
146
0
    // just assume they know what they're doing.
147
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
148
0
                             "'composite' member of AnimationPropertyValueDetails");
149
0
  }
150
0
151
0
  if (!isNull) {
152
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->easing_id, temp.ptr())) {
153
0
      return false;
154
0
    }
155
0
  }
156
0
  if (!isNull && !temp->isUndefined()) {
157
0
    mEasing.Construct();
158
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mEasing.Value()))) {
159
0
      return false;
160
0
    }
161
0
    mIsAnyMemberPresent = true;
162
0
  }
163
0
164
0
  if (!isNull) {
165
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->offset_id, temp.ptr())) {
166
0
      return false;
167
0
    }
168
0
  }
169
0
  if (!isNull && !temp->isUndefined()) {
170
0
    if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &mOffset)) {
171
0
      return false;
172
0
    } else if (!mozilla::IsFinite(mOffset)) {
173
0
      ThrowErrorMessage(cx, MSG_NOT_FINITE, "'offset' member of AnimationPropertyValueDetails");
174
0
      return false;
175
0
    }
176
0
    mIsAnyMemberPresent = true;
177
0
  } else if (cx) {
178
0
    // Don't error out if we have no cx.  In that
179
0
    // situation the caller is default-constructing us and we'll
180
0
    // just assume they know what they're doing.
181
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
182
0
                             "'offset' member of AnimationPropertyValueDetails");
183
0
  }
184
0
185
0
  if (!isNull) {
186
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->value_id, temp.ptr())) {
187
0
      return false;
188
0
    }
189
0
  }
190
0
  if (!isNull && !temp->isUndefined()) {
191
0
    mValue.Construct();
192
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mValue.Value()))) {
193
0
      return false;
194
0
    }
195
0
    mIsAnyMemberPresent = true;
196
0
  }
197
0
  return true;
198
0
}
199
200
bool
201
AnimationPropertyValueDetails::Init(const nsAString& aJSON)
202
0
{
203
0
  AutoJSAPI jsapi;
204
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
205
0
  if (!cleanGlobal) {
206
0
    return false;
207
0
  }
208
0
  if (!jsapi.Init(cleanGlobal)) {
209
0
    return false;
210
0
  }
211
0
  JSContext* cx = jsapi.cx();
212
0
  JS::Rooted<JS::Value> json(cx);
213
0
  bool ok = ParseJSON(cx, aJSON, &json);
214
0
  NS_ENSURE_TRUE(ok, false);
215
0
  return Init(cx, json);
216
0
}
217
218
bool
219
AnimationPropertyValueDetails::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
220
0
{
221
0
  AnimationPropertyValueDetailsAtoms* atomsCache = GetAtomCache<AnimationPropertyValueDetailsAtoms>(cx);
222
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
223
0
    return false;
224
0
  }
225
0
226
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
227
0
  if (!obj) {
228
0
    return false;
229
0
  }
230
0
  rval.set(JS::ObjectValue(*obj));
231
0
232
0
  do {
233
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
234
0
    JS::Rooted<JS::Value> temp(cx);
235
0
    CompositeOperation const & currentValue = mComposite;
236
0
    if (!ToJSValue(cx, currentValue, &temp)) {
237
0
      return false;
238
0
    }
239
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->composite_id, temp, JSPROP_ENUMERATE)) {
240
0
      return false;
241
0
    }
242
0
    break;
243
0
  } while(false);
244
0
245
0
  if (mEasing.WasPassed()) {
246
0
    do {
247
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
248
0
      JS::Rooted<JS::Value> temp(cx);
249
0
      nsString const & currentValue = mEasing.InternalValue();
250
0
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
251
0
        return false;
252
0
      }
253
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->easing_id, temp, JSPROP_ENUMERATE)) {
254
0
        return false;
255
0
      }
256
0
      break;
257
0
    } while(false);
258
0
  }
259
0
260
0
  do {
261
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
262
0
    JS::Rooted<JS::Value> temp(cx);
263
0
    double const & currentValue = mOffset;
264
0
    temp.set(JS_NumberValue(double(currentValue)));
265
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->offset_id, temp, JSPROP_ENUMERATE)) {
266
0
      return false;
267
0
    }
268
0
    break;
269
0
  } while(false);
270
0
271
0
  if (mValue.WasPassed()) {
272
0
    do {
273
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
274
0
      JS::Rooted<JS::Value> temp(cx);
275
0
      nsString const & currentValue = mValue.InternalValue();
276
0
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
277
0
        return false;
278
0
      }
279
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->value_id, temp, JSPROP_ENUMERATE)) {
280
0
        return false;
281
0
      }
282
0
      break;
283
0
    } while(false);
284
0
  }
285
0
286
0
  return true;
287
0
}
288
289
bool
290
AnimationPropertyValueDetails::ToJSON(nsAString& aJSON) const
291
0
{
292
0
  AutoJSAPI jsapi;
293
0
  jsapi.Init();
294
0
  JSContext *cx = jsapi.cx();
295
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
296
0
  // because we'll only be creating objects, in ways that have no
297
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
298
0
  // which likewise guarantees no side-effects for the sorts of
299
0
  // things we will pass it.
300
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
301
0
  JS::Rooted<JS::Value> val(cx);
302
0
  if (!ToObjectInternal(cx, &val)) {
303
0
    return false;
304
0
  }
305
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
306
0
  return StringifyToJSON(cx, obj, aJSON);
307
0
}
308
309
void
310
AnimationPropertyValueDetails::TraceDictionary(JSTracer* trc)
311
0
{
312
0
}
313
314
AnimationPropertyValueDetails&
315
AnimationPropertyValueDetails::operator=(const AnimationPropertyValueDetails& aOther)
316
0
{
317
0
  DictionaryBase::operator=(aOther);
318
0
  mComposite = aOther.mComposite;
319
0
  mEasing.Reset();
320
0
  if (aOther.mEasing.WasPassed()) {
321
0
    mEasing.Construct(aOther.mEasing.Value());
322
0
  }
323
0
  mOffset = aOther.mOffset;
324
0
  mValue.Reset();
325
0
  if (aOther.mValue.WasPassed()) {
326
0
    mValue.Construct(aOther.mValue.Value());
327
0
  }
328
0
  return *this;
329
0
}
330
331
namespace binding_detail {
332
} // namespace binding_detail
333
334
335
bool
336
ElementOrCSSPseudoElement::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
337
0
{
338
0
  switch (mType) {
339
0
    case eUninitialized: {
340
0
      return false;
341
0
      break;
342
0
    }
343
0
    case eElement: {
344
0
      if (!GetOrCreateDOMReflector(cx, mValue.mElement.Value(), rval)) {
345
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
346
0
        return false;
347
0
      }
348
0
      return true;
349
0
      break;
350
0
    }
351
0
    case eCSSPseudoElement: {
352
0
      if (!GetOrCreateDOMReflector(cx, mValue.mCSSPseudoElement.Value(), rval)) {
353
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
354
0
        return false;
355
0
      }
356
0
      return true;
357
0
      break;
358
0
    }
359
0
    default: {
360
0
      return false;
361
0
      break;
362
0
    }
363
0
  }
364
0
365
0
  return false;
366
0
}
367
368
369
OwningNonNull<mozilla::dom::Element>&
370
OwningElementOrCSSPseudoElement::RawSetAsElement()
371
0
{
372
0
  if (mType == eElement) {
373
0
    return mValue.mElement.Value();
374
0
  }
375
0
  MOZ_ASSERT(mType == eUninitialized);
376
0
  mType = eElement;
377
0
  return mValue.mElement.SetValue();
378
0
}
379
380
OwningNonNull<mozilla::dom::Element>&
381
OwningElementOrCSSPseudoElement::SetAsElement()
382
0
{
383
0
  if (mType == eElement) {
384
0
    return mValue.mElement.Value();
385
0
  }
386
0
  Uninit();
387
0
  mType = eElement;
388
0
  return mValue.mElement.SetValue();
389
0
}
390
391
bool
392
OwningElementOrCSSPseudoElement::TrySetToElement(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
393
0
{
394
0
  tryNext = false;
395
0
  { // scope for memberSlot
396
0
    OwningNonNull<mozilla::dom::Element>& memberSlot = RawSetAsElement();
397
0
    static_assert(IsRefcounted<mozilla::dom::Element>::value, "We can only store refcounted classes.");{
398
0
      nsresult rv = UnwrapObject<prototypes::id::Element, mozilla::dom::Element>(value, memberSlot);
399
0
      if (NS_FAILED(rv)) {
400
0
        DestroyElement();
401
0
        tryNext = true;
402
0
        return true;
403
0
      }
404
0
    }
405
0
  }
406
0
  return true;
407
0
}
408
409
void
410
OwningElementOrCSSPseudoElement::DestroyElement()
411
0
{
412
0
  MOZ_ASSERT(IsElement(), "Wrong type!");
413
0
  mValue.mElement.Destroy();
414
0
  mType = eUninitialized;
415
0
}
416
417
418
419
420
OwningNonNull<mozilla::dom::CSSPseudoElement>&
421
OwningElementOrCSSPseudoElement::RawSetAsCSSPseudoElement()
422
0
{
423
0
  if (mType == eCSSPseudoElement) {
424
0
    return mValue.mCSSPseudoElement.Value();
425
0
  }
426
0
  MOZ_ASSERT(mType == eUninitialized);
427
0
  mType = eCSSPseudoElement;
428
0
  return mValue.mCSSPseudoElement.SetValue();
429
0
}
430
431
OwningNonNull<mozilla::dom::CSSPseudoElement>&
432
OwningElementOrCSSPseudoElement::SetAsCSSPseudoElement()
433
0
{
434
0
  if (mType == eCSSPseudoElement) {
435
0
    return mValue.mCSSPseudoElement.Value();
436
0
  }
437
0
  Uninit();
438
0
  mType = eCSSPseudoElement;
439
0
  return mValue.mCSSPseudoElement.SetValue();
440
0
}
441
442
bool
443
OwningElementOrCSSPseudoElement::TrySetToCSSPseudoElement(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
444
0
{
445
0
  tryNext = false;
446
0
  { // scope for memberSlot
447
0
    OwningNonNull<mozilla::dom::CSSPseudoElement>& memberSlot = RawSetAsCSSPseudoElement();
448
0
    static_assert(IsRefcounted<mozilla::dom::CSSPseudoElement>::value, "We can only store refcounted classes.");{
449
0
      nsresult rv = UnwrapObject<prototypes::id::CSSPseudoElement, mozilla::dom::CSSPseudoElement>(value, memberSlot);
450
0
      if (NS_FAILED(rv)) {
451
0
        DestroyCSSPseudoElement();
452
0
        tryNext = true;
453
0
        return true;
454
0
      }
455
0
    }
456
0
  }
457
0
  return true;
458
0
}
459
460
void
461
OwningElementOrCSSPseudoElement::DestroyCSSPseudoElement()
462
0
{
463
0
  MOZ_ASSERT(IsCSSPseudoElement(), "Wrong type!");
464
0
  mValue.mCSSPseudoElement.Destroy();
465
0
  mType = eUninitialized;
466
0
}
467
468
469
470
471
void
472
OwningElementOrCSSPseudoElement::Uninit()
473
{
474
  switch (mType) {
475
    case eUninitialized: {
476
      break;
477
    }
478
    case eElement: {
479
      DestroyElement();
480
      break;
481
    }
482
    case eCSSPseudoElement: {
483
      DestroyCSSPseudoElement();
484
      break;
485
    }
486
  }
487
}
488
489
bool
490
OwningElementOrCSSPseudoElement::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
491
0
{
492
0
  switch (mType) {
493
0
    case eUninitialized: {
494
0
      return false;
495
0
      break;
496
0
    }
497
0
    case eElement: {
498
0
      if (!GetOrCreateDOMReflector(cx, mValue.mElement.Value(), rval)) {
499
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
500
0
        return false;
501
0
      }
502
0
      return true;
503
0
      break;
504
0
    }
505
0
    case eCSSPseudoElement: {
506
0
      if (!GetOrCreateDOMReflector(cx, mValue.mCSSPseudoElement.Value(), rval)) {
507
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
508
0
        return false;
509
0
      }
510
0
      return true;
511
0
      break;
512
0
    }
513
0
    default: {
514
0
      return false;
515
0
      break;
516
0
    }
517
0
  }
518
0
519
0
  return false;
520
0
}
521
522
void
523
OwningElementOrCSSPseudoElement::TraceUnion(JSTracer* trc)
524
0
{
525
0
}
526
527
OwningElementOrCSSPseudoElement&
528
OwningElementOrCSSPseudoElement::operator=(const OwningElementOrCSSPseudoElement& aOther)
529
0
{
530
0
  switch (aOther.mType) {
531
0
    case eUninitialized: {
532
0
      MOZ_ASSERT(mType == eUninitialized,
533
0
                 "We need to destroy ourselves?");
534
0
      break;
535
0
    }
536
0
    case eElement: {
537
0
      SetAsElement() = aOther.GetAsElement();
538
0
      break;
539
0
    }
540
0
    case eCSSPseudoElement: {
541
0
      SetAsCSSPseudoElement() = aOther.GetAsCSSPseudoElement();
542
0
      break;
543
0
    }
544
0
  }
545
0
  return *this;
546
0
}
547
548
549
550
KeyframeEffectOptions::KeyframeEffectOptions()
551
  : EffectTiming(FastDictionaryInitializer())
552
0
{
553
0
  // Safe to pass a null context if we pass a null value
554
0
  Init(nullptr, JS::NullHandleValue);
555
0
}
556
557
558
559
bool
560
KeyframeEffectOptions::InitIds(JSContext* cx, KeyframeEffectOptionsAtoms* atomsCache)
561
0
{
562
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
563
0
564
0
  // Initialize these in reverse order so that any failure leaves the first one
565
0
  // uninitialized.
566
0
  if (!atomsCache->iterationComposite_id.init(cx, "iterationComposite") ||
567
0
      !atomsCache->composite_id.init(cx, "composite")) {
568
0
    return false;
569
0
  }
570
0
  return true;
571
0
}
572
573
bool
574
KeyframeEffectOptions::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
575
0
{
576
0
  // Passing a null JSContext is OK only if we're initing from null,
577
0
  // Since in that case we will not have to do any property gets
578
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
579
0
  // checkers by static analysis tools
580
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
581
0
  KeyframeEffectOptionsAtoms* atomsCache = nullptr;
582
0
  if (cx) {
583
0
    atomsCache = GetAtomCache<KeyframeEffectOptionsAtoms>(cx);
584
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
585
0
      return false;
586
0
    }
587
0
  }
588
0
589
0
  // Per spec, we init the parent's members first
590
0
  if (!EffectTiming::Init(cx, val)) {
591
0
    return false;
592
0
  }
593
0
594
0
  bool isNull = val.isNullOrUndefined();
595
0
  // We only need these if !isNull, in which case we have |cx|.
596
0
  Maybe<JS::Rooted<JSObject *> > object;
597
0
  Maybe<JS::Rooted<JS::Value> > temp;
598
0
  if (!isNull) {
599
0
    MOZ_ASSERT(cx);
600
0
    object.emplace(cx, &val.toObject());
601
0
    temp.emplace(cx);
602
0
  }
603
0
  if (!isNull) {
604
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->composite_id, temp.ptr())) {
605
0
      return false;
606
0
    }
607
0
  }
608
0
  if (!isNull && !temp->isUndefined()) {
609
0
    {
610
0
      int index;
611
0
      if (!FindEnumStringIndex<true>(cx, temp.ref(), CompositeOperationValues::strings, "CompositeOperation", "'composite' member of KeyframeEffectOptions", &index)) {
612
0
        return false;
613
0
      }
614
0
      MOZ_ASSERT(index >= 0);
615
0
      mComposite = static_cast<CompositeOperation>(index);
616
0
    }
617
0
  } else {
618
0
    mComposite = CompositeOperation::Replace;
619
0
  }
620
0
  mIsAnyMemberPresent = true;
621
0
622
0
  if (!isNull) {
623
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->iterationComposite_id, temp.ptr())) {
624
0
      return false;
625
0
    }
626
0
  }
627
0
  if (!isNull && !temp->isUndefined()) {
628
0
    {
629
0
      int index;
630
0
      if (!FindEnumStringIndex<true>(cx, temp.ref(), IterationCompositeOperationValues::strings, "IterationCompositeOperation", "'iterationComposite' member of KeyframeEffectOptions", &index)) {
631
0
        return false;
632
0
      }
633
0
      MOZ_ASSERT(index >= 0);
634
0
      mIterationComposite = static_cast<IterationCompositeOperation>(index);
635
0
    }
636
0
  } else {
637
0
    mIterationComposite = IterationCompositeOperation::Replace;
638
0
  }
639
0
  mIsAnyMemberPresent = true;
640
0
  return true;
641
0
}
642
643
bool
644
KeyframeEffectOptions::Init(const nsAString& aJSON)
645
0
{
646
0
  AutoJSAPI jsapi;
647
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
648
0
  if (!cleanGlobal) {
649
0
    return false;
650
0
  }
651
0
  if (!jsapi.Init(cleanGlobal)) {
652
0
    return false;
653
0
  }
654
0
  JSContext* cx = jsapi.cx();
655
0
  JS::Rooted<JS::Value> json(cx);
656
0
  bool ok = ParseJSON(cx, aJSON, &json);
657
0
  NS_ENSURE_TRUE(ok, false);
658
0
  return Init(cx, json);
659
0
}
660
661
bool
662
KeyframeEffectOptions::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
663
0
{
664
0
  KeyframeEffectOptionsAtoms* atomsCache = GetAtomCache<KeyframeEffectOptionsAtoms>(cx);
665
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
666
0
    return false;
667
0
  }
668
0
669
0
  // Per spec, we define the parent's members first
670
0
  if (!EffectTiming::ToObjectInternal(cx, rval)) {
671
0
    return false;
672
0
  }
673
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
674
0
675
0
  do {
676
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
677
0
    JS::Rooted<JS::Value> temp(cx);
678
0
    CompositeOperation const & currentValue = mComposite;
679
0
    if (!ToJSValue(cx, currentValue, &temp)) {
680
0
      return false;
681
0
    }
682
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->composite_id, temp, JSPROP_ENUMERATE)) {
683
0
      return false;
684
0
    }
685
0
    break;
686
0
  } while(false);
687
0
688
0
  do {
689
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
690
0
    JS::Rooted<JS::Value> temp(cx);
691
0
    IterationCompositeOperation const & currentValue = mIterationComposite;
692
0
    if (!ToJSValue(cx, currentValue, &temp)) {
693
0
      return false;
694
0
    }
695
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->iterationComposite_id, temp, JSPROP_ENUMERATE)) {
696
0
      return false;
697
0
    }
698
0
    break;
699
0
  } while(false);
700
0
701
0
  return true;
702
0
}
703
704
bool
705
KeyframeEffectOptions::ToJSON(nsAString& aJSON) const
706
0
{
707
0
  AutoJSAPI jsapi;
708
0
  jsapi.Init();
709
0
  JSContext *cx = jsapi.cx();
710
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
711
0
  // because we'll only be creating objects, in ways that have no
712
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
713
0
  // which likewise guarantees no side-effects for the sorts of
714
0
  // things we will pass it.
715
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
716
0
  JS::Rooted<JS::Value> val(cx);
717
0
  if (!ToObjectInternal(cx, &val)) {
718
0
    return false;
719
0
  }
720
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
721
0
  return StringifyToJSON(cx, obj, aJSON);
722
0
}
723
724
void
725
KeyframeEffectOptions::TraceDictionary(JSTracer* trc)
726
0
{
727
0
  EffectTiming::TraceDictionary(trc);
728
0
}
729
730
KeyframeEffectOptions&
731
KeyframeEffectOptions::operator=(const KeyframeEffectOptions& aOther)
732
0
{
733
0
  EffectTiming::operator=(aOther);
734
0
  mComposite = aOther.mComposite;
735
0
  mIterationComposite = aOther.mIterationComposite;
736
0
  return *this;
737
0
}
738
739
namespace binding_detail {
740
} // namespace binding_detail
741
742
743
744
AnimationPropertyDetails::AnimationPropertyDetails()
745
0
{
746
0
  // Safe to pass a null context if we pass a null value
747
0
  Init(nullptr, JS::NullHandleValue);
748
0
}
749
750
751
752
bool
753
AnimationPropertyDetails::InitIds(JSContext* cx, AnimationPropertyDetailsAtoms* atomsCache)
754
0
{
755
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
756
0
757
0
  // Initialize these in reverse order so that any failure leaves the first one
758
0
  // uninitialized.
759
0
  if (!atomsCache->warning_id.init(cx, "warning") ||
760
0
      !atomsCache->values_id.init(cx, "values") ||
761
0
      !atomsCache->runningOnCompositor_id.init(cx, "runningOnCompositor") ||
762
0
      !atomsCache->property_id.init(cx, "property")) {
763
0
    return false;
764
0
  }
765
0
  return true;
766
0
}
767
768
bool
769
AnimationPropertyDetails::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
770
0
{
771
0
  // Passing a null JSContext is OK only if we're initing from null,
772
0
  // Since in that case we will not have to do any property gets
773
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
774
0
  // checkers by static analysis tools
775
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
776
0
  AnimationPropertyDetailsAtoms* atomsCache = nullptr;
777
0
  if (cx) {
778
0
    atomsCache = GetAtomCache<AnimationPropertyDetailsAtoms>(cx);
779
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
780
0
      return false;
781
0
    }
782
0
  }
783
0
784
0
  if (!IsConvertibleToDictionary(val)) {
785
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
786
0
  }
787
0
788
0
  bool isNull = val.isNullOrUndefined();
789
0
  // We only need these if !isNull, in which case we have |cx|.
790
0
  Maybe<JS::Rooted<JSObject *> > object;
791
0
  Maybe<JS::Rooted<JS::Value> > temp;
792
0
  if (!isNull) {
793
0
    MOZ_ASSERT(cx);
794
0
    object.emplace(cx, &val.toObject());
795
0
    temp.emplace(cx);
796
0
  }
797
0
  if (!isNull) {
798
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->property_id, temp.ptr())) {
799
0
      return false;
800
0
    }
801
0
  }
802
0
  if (!isNull && !temp->isUndefined()) {
803
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mProperty)) {
804
0
      return false;
805
0
    }
806
0
    mIsAnyMemberPresent = true;
807
0
  } else if (cx) {
808
0
    // Don't error out if we have no cx.  In that
809
0
    // situation the caller is default-constructing us and we'll
810
0
    // just assume they know what they're doing.
811
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
812
0
                             "'property' member of AnimationPropertyDetails");
813
0
  }
814
0
815
0
  if (!isNull) {
816
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->runningOnCompositor_id, temp.ptr())) {
817
0
      return false;
818
0
    }
819
0
  }
820
0
  if (!isNull && !temp->isUndefined()) {
821
0
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mRunningOnCompositor)) {
822
0
      return false;
823
0
    }
824
0
    mIsAnyMemberPresent = true;
825
0
  } else if (cx) {
826
0
    // Don't error out if we have no cx.  In that
827
0
    // situation the caller is default-constructing us and we'll
828
0
    // just assume they know what they're doing.
829
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
830
0
                             "'runningOnCompositor' member of AnimationPropertyDetails");
831
0
  }
832
0
833
0
  if (!isNull) {
834
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->values_id, temp.ptr())) {
835
0
      return false;
836
0
    }
837
0
  }
838
0
  if (!isNull && !temp->isUndefined()) {
839
0
    if (temp.ref().isObject()) {
840
0
      JS::ForOfIterator iter(cx);
841
0
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
842
0
        return false;
843
0
      }
844
0
      if (!iter.valueIsIterable()) {
845
0
        ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'values' member of AnimationPropertyDetails");
846
0
        return false;
847
0
      }
848
0
      Sequence<AnimationPropertyValueDetails> &arr = mValues;
849
0
      JS::Rooted<JS::Value> temp(cx);
850
0
      while (true) {
851
0
        bool done;
852
0
        if (!iter.next(&temp, &done)) {
853
0
          return false;
854
0
        }
855
0
        if (done) {
856
0
          break;
857
0
        }
858
0
        AnimationPropertyValueDetails* slotPtr = arr.AppendElement(mozilla::fallible);
859
0
        if (!slotPtr) {
860
0
          JS_ReportOutOfMemory(cx);
861
0
          return false;
862
0
        }
863
0
        AnimationPropertyValueDetails& slot = *slotPtr;
864
0
        if (!slot.Init(cx, temp,  "Element of 'values' member of AnimationPropertyDetails", passedToJSImpl)) {
865
0
          return false;
866
0
        }
867
0
      }
868
0
    } else {
869
0
      ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'values' member of AnimationPropertyDetails");
870
0
      return false;
871
0
    }
872
0
    mIsAnyMemberPresent = true;
873
0
  } else if (cx) {
874
0
    // Don't error out if we have no cx.  In that
875
0
    // situation the caller is default-constructing us and we'll
876
0
    // just assume they know what they're doing.
877
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
878
0
                             "'values' member of AnimationPropertyDetails");
879
0
  }
880
0
881
0
  if (!isNull) {
882
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->warning_id, temp.ptr())) {
883
0
      return false;
884
0
    }
885
0
  }
886
0
  if (!isNull && !temp->isUndefined()) {
887
0
    mWarning.Construct();
888
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mWarning.Value()))) {
889
0
      return false;
890
0
    }
891
0
    mIsAnyMemberPresent = true;
892
0
  }
893
0
  return true;
894
0
}
895
896
bool
897
AnimationPropertyDetails::Init(const nsAString& aJSON)
898
0
{
899
0
  AutoJSAPI jsapi;
900
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
901
0
  if (!cleanGlobal) {
902
0
    return false;
903
0
  }
904
0
  if (!jsapi.Init(cleanGlobal)) {
905
0
    return false;
906
0
  }
907
0
  JSContext* cx = jsapi.cx();
908
0
  JS::Rooted<JS::Value> json(cx);
909
0
  bool ok = ParseJSON(cx, aJSON, &json);
910
0
  NS_ENSURE_TRUE(ok, false);
911
0
  return Init(cx, json);
912
0
}
913
914
bool
915
AnimationPropertyDetails::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
916
0
{
917
0
  AnimationPropertyDetailsAtoms* atomsCache = GetAtomCache<AnimationPropertyDetailsAtoms>(cx);
918
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
919
0
    return false;
920
0
  }
921
0
922
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
923
0
  if (!obj) {
924
0
    return false;
925
0
  }
926
0
  rval.set(JS::ObjectValue(*obj));
927
0
928
0
  do {
929
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
930
0
    JS::Rooted<JS::Value> temp(cx);
931
0
    nsString const & currentValue = mProperty;
932
0
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
933
0
      return false;
934
0
    }
935
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->property_id, temp, JSPROP_ENUMERATE)) {
936
0
      return false;
937
0
    }
938
0
    break;
939
0
  } while(false);
940
0
941
0
  do {
942
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
943
0
    JS::Rooted<JS::Value> temp(cx);
944
0
    bool const & currentValue = mRunningOnCompositor;
945
0
    temp.setBoolean(currentValue);
946
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->runningOnCompositor_id, temp, JSPROP_ENUMERATE)) {
947
0
      return false;
948
0
    }
949
0
    break;
950
0
  } while(false);
951
0
952
0
  do {
953
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
954
0
    JS::Rooted<JS::Value> temp(cx);
955
0
    Sequence<AnimationPropertyValueDetails> const & currentValue = mValues;
956
0
957
0
    uint32_t length = currentValue.Length();
958
0
    JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
959
0
    if (!returnArray) {
960
0
      return false;
961
0
    }
962
0
    // Scope for 'tmp'
963
0
    {
964
0
      JS::Rooted<JS::Value> tmp(cx);
965
0
      for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
966
0
        // Control block to let us common up the JS_DefineElement calls when there
967
0
        // are different ways to succeed at wrapping the object.
968
0
        do {
969
0
          if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
970
0
            return false;
971
0
          }
972
0
          break;
973
0
        } while (false);
974
0
        if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
975
0
                              JSPROP_ENUMERATE)) {
976
0
          return false;
977
0
        }
978
0
      }
979
0
    }
980
0
    temp.setObject(*returnArray);
981
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->values_id, temp, JSPROP_ENUMERATE)) {
982
0
      return false;
983
0
    }
984
0
    break;
985
0
  } while(false);
986
0
987
0
  if (mWarning.WasPassed()) {
988
0
    do {
989
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
990
0
      JS::Rooted<JS::Value> temp(cx);
991
0
      nsString const & currentValue = mWarning.InternalValue();
992
0
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
993
0
        return false;
994
0
      }
995
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->warning_id, temp, JSPROP_ENUMERATE)) {
996
0
        return false;
997
0
      }
998
0
      break;
999
0
    } while(false);
1000
0
  }
1001
0
1002
0
  return true;
1003
0
}
1004
1005
bool
1006
AnimationPropertyDetails::ToJSON(nsAString& aJSON) const
1007
0
{
1008
0
  AutoJSAPI jsapi;
1009
0
  jsapi.Init();
1010
0
  JSContext *cx = jsapi.cx();
1011
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
1012
0
  // because we'll only be creating objects, in ways that have no
1013
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
1014
0
  // which likewise guarantees no side-effects for the sorts of
1015
0
  // things we will pass it.
1016
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
1017
0
  JS::Rooted<JS::Value> val(cx);
1018
0
  if (!ToObjectInternal(cx, &val)) {
1019
0
    return false;
1020
0
  }
1021
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
1022
0
  return StringifyToJSON(cx, obj, aJSON);
1023
0
}
1024
1025
void
1026
AnimationPropertyDetails::TraceDictionary(JSTracer* trc)
1027
0
{
1028
0
}
1029
1030
AnimationPropertyDetails&
1031
AnimationPropertyDetails::operator=(const AnimationPropertyDetails& aOther)
1032
0
{
1033
0
  DictionaryBase::operator=(aOther);
1034
0
  mProperty = aOther.mProperty;
1035
0
  mRunningOnCompositor = aOther.mRunningOnCompositor;
1036
0
  mValues = aOther.mValues;
1037
0
  mWarning.Reset();
1038
0
  if (aOther.mWarning.WasPassed()) {
1039
0
    mWarning.Construct(aOther.mWarning.Value());
1040
0
  }
1041
0
  return *this;
1042
0
}
1043
1044
namespace binding_detail {
1045
} // namespace binding_detail
1046
1047
1048
bool
1049
UnrestrictedDoubleOrKeyframeEffectOptions::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
1050
0
{
1051
0
  switch (mType) {
1052
0
    case eUninitialized: {
1053
0
      return false;
1054
0
      break;
1055
0
    }
1056
0
    case eUnrestrictedDouble: {
1057
0
      rval.set(JS_NumberValue(double(mValue.mUnrestrictedDouble.Value())));
1058
0
      return true;
1059
0
      break;
1060
0
    }
1061
0
    case eKeyframeEffectOptions: {
1062
0
      if (!mValue.mKeyframeEffectOptions.Value().ToObjectInternal(cx, rval)) {
1063
0
        return false;
1064
0
      }
1065
0
      return true;
1066
0
      break;
1067
0
    }
1068
0
    default: {
1069
0
      return false;
1070
0
      break;
1071
0
    }
1072
0
  }
1073
0
1074
0
  return false;
1075
0
}
1076
1077
1078
double&
1079
OwningUnrestrictedDoubleOrKeyframeEffectOptions::RawSetAsUnrestrictedDouble()
1080
0
{
1081
0
  if (mType == eUnrestrictedDouble) {
1082
0
    return mValue.mUnrestrictedDouble.Value();
1083
0
  }
1084
0
  MOZ_ASSERT(mType == eUninitialized);
1085
0
  mType = eUnrestrictedDouble;
1086
0
  return mValue.mUnrestrictedDouble.SetValue();
1087
0
}
1088
1089
double&
1090
OwningUnrestrictedDoubleOrKeyframeEffectOptions::SetAsUnrestrictedDouble()
1091
0
{
1092
0
  if (mType == eUnrestrictedDouble) {
1093
0
    return mValue.mUnrestrictedDouble.Value();
1094
0
  }
1095
0
  Uninit();
1096
0
  mType = eUnrestrictedDouble;
1097
0
  return mValue.mUnrestrictedDouble.SetValue();
1098
0
}
1099
1100
bool
1101
OwningUnrestrictedDoubleOrKeyframeEffectOptions::TrySetToUnrestrictedDouble(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
1102
0
{
1103
0
  tryNext = false;
1104
0
  { // scope for memberSlot
1105
0
    double& memberSlot = RawSetAsUnrestrictedDouble();
1106
0
    if (!ValueToPrimitive<double, eDefault>(cx, value, &memberSlot)) {
1107
0
      return false;
1108
0
    }
1109
0
  }
1110
0
  return true;
1111
0
}
1112
1113
void
1114
OwningUnrestrictedDoubleOrKeyframeEffectOptions::DestroyUnrestrictedDouble()
1115
0
{
1116
0
  MOZ_ASSERT(IsUnrestrictedDouble(), "Wrong type!");
1117
0
  mValue.mUnrestrictedDouble.Destroy();
1118
0
  mType = eUninitialized;
1119
0
}
1120
1121
1122
1123
1124
KeyframeEffectOptions&
1125
OwningUnrestrictedDoubleOrKeyframeEffectOptions::RawSetAsKeyframeEffectOptions()
1126
0
{
1127
0
  if (mType == eKeyframeEffectOptions) {
1128
0
    return mValue.mKeyframeEffectOptions.Value();
1129
0
  }
1130
0
  MOZ_ASSERT(mType == eUninitialized);
1131
0
  mType = eKeyframeEffectOptions;
1132
0
  return mValue.mKeyframeEffectOptions.SetValue();
1133
0
}
1134
1135
KeyframeEffectOptions&
1136
OwningUnrestrictedDoubleOrKeyframeEffectOptions::SetAsKeyframeEffectOptions()
1137
0
{
1138
0
  if (mType == eKeyframeEffectOptions) {
1139
0
    return mValue.mKeyframeEffectOptions.Value();
1140
0
  }
1141
0
  Uninit();
1142
0
  mType = eKeyframeEffectOptions;
1143
0
  return mValue.mKeyframeEffectOptions.SetValue();
1144
0
}
1145
1146
bool
1147
OwningUnrestrictedDoubleOrKeyframeEffectOptions::TrySetToKeyframeEffectOptions(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
1148
0
{
1149
0
  tryNext = false;
1150
0
  { // scope for memberSlot
1151
0
    KeyframeEffectOptions& memberSlot = RawSetAsKeyframeEffectOptions();
1152
0
    if (!IsConvertibleToDictionary(value)) {
1153
0
      DestroyKeyframeEffectOptions();
1154
0
      tryNext = true;
1155
0
      return true;
1156
0
    }
1157
0
    if (!memberSlot.Init(cx, value,  "Member of UnrestrictedDoubleOrKeyframeEffectOptions", passedToJSImpl)) {
1158
0
      return false;
1159
0
    }
1160
0
  }
1161
0
  return true;
1162
0
}
1163
1164
void
1165
OwningUnrestrictedDoubleOrKeyframeEffectOptions::DestroyKeyframeEffectOptions()
1166
0
{
1167
0
  MOZ_ASSERT(IsKeyframeEffectOptions(), "Wrong type!");
1168
0
  mValue.mKeyframeEffectOptions.Destroy();
1169
0
  mType = eUninitialized;
1170
0
}
1171
1172
1173
1174
1175
void
1176
OwningUnrestrictedDoubleOrKeyframeEffectOptions::Uninit()
1177
{
1178
  switch (mType) {
1179
    case eUninitialized: {
1180
      break;
1181
    }
1182
    case eUnrestrictedDouble: {
1183
      DestroyUnrestrictedDouble();
1184
      break;
1185
    }
1186
    case eKeyframeEffectOptions: {
1187
      DestroyKeyframeEffectOptions();
1188
      break;
1189
    }
1190
  }
1191
}
1192
1193
bool
1194
OwningUnrestrictedDoubleOrKeyframeEffectOptions::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
1195
0
{
1196
0
  switch (mType) {
1197
0
    case eUninitialized: {
1198
0
      return false;
1199
0
      break;
1200
0
    }
1201
0
    case eUnrestrictedDouble: {
1202
0
      rval.set(JS_NumberValue(double(mValue.mUnrestrictedDouble.Value())));
1203
0
      return true;
1204
0
      break;
1205
0
    }
1206
0
    case eKeyframeEffectOptions: {
1207
0
      if (!mValue.mKeyframeEffectOptions.Value().ToObjectInternal(cx, rval)) {
1208
0
        return false;
1209
0
      }
1210
0
      return true;
1211
0
      break;
1212
0
    }
1213
0
    default: {
1214
0
      return false;
1215
0
      break;
1216
0
    }
1217
0
  }
1218
0
1219
0
  return false;
1220
0
}
1221
1222
void
1223
OwningUnrestrictedDoubleOrKeyframeEffectOptions::TraceUnion(JSTracer* trc)
1224
0
{
1225
0
}
1226
1227
OwningUnrestrictedDoubleOrKeyframeEffectOptions&
1228
OwningUnrestrictedDoubleOrKeyframeEffectOptions::operator=(const OwningUnrestrictedDoubleOrKeyframeEffectOptions& aOther)
1229
0
{
1230
0
  switch (aOther.mType) {
1231
0
    case eUninitialized: {
1232
0
      MOZ_ASSERT(mType == eUninitialized,
1233
0
                 "We need to destroy ourselves?");
1234
0
      break;
1235
0
    }
1236
0
    case eUnrestrictedDouble: {
1237
0
      SetAsUnrestrictedDouble() = aOther.GetAsUnrestrictedDouble();
1238
0
      break;
1239
0
    }
1240
0
    case eKeyframeEffectOptions: {
1241
0
      SetAsKeyframeEffectOptions() = aOther.GetAsKeyframeEffectOptions();
1242
0
      break;
1243
0
    }
1244
0
  }
1245
0
  return *this;
1246
0
}
1247
1248
1249
namespace KeyframeEffect_Binding {
1250
1251
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<AnimationEffect_Binding::NativeType>::value,
1252
              "Can't inherit from an interface with a different ownership model.");
1253
1254
MOZ_CAN_RUN_SCRIPT static bool
1255
get_target(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::KeyframeEffect* self, JSJitGetterCallArgs args)
1256
0
{
1257
0
  AUTO_PROFILER_LABEL_FAST("get KeyframeEffect.target", DOM, cx);
1258
0
1259
0
  Nullable<OwningElementOrCSSPseudoElement> result;
1260
0
  self->GetTarget(result);
1261
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
1262
0
  if (result.IsNull()) {
1263
0
    args.rval().setNull();
1264
0
    return true;
1265
0
  }
1266
0
  if (!result.Value().ToJSVal(cx, obj, args.rval())) {
1267
0
    return false;
1268
0
  }
1269
0
  return true;
1270
0
}
1271
1272
MOZ_CAN_RUN_SCRIPT static bool
1273
set_target(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::KeyframeEffect* self, JSJitSetterCallArgs args)
1274
0
{
1275
0
  AUTO_PROFILER_LABEL_FAST("set KeyframeEffect.target", DOM, cx);
1276
0
1277
0
  Nullable<ElementOrCSSPseudoElement > arg0;
1278
0
  Maybe<ElementOrCSSPseudoElementArgument> arg0_holder;
1279
0
  if (args[0].isNullOrUndefined()) {
1280
0
    arg0.SetNull();
1281
0
  } else {
1282
0
    arg0_holder.emplace(arg0.SetValue());
1283
0
    {
1284
0
      bool done = false, failed = false, tryNext;
1285
0
      if (args[0].isObject()) {
1286
0
        done = (failed = !arg0_holder.ref().TrySetToElement(cx, args[0], tryNext, false)) || !tryNext ||
1287
0
               (failed = !arg0_holder.ref().TrySetToCSSPseudoElement(cx, args[0], tryNext, false)) || !tryNext;
1288
0
1289
0
      }
1290
0
      if (failed) {
1291
0
        return false;
1292
0
      }
1293
0
      if (!done) {
1294
0
        ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Value being assigned to KeyframeEffect.target", "Element, CSSPseudoElement");
1295
0
        return false;
1296
0
      }
1297
0
    }
1298
0
  }
1299
0
  self->SetTarget(Constify(arg0));
1300
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
1301
0
1302
0
  return true;
1303
0
}
1304
1305
static const JSJitInfo target_getterinfo = {
1306
  { (JSJitGetterOp)get_target },
1307
  { prototypes::id::KeyframeEffect },
1308
  { PrototypeTraits<prototypes::id::KeyframeEffect>::Depth },
1309
  JSJitInfo::Getter,
1310
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
1311
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
1312
  false,  /* isInfallible. False in setters. */
1313
  false,  /* isMovable.  Not relevant for setters. */
1314
  false, /* isEliminatable.  Not relevant for setters. */
1315
  false, /* isAlwaysInSlot.  Only relevant for getters. */
1316
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
1317
  false,  /* isTypedMethod.  Only relevant for methods. */
1318
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
1319
};
1320
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1321
static_assert(0 < 1, "There is no slot for us");
1322
static const JSJitInfo target_setterinfo = {
1323
  { (JSJitGetterOp)set_target },
1324
  { prototypes::id::KeyframeEffect },
1325
  { PrototypeTraits<prototypes::id::KeyframeEffect>::Depth },
1326
  JSJitInfo::Setter,
1327
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
1328
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
1329
  false,  /* isInfallible. False in setters. */
1330
  false,  /* isMovable.  Not relevant for setters. */
1331
  false, /* isEliminatable.  Not relevant for setters. */
1332
  false, /* isAlwaysInSlot.  Only relevant for getters. */
1333
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
1334
  false,  /* isTypedMethod.  Only relevant for methods. */
1335
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
1336
};
1337
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1338
static_assert(0 < 1, "There is no slot for us");
1339
1340
MOZ_CAN_RUN_SCRIPT static bool
1341
get_iterationComposite(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::KeyframeEffect* self, JSJitGetterCallArgs args)
1342
0
{
1343
0
  AUTO_PROFILER_LABEL_FAST("get KeyframeEffect.iterationComposite", DOM, cx);
1344
0
1345
0
  IterationCompositeOperation result(self->IterationComposite());
1346
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
1347
0
  if (!ToJSValue(cx, result, args.rval())) {
1348
0
    return false;
1349
0
  }
1350
0
  return true;
1351
0
}
1352
1353
MOZ_CAN_RUN_SCRIPT static bool
1354
set_iterationComposite(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::KeyframeEffect* self, JSJitSetterCallArgs args)
1355
0
{
1356
0
  AUTO_PROFILER_LABEL_FAST("set KeyframeEffect.iterationComposite", DOM, cx);
1357
0
1358
0
  IterationCompositeOperation arg0;
1359
0
  {
1360
0
    int index;
1361
0
    if (!FindEnumStringIndex<false>(cx, args[0], IterationCompositeOperationValues::strings, "IterationCompositeOperation", "Value being assigned to KeyframeEffect.iterationComposite", &index)) {
1362
0
      return false;
1363
0
    }
1364
0
    if (index < 0) {
1365
0
      return true;
1366
0
    }
1367
0
    arg0 = static_cast<IterationCompositeOperation>(index);
1368
0
  }
1369
0
  self->SetIterationComposite(arg0);
1370
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
1371
0
1372
0
  return true;
1373
0
}
1374
1375
static const JSJitInfo iterationComposite_getterinfo = {
1376
  { (JSJitGetterOp)get_iterationComposite },
1377
  { prototypes::id::KeyframeEffect },
1378
  { PrototypeTraits<prototypes::id::KeyframeEffect>::Depth },
1379
  JSJitInfo::Getter,
1380
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
1381
  JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
1382
  false,  /* isInfallible. False in setters. */
1383
  false,  /* isMovable.  Not relevant for setters. */
1384
  false, /* isEliminatable.  Not relevant for setters. */
1385
  false, /* isAlwaysInSlot.  Only relevant for getters. */
1386
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
1387
  false,  /* isTypedMethod.  Only relevant for methods. */
1388
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
1389
};
1390
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1391
static_assert(0 < 1, "There is no slot for us");
1392
static const JSJitInfo iterationComposite_setterinfo = {
1393
  { (JSJitGetterOp)set_iterationComposite },
1394
  { prototypes::id::KeyframeEffect },
1395
  { PrototypeTraits<prototypes::id::KeyframeEffect>::Depth },
1396
  JSJitInfo::Setter,
1397
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
1398
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
1399
  false,  /* isInfallible. False in setters. */
1400
  false,  /* isMovable.  Not relevant for setters. */
1401
  false, /* isEliminatable.  Not relevant for setters. */
1402
  false, /* isAlwaysInSlot.  Only relevant for getters. */
1403
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
1404
  false,  /* isTypedMethod.  Only relevant for methods. */
1405
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
1406
};
1407
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1408
static_assert(0 < 1, "There is no slot for us");
1409
1410
MOZ_CAN_RUN_SCRIPT static bool
1411
get_composite(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::KeyframeEffect* self, JSJitGetterCallArgs args)
1412
0
{
1413
0
  AUTO_PROFILER_LABEL_FAST("get KeyframeEffect.composite", DOM, cx);
1414
0
1415
0
  CompositeOperation result(self->Composite());
1416
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
1417
0
  if (!ToJSValue(cx, result, args.rval())) {
1418
0
    return false;
1419
0
  }
1420
0
  return true;
1421
0
}
1422
1423
MOZ_CAN_RUN_SCRIPT static bool
1424
set_composite(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::KeyframeEffect* self, JSJitSetterCallArgs args)
1425
0
{
1426
0
  AUTO_PROFILER_LABEL_FAST("set KeyframeEffect.composite", DOM, cx);
1427
0
1428
0
  CompositeOperation arg0;
1429
0
  {
1430
0
    int index;
1431
0
    if (!FindEnumStringIndex<false>(cx, args[0], CompositeOperationValues::strings, "CompositeOperation", "Value being assigned to KeyframeEffect.composite", &index)) {
1432
0
      return false;
1433
0
    }
1434
0
    if (index < 0) {
1435
0
      return true;
1436
0
    }
1437
0
    arg0 = static_cast<CompositeOperation>(index);
1438
0
  }
1439
0
  self->SetComposite(arg0);
1440
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
1441
0
1442
0
  return true;
1443
0
}
1444
1445
static const JSJitInfo composite_getterinfo = {
1446
  { (JSJitGetterOp)get_composite },
1447
  { prototypes::id::KeyframeEffect },
1448
  { PrototypeTraits<prototypes::id::KeyframeEffect>::Depth },
1449
  JSJitInfo::Getter,
1450
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
1451
  JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
1452
  false,  /* isInfallible. False in setters. */
1453
  false,  /* isMovable.  Not relevant for setters. */
1454
  false, /* isEliminatable.  Not relevant for setters. */
1455
  false, /* isAlwaysInSlot.  Only relevant for getters. */
1456
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
1457
  false,  /* isTypedMethod.  Only relevant for methods. */
1458
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
1459
};
1460
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1461
static_assert(0 < 1, "There is no slot for us");
1462
static const JSJitInfo composite_setterinfo = {
1463
  { (JSJitGetterOp)set_composite },
1464
  { prototypes::id::KeyframeEffect },
1465
  { PrototypeTraits<prototypes::id::KeyframeEffect>::Depth },
1466
  JSJitInfo::Setter,
1467
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
1468
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
1469
  false,  /* isInfallible. False in setters. */
1470
  false,  /* isMovable.  Not relevant for setters. */
1471
  false, /* isEliminatable.  Not relevant for setters. */
1472
  false, /* isAlwaysInSlot.  Only relevant for getters. */
1473
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
1474
  false,  /* isTypedMethod.  Only relevant for methods. */
1475
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
1476
};
1477
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1478
static_assert(0 < 1, "There is no slot for us");
1479
1480
MOZ_CAN_RUN_SCRIPT static bool
1481
getKeyframes(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::KeyframeEffect* self, const JSJitMethodCallArgs& args)
1482
0
{
1483
0
  AUTO_PROFILER_LABEL_FAST("KeyframeEffect.getKeyframes", DOM, cx);
1484
0
1485
0
  FastErrorResult rv;
1486
0
  nsTArray<JSObject*> result;
1487
0
  SequenceRooter<JSObject* > resultRooter(cx, &result);
1488
0
  self->GetKeyframes(cx, result, rv);
1489
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1490
0
    return false;
1491
0
  }
1492
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
1493
0
1494
0
  uint32_t length = result.Length();
1495
0
  JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
1496
0
  if (!returnArray) {
1497
0
    return false;
1498
0
  }
1499
0
  // Scope for 'tmp'
1500
0
  {
1501
0
    JS::Rooted<JS::Value> tmp(cx);
1502
0
    for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
1503
0
      // Control block to let us common up the JS_DefineElement calls when there
1504
0
      // are different ways to succeed at wrapping the object.
1505
0
      do {
1506
0
        JS::ExposeObjectToActiveJS(result[sequenceIdx0]);
1507
0
        tmp.setObject(*result[sequenceIdx0]);
1508
0
        if (!MaybeWrapObjectValue(cx, &tmp)) {
1509
0
          return false;
1510
0
        }
1511
0
        break;
1512
0
      } while (false);
1513
0
      if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
1514
0
                            JSPROP_ENUMERATE)) {
1515
0
        return false;
1516
0
      }
1517
0
    }
1518
0
  }
1519
0
  args.rval().setObject(*returnArray);
1520
0
  return true;
1521
0
}
1522
1523
static const JSJitInfo getKeyframes_methodinfo = {
1524
  { (JSJitGetterOp)getKeyframes },
1525
  { prototypes::id::KeyframeEffect },
1526
  { PrototypeTraits<prototypes::id::KeyframeEffect>::Depth },
1527
  JSJitInfo::Method,
1528
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
1529
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
1530
  false,  /* isInfallible. False in setters. */
1531
  false,  /* isMovable.  Not relevant for setters. */
1532
  false, /* isEliminatable.  Not relevant for setters. */
1533
  false, /* isAlwaysInSlot.  Only relevant for getters. */
1534
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
1535
  false,  /* isTypedMethod.  Only relevant for methods. */
1536
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
1537
};
1538
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1539
static_assert(0 < 1, "There is no slot for us");
1540
1541
MOZ_CAN_RUN_SCRIPT static bool
1542
setKeyframes(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::KeyframeEffect* self, const JSJitMethodCallArgs& args)
1543
0
{
1544
0
  AUTO_PROFILER_LABEL_FAST("KeyframeEffect.setKeyframes", DOM, cx);
1545
0
1546
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
1547
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "KeyframeEffect.setKeyframes");
1548
0
  }
1549
0
  JS::Rooted<JSObject*> arg0(cx);
1550
0
  if (args[0].isObject()) {
1551
0
    arg0 = &args[0].toObject();
1552
0
  } else if (args[0].isNullOrUndefined()) {
1553
0
    arg0 = nullptr;
1554
0
  } else {
1555
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of KeyframeEffect.setKeyframes");
1556
0
    return false;
1557
0
  }
1558
0
  FastErrorResult rv;
1559
0
  self->SetKeyframes(cx, arg0, rv);
1560
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1561
0
    return false;
1562
0
  }
1563
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
1564
0
  args.rval().setUndefined();
1565
0
  return true;
1566
0
}
1567
1568
static const JSJitInfo setKeyframes_methodinfo = {
1569
  { (JSJitGetterOp)setKeyframes },
1570
  { prototypes::id::KeyframeEffect },
1571
  { PrototypeTraits<prototypes::id::KeyframeEffect>::Depth },
1572
  JSJitInfo::Method,
1573
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
1574
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
1575
  false,  /* isInfallible. False in setters. */
1576
  false,  /* isMovable.  Not relevant for setters. */
1577
  false, /* isEliminatable.  Not relevant for setters. */
1578
  false, /* isAlwaysInSlot.  Only relevant for getters. */
1579
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
1580
  false,  /* isTypedMethod.  Only relevant for methods. */
1581
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
1582
};
1583
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1584
static_assert(0 < 1, "There is no slot for us");
1585
1586
MOZ_CAN_RUN_SCRIPT static bool
1587
getProperties(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::KeyframeEffect* self, const JSJitMethodCallArgs& args)
1588
0
{
1589
0
  AUTO_PROFILER_LABEL_FAST("KeyframeEffect.getProperties", DOM, cx);
1590
0
1591
0
  FastErrorResult rv;
1592
0
  nsTArray<AnimationPropertyDetails> result;
1593
0
  self->GetProperties(result, rv);
1594
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1595
0
    return false;
1596
0
  }
1597
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
1598
0
1599
0
  uint32_t length = result.Length();
1600
0
  JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
1601
0
  if (!returnArray) {
1602
0
    return false;
1603
0
  }
1604
0
  // Scope for 'tmp'
1605
0
  {
1606
0
    JS::Rooted<JS::Value> tmp(cx);
1607
0
    for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
1608
0
      // Control block to let us common up the JS_DefineElement calls when there
1609
0
      // are different ways to succeed at wrapping the object.
1610
0
      do {
1611
0
        if (!result[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
1612
0
          return false;
1613
0
        }
1614
0
        break;
1615
0
      } while (false);
1616
0
      if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
1617
0
                            JSPROP_ENUMERATE)) {
1618
0
        return false;
1619
0
      }
1620
0
    }
1621
0
  }
1622
0
  args.rval().setObject(*returnArray);
1623
0
  return true;
1624
0
}
1625
1626
static const JSJitInfo getProperties_methodinfo = {
1627
  { (JSJitGetterOp)getProperties },
1628
  { prototypes::id::KeyframeEffect },
1629
  { PrototypeTraits<prototypes::id::KeyframeEffect>::Depth },
1630
  JSJitInfo::Method,
1631
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
1632
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
1633
  false,  /* isInfallible. False in setters. */
1634
  false,  /* isMovable.  Not relevant for setters. */
1635
  false, /* isEliminatable.  Not relevant for setters. */
1636
  false, /* isAlwaysInSlot.  Only relevant for getters. */
1637
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
1638
  false,  /* isTypedMethod.  Only relevant for methods. */
1639
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
1640
};
1641
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1642
static_assert(0 < 1, "There is no slot for us");
1643
1644
static bool
1645
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
1646
0
{
1647
0
  mozilla::dom::KeyframeEffect* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::KeyframeEffect>(obj);
1648
0
  // We don't want to preserve if we don't have a wrapper, and we
1649
0
  // obviously can't preserve if we're not initialized.
1650
0
  if (self && self->GetWrapperPreserveColor()) {
1651
0
    PreserveWrapper(self);
1652
0
  }
1653
0
  return true;
1654
0
}
1655
1656
static void
1657
_finalize(js::FreeOp* fop, JSObject* obj)
1658
0
{
1659
0
  mozilla::dom::KeyframeEffect* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::KeyframeEffect>(obj);
1660
0
  if (self) {
1661
0
    ClearWrapper(self, self, obj);
1662
0
    AddForDeferredFinalization<mozilla::dom::KeyframeEffect>(self);
1663
0
  }
1664
0
}
1665
1666
static size_t
1667
_objectMoved(JSObject* obj, JSObject* old)
1668
0
{
1669
0
  mozilla::dom::KeyframeEffect* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::KeyframeEffect>(obj);
1670
0
  if (self) {
1671
0
    UpdateWrapper(self, self, obj, old);
1672
0
  }
1673
0
1674
0
  return 0;
1675
0
}
1676
1677
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
1678
#if defined(__clang__)
1679
#pragma clang diagnostic push
1680
#pragma clang diagnostic ignored "-Wmissing-braces"
1681
#endif
1682
static const JSFunctionSpec sMethods_specs[] = {
1683
  JS_FNSPEC("getKeyframes", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getKeyframes_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
1684
  JS_FNSPEC("setKeyframes", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setKeyframes_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
1685
  JS_FS_END
1686
};
1687
#if defined(__clang__)
1688
#pragma clang diagnostic pop
1689
#endif
1690
1691
1692
static const Prefable<const JSFunctionSpec> sMethods[] = {
1693
  { nullptr, &sMethods_specs[0] },
1694
  { nullptr, nullptr }
1695
};
1696
1697
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1698
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1699
static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1700
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1701
1702
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
1703
#if defined(__clang__)
1704
#pragma clang diagnostic push
1705
#pragma clang diagnostic ignored "-Wmissing-braces"
1706
#endif
1707
static const JSFunctionSpec sChromeMethods_specs[] = {
1708
  JS_FNSPEC("getProperties", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getProperties_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
1709
  JS_FS_END
1710
};
1711
#if defined(__clang__)
1712
#pragma clang diagnostic pop
1713
#endif
1714
1715
1716
static const Prefable<const JSFunctionSpec> sChromeMethods[] = {
1717
  { nullptr, &sChromeMethods_specs[0] },
1718
  { nullptr, nullptr }
1719
};
1720
1721
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1722
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1723
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1724
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1725
1726
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
1727
#if defined(__clang__)
1728
#pragma clang diagnostic push
1729
#pragma clang diagnostic ignored "-Wmissing-braces"
1730
#endif
1731
static const JSPropertySpec sAttributes_specs[] = {
1732
  { "target", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &target_getterinfo, GenericSetter<NormalThisPolicy>, &target_setterinfo },
1733
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr },
1734
  { "iterationComposite", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &iterationComposite_getterinfo, GenericSetter<NormalThisPolicy>, &iterationComposite_setterinfo },
1735
  { "composite", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &composite_getterinfo, GenericSetter<NormalThisPolicy>, &composite_setterinfo },
1736
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
1737
};
1738
#if defined(__clang__)
1739
#pragma clang diagnostic pop
1740
#endif
1741
1742
// Can't be const because the pref-enabled boolean needs to be writable
1743
static PrefableDisablers sAttributes_disablers2 = {
1744
  true, false, 0, nullptr
1745
};
1746
1747
static const Prefable<const JSPropertySpec> sAttributes[] = {
1748
  { nullptr, &sAttributes_specs[0] },
1749
  { &sAttributes_disablers2, &sAttributes_specs[2] },
1750
  { nullptr, nullptr }
1751
};
1752
1753
static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1754
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1755
static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1756
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1757
1758
1759
static uint16_t sNativeProperties_sortedPropertyIndices[5];
1760
static PropertyInfo sNativeProperties_propertyInfos[5];
1761
1762
static const NativePropertiesN<2> sNativeProperties = {
1763
  false, 0,
1764
  false, 0,
1765
  true,  0 /* sMethods */,
1766
  true,  1 /* sAttributes */,
1767
  false, 0,
1768
  false, 0,
1769
  false, 0,
1770
  -1,
1771
  5,
1772
  sNativeProperties_sortedPropertyIndices,
1773
  {
1774
    { sMethods, &sNativeProperties_propertyInfos[0] },
1775
    { sAttributes, &sNativeProperties_propertyInfos[2] }
1776
  }
1777
};
1778
static_assert(5 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
1779
    "We have a property info count that is oversized");
1780
1781
static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[1];
1782
static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[1];
1783
1784
static const NativePropertiesN<1> sChromeOnlyNativeProperties = {
1785
  false, 0,
1786
  false, 0,
1787
  true,  0 /* sChromeMethods */,
1788
  false, 0,
1789
  false, 0,
1790
  false, 0,
1791
  false, 0,
1792
  -1,
1793
  1,
1794
  sChromeOnlyNativeProperties_sortedPropertyIndices,
1795
  {
1796
    { sChromeMethods, &sChromeOnlyNativeProperties_propertyInfos[0] }
1797
  }
1798
};
1799
static_assert(1 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
1800
    "We have a property info count that is oversized");
1801
1802
static bool
1803
_constructor(JSContext* cx, unsigned argc, JS::Value* vp)
1804
0
{
1805
0
  AUTO_PROFILER_LABEL_FAST("KeyframeEffect constructor", DOM, cx);
1806
0
1807
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
1808
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
1809
0
  if (!args.isConstructing()) {
1810
0
    // XXXbz wish I could get the name from the callee instead of
1811
0
    // Adding more relocations
1812
0
    return ThrowConstructorWithoutNew(cx, "KeyframeEffect");
1813
0
  }
1814
0
1815
0
  JS::Rooted<JSObject*> desiredProto(cx);
1816
0
  if (!GetDesiredProto(cx, args, &desiredProto)) {
1817
0
    return false;
1818
0
  }
1819
0
1820
0
  unsigned argcount = std::min(args.length(), 3u);
1821
0
  switch (argcount) {
1822
0
    case 1: {
1823
0
      GlobalObject global(cx, obj);
1824
0
      if (global.Failed()) {
1825
0
        return false;
1826
0
      }
1827
0
1828
0
      NonNull<mozilla::dom::KeyframeEffect> arg0;
1829
0
      if (args[0].isObject()) {
1830
0
        {
1831
0
          nsresult rv = UnwrapObject<prototypes::id::KeyframeEffect, mozilla::dom::KeyframeEffect>(args[0], arg0);
1832
0
          if (NS_FAILED(rv)) {
1833
0
            ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of KeyframeEffect.constructor", "KeyframeEffect");
1834
0
            return false;
1835
0
          }
1836
0
        }
1837
0
      } else {
1838
0
        ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of KeyframeEffect.constructor");
1839
0
        return false;
1840
0
      }
1841
0
      FastErrorResult rv;
1842
0
      auto result(StrongOrRawPtr<mozilla::dom::KeyframeEffect>(mozilla::dom::KeyframeEffect::Constructor(global, MOZ_KnownLive(NonNullHelper(arg0)), rv)));
1843
0
      if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1844
0
        return false;
1845
0
      }
1846
0
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
1847
0
      static_assert(!IsPointer<decltype(result)>::value,
1848
0
                    "NewObject implies that we need to keep the object alive with a strong reference.");
1849
0
      if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
1850
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
1851
0
        return false;
1852
0
      }
1853
0
      return true;
1854
0
      break;
1855
0
    }
1856
0
    case 2: {
1857
0
      MOZ_FALLTHROUGH;
1858
0
    }
1859
0
    case 3: {
1860
0
      GlobalObject global(cx, obj);
1861
0
      if (global.Failed()) {
1862
0
        return false;
1863
0
      }
1864
0
1865
0
      Nullable<ElementOrCSSPseudoElement > arg0;
1866
0
      Maybe<ElementOrCSSPseudoElementArgument> arg0_holder;
1867
0
      if (args[0].isNullOrUndefined()) {
1868
0
        arg0.SetNull();
1869
0
      } else {
1870
0
        arg0_holder.emplace(arg0.SetValue());
1871
0
        {
1872
0
          bool done = false, failed = false, tryNext;
1873
0
          if (args[0].isObject()) {
1874
0
            done = (failed = !arg0_holder.ref().TrySetToElement(cx, args[0], tryNext, false)) || !tryNext ||
1875
0
                   (failed = !arg0_holder.ref().TrySetToCSSPseudoElement(cx, args[0], tryNext, false)) || !tryNext;
1876
0
1877
0
          }
1878
0
          if (failed) {
1879
0
            return false;
1880
0
          }
1881
0
          if (!done) {
1882
0
            ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 1 of KeyframeEffect.constructor", "Element, CSSPseudoElement");
1883
0
            return false;
1884
0
          }
1885
0
        }
1886
0
      }
1887
0
      JS::Rooted<JSObject*> arg1(cx);
1888
0
      if (args[1].isObject()) {
1889
0
        arg1 = &args[1].toObject();
1890
0
      } else if (args[1].isNullOrUndefined()) {
1891
0
        arg1 = nullptr;
1892
0
      } else {
1893
0
        ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of KeyframeEffect.constructor");
1894
0
        return false;
1895
0
      }
1896
0
      UnrestrictedDoubleOrKeyframeEffectOptions arg2;
1897
0
      UnrestrictedDoubleOrKeyframeEffectOptionsArgument arg2_holder(arg2);
1898
0
      if (!(args.hasDefined(2))) {
1899
0
        if (!arg2.RawSetAsKeyframeEffectOptions().Init(cx, JS::NullHandleValue, "Member of UnrestrictedDoubleOrKeyframeEffectOptions")) {
1900
0
          return false;
1901
0
        }
1902
0
      } else {
1903
0
        {
1904
0
          bool done = false, failed = false, tryNext;
1905
0
          if (!done) {
1906
0
            done = (failed = !arg2_holder.TrySetToKeyframeEffectOptions(cx, args[2], tryNext, false)) || !tryNext;
1907
0
          }
1908
0
          if (!done) {
1909
0
            do {
1910
0
              done = (failed = !arg2_holder.TrySetToUnrestrictedDouble(cx, args[2], tryNext)) || !tryNext;
1911
0
              break;
1912
0
            } while (false);
1913
0
          }
1914
0
          if (failed) {
1915
0
            return false;
1916
0
          }
1917
0
          if (!done) {
1918
0
            ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 3 of KeyframeEffect.constructor", "KeyframeEffectOptions");
1919
0
            return false;
1920
0
          }
1921
0
        }
1922
0
      }
1923
0
      FastErrorResult rv;
1924
0
      auto result(StrongOrRawPtr<mozilla::dom::KeyframeEffect>(mozilla::dom::KeyframeEffect::Constructor(global, Constify(arg0), arg1, Constify(arg2), rv)));
1925
0
      if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1926
0
        return false;
1927
0
      }
1928
0
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
1929
0
      static_assert(!IsPointer<decltype(result)>::value,
1930
0
                    "NewObject implies that we need to keep the object alive with a strong reference.");
1931
0
      if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
1932
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
1933
0
        return false;
1934
0
      }
1935
0
      return true;
1936
0
      break;
1937
0
    }
1938
0
    default: {
1939
0
      return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "KeyframeEffect");
1940
0
      break;
1941
0
    }
1942
0
  }
1943
0
  MOZ_CRASH("We have an always-returning default case");
1944
0
  return false;
1945
0
}
1946
1947
static const js::ClassOps sInterfaceObjectClassOps = {
1948
    nullptr,               /* addProperty */
1949
    nullptr,               /* delProperty */
1950
    nullptr,               /* enumerate */
1951
    nullptr,               /* newEnumerate */
1952
    nullptr,               /* resolve */
1953
    nullptr,               /* mayResolve */
1954
    nullptr,               /* finalize */
1955
    _constructor, /* call */
1956
    nullptr,               /* hasInstance */
1957
    _constructor, /* construct */
1958
    nullptr,               /* trace */
1959
};
1960
1961
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
1962
  {
1963
    "Function",
1964
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
1965
    &sInterfaceObjectClassOps,
1966
    JS_NULL_CLASS_SPEC,
1967
    JS_NULL_CLASS_EXT,
1968
    &sInterfaceObjectClassObjectOps
1969
  },
1970
  eInterface,
1971
  true,
1972
  prototypes::id::KeyframeEffect,
1973
  PrototypeTraits<prototypes::id::KeyframeEffect>::Depth,
1974
  sNativePropertyHooks,
1975
  "function KeyframeEffect() {\n    [native code]\n}",
1976
  AnimationEffect_Binding::GetConstructorObject
1977
};
1978
1979
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
1980
  {
1981
    "KeyframeEffectPrototype",
1982
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
1983
    JS_NULL_CLASS_OPS,
1984
    JS_NULL_CLASS_SPEC,
1985
    JS_NULL_CLASS_EXT,
1986
    JS_NULL_OBJECT_OPS
1987
  },
1988
  eInterfacePrototype,
1989
  false,
1990
  prototypes::id::KeyframeEffect,
1991
  PrototypeTraits<prototypes::id::KeyframeEffect>::Depth,
1992
  sNativePropertyHooks,
1993
  "[object KeyframeEffectPrototype]",
1994
  AnimationEffect_Binding::GetProtoObject
1995
};
1996
1997
bool
1998
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
1999
0
{
2000
0
  return nsDocument::IsWebAnimationsEnabled(aCx, aObj);
2001
0
}
2002
2003
static const js::ClassOps sClassOps = {
2004
  _addProperty, /* addProperty */
2005
  nullptr,               /* delProperty */
2006
  nullptr,               /* enumerate */
2007
  nullptr, /* newEnumerate */
2008
  nullptr, /* resolve */
2009
  nullptr, /* mayResolve */
2010
  _finalize, /* finalize */
2011
  nullptr, /* call */
2012
  nullptr,               /* hasInstance */
2013
  nullptr,               /* construct */
2014
  nullptr, /* trace */
2015
};
2016
2017
static const js::ClassExtension sClassExtension = {
2018
  nullptr, /* weakmapKeyDelegateOp */
2019
  _objectMoved /* objectMovedOp */
2020
};
2021
2022
static const DOMJSClass sClass = {
2023
  { "KeyframeEffect",
2024
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
2025
    &sClassOps,
2026
    JS_NULL_CLASS_SPEC,
2027
    &sClassExtension,
2028
    JS_NULL_OBJECT_OPS
2029
  },
2030
  { prototypes::id::AnimationEffect, prototypes::id::KeyframeEffect, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
2031
  IsBaseOf<nsISupports, mozilla::dom::KeyframeEffect >::value,
2032
  sNativePropertyHooks,
2033
  FindAssociatedGlobalForNative<mozilla::dom::KeyframeEffect>::Get,
2034
  GetProtoObjectHandle,
2035
  GetCCParticipant<mozilla::dom::KeyframeEffect>::Get()
2036
};
2037
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
2038
              "Must have the right minimal number of reserved slots.");
2039
static_assert(1 >= 1,
2040
              "Must have enough reserved slots.");
2041
2042
const JSClass*
2043
GetJSClass()
2044
0
{
2045
0
  return sClass.ToJSClass();
2046
0
}
2047
2048
bool
2049
Wrap(JSContext* aCx, mozilla::dom::KeyframeEffect* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
2050
0
{
2051
0
  static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::KeyframeEffect>::value,
2052
0
                "Shouldn't have wrappercached things that are not refcounted.");
2053
0
  MOZ_ASSERT(static_cast<mozilla::dom::KeyframeEffect*>(aObject) ==
2054
0
             reinterpret_cast<mozilla::dom::KeyframeEffect*>(aObject),
2055
0
             "Multiple inheritance for mozilla::dom::KeyframeEffect is broken.");
2056
0
  MOZ_ASSERT(static_cast<mozilla::dom::AnimationEffect*>(aObject) ==
2057
0
             reinterpret_cast<mozilla::dom::AnimationEffect*>(aObject),
2058
0
             "Multiple inheritance for mozilla::dom::AnimationEffect is broken.");
2059
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
2060
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
2061
0
  MOZ_ASSERT(!aCache->GetWrapper(),
2062
0
             "You should probably not be using Wrap() directly; use "
2063
0
             "GetOrCreateDOMReflector instead");
2064
0
2065
0
  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
2066
0
             "nsISupports must be on our primary inheritance chain");
2067
0
2068
0
  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
2069
0
  if (!global) {
2070
0
    return false;
2071
0
  }
2072
0
  MOZ_ASSERT(JS_IsGlobalObject(global));
2073
0
  MOZ_ASSERT(JS::ObjectIsNotGray(global));
2074
0
2075
0
  // That might have ended up wrapping us already, due to the wonders
2076
0
  // of XBL.  Check for that, and bail out as needed.
2077
0
  aReflector.set(aCache->GetWrapper());
2078
0
  if (aReflector) {
2079
#ifdef DEBUG
2080
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
2081
#endif // DEBUG
2082
    return true;
2083
0
  }
2084
0
2085
0
  JSAutoRealm ar(aCx, global);
2086
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
2087
0
  if (!canonicalProto) {
2088
0
    return false;
2089
0
  }
2090
0
  JS::Rooted<JSObject*> proto(aCx);
2091
0
  if (aGivenProto) {
2092
0
    proto = aGivenProto;
2093
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
2094
0
    // coming in, we changed compartments to that of "parent" so may need
2095
0
    // to wrap the proto here.
2096
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
2097
0
      if (!JS_WrapObject(aCx, &proto)) {
2098
0
        return false;
2099
0
      }
2100
0
    }
2101
0
  } else {
2102
0
    proto = canonicalProto;
2103
0
  }
2104
0
2105
0
  BindingJSObjectCreator<mozilla::dom::KeyframeEffect> creator(aCx);
2106
0
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
2107
0
  if (!aReflector) {
2108
0
    return false;
2109
0
  }
2110
0
2111
0
  aCache->SetWrapper(aReflector);
2112
0
  creator.InitializationSucceeded();
2113
0
2114
0
  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
2115
0
             aCache->GetWrapperPreserveColor() == aReflector);
2116
0
  // If proto != canonicalProto, we have to preserve our wrapper;
2117
0
  // otherwise we won't be able to properly recreate it later, since
2118
0
  // we won't know what proto to use.  Note that we don't check
2119
0
  // aGivenProto here, since it's entirely possible (and even
2120
0
  // somewhat common) to have a non-null aGivenProto which is the
2121
0
  // same as canonicalProto.
2122
0
  if (proto != canonicalProto) {
2123
0
    PreserveWrapper(aObject);
2124
0
  }
2125
0
2126
0
  return true;
2127
0
}
2128
2129
const NativePropertyHooks sNativePropertyHooks[] = { {
2130
  nullptr,
2131
  nullptr,
2132
  nullptr,
2133
  { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
2134
  prototypes::id::KeyframeEffect,
2135
  constructors::id::KeyframeEffect,
2136
  AnimationEffect_Binding::sNativePropertyHooks,
2137
  &DefaultXrayExpandoObjectClass
2138
} };
2139
2140
void
2141
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
2142
0
{
2143
0
  JS::Handle<JSObject*> parentProto(AnimationEffect_Binding::GetProtoObjectHandle(aCx));
2144
0
  if (!parentProto) {
2145
0
    return;
2146
0
  }
2147
0
2148
0
  JS::Handle<JSObject*> constructorProto(AnimationEffect_Binding::GetConstructorObjectHandle(aCx));
2149
0
  if (!constructorProto) {
2150
0
    return;
2151
0
  }
2152
0
2153
0
  static bool sIdsInited = false;
2154
0
  if (!sIdsInited && NS_IsMainThread()) {
2155
0
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
2156
0
      return;
2157
0
    }
2158
0
    if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
2159
0
      return;
2160
0
    }
2161
0
    sIdsInited = true;
2162
0
  }
2163
0
2164
0
  static bool sPrefCachesInited = false;
2165
0
  if (!sPrefCachesInited && NS_IsMainThread()) {
2166
0
    sPrefCachesInited = true;
2167
0
    Preferences::AddBoolVarCache(&sAttributes[1].disablers->enabled, "dom.animations-api.compositing.enabled");
2168
0
  }
2169
0
2170
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::KeyframeEffect);
2171
0
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::KeyframeEffect);
2172
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
2173
0
                              &sPrototypeClass.mBase, protoCache,
2174
0
                              nullptr,
2175
0
                              constructorProto, &sInterfaceObjectClass.mBase, 1, nullptr,
2176
0
                              interfaceCache,
2177
0
                              sNativeProperties.Upcast(),
2178
0
                              sChromeOnlyNativeProperties.Upcast(),
2179
0
                              "KeyframeEffect", aDefineOnGlobal,
2180
0
                              nullptr,
2181
0
                              false);
2182
0
}
2183
2184
JSObject*
2185
GetConstructorObject(JSContext* aCx)
2186
0
{
2187
0
  return GetConstructorObjectHandle(aCx);
2188
0
}
2189
2190
} // namespace KeyframeEffect_Binding
2191
2192
2193
2194
} // namespace dom
2195
} // namespace mozilla