/* THIS FILE IS AUTOGENERATED FROM BaseKeyframeTypes.webidl BY Codegen.py - DO NOT EDIT */

#include <type_traits>
#include "AtomList.h"
#include "BaseKeyframeTypesBinding.h"
#include "MainThreadUtils.h"
#include "js/Array.h"
#include "js/CallAndConstruct.h"
#include "js/Exception.h"
#include "js/ForOfIterator.h"
#include "js/MapAndSet.h"
#include "js/Object.h"
#include "js/PropertyAndElement.h"
#include "js/PropertyDescriptor.h"
#include "js/experimental/JitInfo.h"
#include "jsapi.h"
#include "mozilla/FloatingPoint.h"
#include "mozilla/OwningNonNull.h"
#include "mozilla/dom/BindingCallContext.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/NonRefcountedDOMObject.h"
#include "mozilla/dom/Nullable.h"
#include "mozilla/dom/PrimitiveConversions.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/SimpleGlobalObject.h"
#include "nsContentUtils.h"

namespace mozilla {

namespace dom {

namespace binding_detail {}; // Just to make sure it's known as a namespace
using namespace mozilla::dom::binding_detail;


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<CompositeOperation>::Values[3];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, CompositeOperation aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<CompositeOperation>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<CompositeOperation>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<CompositeOperation>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<CompositeOperationOrAuto>::Values[4];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, CompositeOperationOrAuto aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<CompositeOperationOrAuto>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<CompositeOperationOrAuto>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<CompositeOperationOrAuto>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}



BaseKeyframe::BaseKeyframe()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




bool
BaseKeyframe::InitIds(JSContext* cx, BaseKeyframeAtoms* atomsCache)
{
  MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->simulateComputeValuesFailure_id.init(cx, "simulateComputeValuesFailure") ||
      !atomsCache->offset_id.init(cx, "offset") ||
      !atomsCache->easing_id.init(cx, "easing") ||
      !atomsCache->composite_id.init(cx, "composite")) {
    return false;
  }
  return true;
}

bool
BaseKeyframe::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  BaseKeyframeAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<BaseKeyframeAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->composite_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<CompositeOperationOrAuto>::Values,
                                                                         "CompositeOperationOrAuto", "'composite' member of BaseKeyframe",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mComposite = static_cast<CompositeOperationOrAuto>(index);
    }
  } else {
    mComposite = CompositeOperationOrAuto::Auto;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->easing_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mEasing)) {
      return false;
    }
  } else {
    mEasing.AssignLiteral("linear");
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->offset_id, temp.ptr())) {
      return false;
    }
  }
  if (!(!isNull && !temp->isUndefined()) || temp.ref().isNullOrUndefined()) {
    mOffset.SetNull();
  } else if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), "'offset' member of BaseKeyframe", &mOffset.SetValue())) {
    return false;
  } else if (!std::isfinite(mOffset.Value())) {
    cx.ThrowErrorMessage<MSG_NOT_FINITE>("'offset' member of BaseKeyframe");
    return false;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (nsContentUtils::ThreadsafeIsSystemCaller(cx)) {
      if (!JS_GetPropertyById(cx, *object, atomsCache->simulateComputeValuesFailure_id, temp.ptr())) {
        return false;
      }
    } else {
      temp->setUndefined();
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'simulateComputeValuesFailure' member of BaseKeyframe", &mSimulateComputeValuesFailure)) {
      return false;
    }
  } else {
    mSimulateComputeValuesFailure = false;
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
BaseKeyframe::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

bool
BaseKeyframe::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  BaseKeyframeAtoms* atomsCache = GetAtomCache<BaseKeyframeAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    CompositeOperationOrAuto const & currentValue = mComposite;
    if (!ToJSValue(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->composite_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    nsCString const & currentValue = mEasing;
    if (!NonVoidUTF8StringToJsval(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->easing_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    Nullable<double> const & currentValue = mOffset;
    if (currentValue.IsNull()) {
      temp.setNull();
      if (!JS_DefinePropertyById(cx, obj, atomsCache->offset_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    }
    temp.set(JS_NumberValue(double(currentValue.Value())));
    if (!JS_DefinePropertyById(cx, obj, atomsCache->offset_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  if (nsContentUtils::ThreadsafeIsSystemCaller(cx)) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      bool const & currentValue = mSimulateComputeValuesFailure;
      temp.setBoolean(currentValue);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->simulateComputeValuesFailure_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

void
BaseKeyframe::TraceDictionary(JSTracer* trc)
{
}

BaseKeyframe&
BaseKeyframe::operator=(const BaseKeyframe& aOther)
{
  DictionaryBase::operator=(aOther);
  mComposite = aOther.mComposite;
  mEasing = aOther.mEasing;
  mOffset = aOther.mOffset;
  mSimulateComputeValuesFailure = aOther.mSimulateComputeValuesFailure;
  return *this;
}


bool
CompositeOperationOrAutoOrCompositeOperationOrAutoSequence::TrySetToCompositeOperationOrAuto(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    CompositeOperationOrAuto& memberSlot = RawSetAsCompositeOperationOrAuto();
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, value,
                                                                         binding_detail::EnumStrings<CompositeOperationOrAuto>::Values,
                                                                         "CompositeOperationOrAuto", "CompositeOperationOrAuto branch of (CompositeOperationOrAuto or sequence<CompositeOperationOrAuto>)",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      memberSlot = static_cast<CompositeOperationOrAuto>(index);
    }
  }
  return true;
}

bool
CompositeOperationOrAutoOrCompositeOperationOrAutoSequence::TrySetToCompositeOperationOrAuto(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToCompositeOperationOrAuto(cx, value, tryNext, passedToJSImpl);
}







bool
CompositeOperationOrAutoOrCompositeOperationOrAutoSequence::TrySetToCompositeOperationOrAutoSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    binding_detail::AutoSequence<CompositeOperationOrAuto>& memberSlot = RawSetAsCompositeOperationOrAutoSequence();
    JS::ForOfIterator iter(cx);
    if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
      return false;
    }
    if (!iter.valueIsIterable()) {
      DestroyCompositeOperationOrAutoSequence();
      tryNext = true;
      return true;
    }
    binding_detail::AutoSequence<CompositeOperationOrAuto> &arr = memberSlot;
    JS::Rooted<JS::Value> temp(cx);
    while (true) {
      bool done;
      if (!iter.next(&temp, &done)) {
        return false;
      }
      if (done) {
        break;
      }
      CompositeOperationOrAuto* slotPtr = arr.AppendElement(mozilla::fallible);
      if (!slotPtr) {
        JS_ReportOutOfMemory(cx);
        return false;
      }
      CompositeOperationOrAuto& slot = *slotPtr;
      {
        int index;
        if (!binding_detail::FindEnumStringIndex<true>(cx, temp,
                                                                           binding_detail::EnumStrings<CompositeOperationOrAuto>::Values,
                                                                           "CompositeOperationOrAuto", "element of sequence<CompositeOperationOrAuto> branch of (CompositeOperationOrAuto or sequence<CompositeOperationOrAuto>)",
                                                                           &index)) {
          return false;
        }
        MOZ_ASSERT(index >= 0);
        slot = static_cast<CompositeOperationOrAuto>(index);
      }
    }
  }
  return true;
}

bool
CompositeOperationOrAutoOrCompositeOperationOrAutoSequence::TrySetToCompositeOperationOrAutoSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToCompositeOperationOrAutoSequence(cx, value, tryNext, passedToJSImpl);
}







bool
CompositeOperationOrAutoOrCompositeOperationOrAutoSequence::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  bool done = false, failed = false, tryNext;
  if (value.isObject()) {
    done = (failed = !TrySetToCompositeOperationOrAutoSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (!done) {
    do {
      done = (failed = !TrySetToCompositeOperationOrAuto(cx, value, tryNext)) || !tryNext;
      break;
    } while (false);
  }
  if (failed) {
    return false;
  }
  if (!done) {
    cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<CompositeOperationOrAuto>");
    return false;
  }
  return true;
}

bool
CompositeOperationOrAutoOrCompositeOperationOrAutoSequence::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}


bool
CompositeOperationOrAutoOrCompositeOperationOrAutoSequence::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
  switch (mType) {
    case eUninitialized: {
      return false;
    }
    case eCompositeOperationOrAuto: {
      if (!ToJSValue(cx, mValue.mCompositeOperationOrAuto.Value(), rval)) {
        return false;
      }
      return true;
    }
    case eCompositeOperationOrAutoSequence: {

      uint32_t length = mValue.mCompositeOperationOrAutoSequence.Value().Length();
      JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
      if (!returnArray) {
        return false;
      }
      // Scope for 'tmp'
      {
        JS::Rooted<JS::Value> tmp(cx);
        for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
          // Control block to let us common up the JS_DefineElement calls when there
          // are different ways to succeed at wrapping the object.
          do {
            if (!ToJSValue(cx, mValue.mCompositeOperationOrAutoSequence.Value()[sequenceIdx0], &tmp)) {
              return false;
            }
            break;
          } while (false);
          if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
                                JSPROP_ENUMERATE)) {
            return false;
          }
        }
      }
      rval.setObject(*returnArray);
      return true;
    }
    default: {
      return false;
    }
  }
}



OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence::OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence(OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence&& aOther)
  : mType(eUninitialized)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eCompositeOperationOrAuto: {
      mType = eCompositeOperationOrAuto;
      mValue.mCompositeOperationOrAuto.SetValue(std::move(aOther.mValue.mCompositeOperationOrAuto.Value()));
      break;
    }
    case eCompositeOperationOrAutoSequence: {
      mType = eCompositeOperationOrAutoSequence;
      mValue.mCompositeOperationOrAutoSequence.SetValue(std::move(aOther.mValue.mCompositeOperationOrAutoSequence.Value()));
      break;
    }
  }
}



bool
OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence::TrySetToCompositeOperationOrAuto(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    CompositeOperationOrAuto& memberSlot = RawSetAsCompositeOperationOrAuto();
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, value,
                                                                         binding_detail::EnumStrings<CompositeOperationOrAuto>::Values,
                                                                         "CompositeOperationOrAuto", "CompositeOperationOrAuto branch of (CompositeOperationOrAuto or sequence<CompositeOperationOrAuto>)",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      memberSlot = static_cast<CompositeOperationOrAuto>(index);
    }
  }
  return true;
}

bool
OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence::TrySetToCompositeOperationOrAuto(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToCompositeOperationOrAuto(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] CompositeOperationOrAuto&
OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence::RawSetAsCompositeOperationOrAuto()
{
  if (mType == eCompositeOperationOrAuto) {
    return mValue.mCompositeOperationOrAuto.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eCompositeOperationOrAuto;
  return mValue.mCompositeOperationOrAuto.SetValue();
}

[[nodiscard]] CompositeOperationOrAuto&
OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence::SetAsCompositeOperationOrAuto()
{
  if (mType == eCompositeOperationOrAuto) {
    return mValue.mCompositeOperationOrAuto.Value();
  }
  Uninit();
  mType = eCompositeOperationOrAuto;
  return mValue.mCompositeOperationOrAuto.SetValue();
}


void
OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence::DestroyCompositeOperationOrAuto()
{
  MOZ_RELEASE_ASSERT(IsCompositeOperationOrAuto(), "Wrong type!");
  mValue.mCompositeOperationOrAuto.Destroy();
  mType = eUninitialized;
}



bool
OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence::TrySetToCompositeOperationOrAutoSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    Sequence<CompositeOperationOrAuto>& memberSlot = RawSetAsCompositeOperationOrAutoSequence();
    JS::ForOfIterator iter(cx);
    if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
      return false;
    }
    if (!iter.valueIsIterable()) {
      DestroyCompositeOperationOrAutoSequence();
      tryNext = true;
      return true;
    }
    Sequence<CompositeOperationOrAuto> &arr = memberSlot;
    JS::Rooted<JS::Value> temp(cx);
    while (true) {
      bool done;
      if (!iter.next(&temp, &done)) {
        return false;
      }
      if (done) {
        break;
      }
      CompositeOperationOrAuto* slotPtr = arr.AppendElement(mozilla::fallible);
      if (!slotPtr) {
        JS_ReportOutOfMemory(cx);
        return false;
      }
      CompositeOperationOrAuto& slot = *slotPtr;
      {
        int index;
        if (!binding_detail::FindEnumStringIndex<true>(cx, temp,
                                                                           binding_detail::EnumStrings<CompositeOperationOrAuto>::Values,
                                                                           "CompositeOperationOrAuto", "element of sequence<CompositeOperationOrAuto> branch of (CompositeOperationOrAuto or sequence<CompositeOperationOrAuto>)",
                                                                           &index)) {
          return false;
        }
        MOZ_ASSERT(index >= 0);
        slot = static_cast<CompositeOperationOrAuto>(index);
      }
    }
  }
  return true;
}

bool
OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence::TrySetToCompositeOperationOrAutoSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToCompositeOperationOrAutoSequence(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] Sequence<CompositeOperationOrAuto>&
OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence::RawSetAsCompositeOperationOrAutoSequence()
{
  if (mType == eCompositeOperationOrAutoSequence) {
    return mValue.mCompositeOperationOrAutoSequence.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eCompositeOperationOrAutoSequence;
  return mValue.mCompositeOperationOrAutoSequence.SetValue();
}

[[nodiscard]] Sequence<CompositeOperationOrAuto>&
OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence::SetAsCompositeOperationOrAutoSequence()
{
  if (mType == eCompositeOperationOrAutoSequence) {
    return mValue.mCompositeOperationOrAutoSequence.Value();
  }
  Uninit();
  mType = eCompositeOperationOrAutoSequence;
  return mValue.mCompositeOperationOrAutoSequence.SetValue();
}


void
OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence::DestroyCompositeOperationOrAutoSequence()
{
  MOZ_RELEASE_ASSERT(IsCompositeOperationOrAutoSequence(), "Wrong type!");
  mValue.mCompositeOperationOrAutoSequence.Destroy();
  mType = eUninitialized;
}



bool
OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  bool done = false, failed = false, tryNext;
  if (value.isObject()) {
    done = (failed = !TrySetToCompositeOperationOrAutoSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (!done) {
    do {
      done = (failed = !TrySetToCompositeOperationOrAuto(cx, value, tryNext)) || !tryNext;
      break;
    } while (false);
  }
  if (failed) {
    return false;
  }
  if (!done) {
    cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<CompositeOperationOrAuto>");
    return false;
  }
  return true;
}

bool
OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}

void
OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence::Uninit()
{
  switch (mType) {
    case eUninitialized: {
      break;
    }
    case eCompositeOperationOrAuto: {
      DestroyCompositeOperationOrAuto();
      break;
    }
    case eCompositeOperationOrAutoSequence: {
      DestroyCompositeOperationOrAutoSequence();
      break;
    }
  }
}

bool
OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
  switch (mType) {
    case eUninitialized: {
      return false;
    }
    case eCompositeOperationOrAuto: {
      if (!ToJSValue(cx, mValue.mCompositeOperationOrAuto.Value(), rval)) {
        return false;
      }
      return true;
    }
    case eCompositeOperationOrAutoSequence: {

      uint32_t length = mValue.mCompositeOperationOrAutoSequence.Value().Length();
      JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
      if (!returnArray) {
        return false;
      }
      // Scope for 'tmp'
      {
        JS::Rooted<JS::Value> tmp(cx);
        for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
          // Control block to let us common up the JS_DefineElement calls when there
          // are different ways to succeed at wrapping the object.
          do {
            if (!ToJSValue(cx, mValue.mCompositeOperationOrAutoSequence.Value()[sequenceIdx0], &tmp)) {
              return false;
            }
            break;
          } while (false);
          if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
                                JSPROP_ENUMERATE)) {
            return false;
          }
        }
      }
      rval.setObject(*returnArray);
      return true;
    }
    default: {
      return false;
    }
  }
}

OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence&
OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence::operator=(OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence&& aOther)
{
  this->~OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence();
  new (this) OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence (std::move(aOther));
  return *this;
}


OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence&
OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence::operator=(const OwningCompositeOperationOrAutoOrCompositeOperationOrAutoSequence& aOther)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eCompositeOperationOrAuto: {
      SetAsCompositeOperationOrAuto() = aOther.GetAsCompositeOperationOrAuto();
      break;
    }
    case eCompositeOperationOrAutoSequence: {
      SetAsCompositeOperationOrAutoSequence() = aOther.GetAsCompositeOperationOrAutoSequence();
      break;
    }
  }
  return *this;
}


bool
DoubleOrNullOrDoubleOrNullSequence::TrySetToDouble(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    double& memberSlot = RawSetAsDouble();
    if (!ValueToPrimitive<double, eDefault>(cx, value, "Double branch of (double? or sequence<double?>)", &memberSlot)) {
      return false;
    } else if (!std::isfinite(memberSlot)) {
      cx.ThrowErrorMessage<MSG_NOT_FINITE>("Double branch of (double? or sequence<double?>)");
      return false;
    }
  }
  return true;
}

bool
DoubleOrNullOrDoubleOrNullSequence::TrySetToDouble(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToDouble(cx, value, tryNext, passedToJSImpl);
}







bool
DoubleOrNullOrDoubleOrNullSequence::TrySetToDoubleOrNullSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    binding_detail::AutoSequence<Nullable<double>>& memberSlot = RawSetAsDoubleOrNullSequence();
    JS::ForOfIterator iter(cx);
    if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
      return false;
    }
    if (!iter.valueIsIterable()) {
      DestroyDoubleOrNullSequence();
      tryNext = true;
      return true;
    }
    binding_detail::AutoSequence<Nullable<double>> &arr = memberSlot;
    JS::Rooted<JS::Value> temp(cx);
    while (true) {
      bool done;
      if (!iter.next(&temp, &done)) {
        return false;
      }
      if (done) {
        break;
      }
      Nullable<double>* slotPtr = arr.AppendElement(mozilla::fallible);
      if (!slotPtr) {
        JS_ReportOutOfMemory(cx);
        return false;
      }
      Nullable<double>& slot = *slotPtr;
      if (temp.isNullOrUndefined()) {
        slot.SetNull();
      } else if (!ValueToPrimitive<double, eDefault>(cx, temp, "Element of sequence<double?> branch of (double? or sequence<double?>)", &slot.SetValue())) {
        return false;
      } else if (!std::isfinite(slot.Value())) {
        cx.ThrowErrorMessage<MSG_NOT_FINITE>("Element of sequence<double?> branch of (double? or sequence<double?>)");
        return false;
      }
    }
  }
  return true;
}

bool
DoubleOrNullOrDoubleOrNullSequence::TrySetToDoubleOrNullSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToDoubleOrNullSequence(cx, value, tryNext, passedToJSImpl);
}







bool
DoubleOrNullOrDoubleOrNullSequence::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  if (value.isNullOrUndefined()) {
    SetNull();
  } else {
    bool done = false, failed = false, tryNext;
    if (value.isObject()) {
      done = (failed = !TrySetToDoubleOrNullSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
    }
    if (!done) {
      do {
        done = (failed = !TrySetToDouble(cx, value, tryNext)) || !tryNext;
        break;
      } while (false);
    }
    if (failed) {
      return false;
    }
    if (!done) {
      cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<double?>");
      return false;
    }
  }
  return true;
}

bool
DoubleOrNullOrDoubleOrNullSequence::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}


bool
DoubleOrNullOrDoubleOrNullSequence::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
  switch (mType) {
    case eUninitialized: {
      return false;
    }
    case eNull: {
      rval.setNull();
      return true;
    }
    case eDouble: {
      rval.set(JS_NumberValue(double(mValue.mDouble.Value())));
      return true;
    }
    case eDoubleOrNullSequence: {

      uint32_t length = mValue.mDoubleOrNullSequence.Value().Length();
      JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
      if (!returnArray) {
        return false;
      }
      // Scope for 'tmp'
      {
        JS::Rooted<JS::Value> tmp(cx);
        for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
          // Control block to let us common up the JS_DefineElement calls when there
          // are different ways to succeed at wrapping the object.
          do {
            if (mValue.mDoubleOrNullSequence.Value()[sequenceIdx0].IsNull()) {
              tmp.setNull();
              break;
            }
            tmp.set(JS_NumberValue(double(mValue.mDoubleOrNullSequence.Value()[sequenceIdx0].Value())));
            break;
          } while (false);
          if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
                                JSPROP_ENUMERATE)) {
            return false;
          }
        }
      }
      rval.setObject(*returnArray);
      return true;
    }
    default: {
      return false;
    }
  }
}



OwningDoubleOrNullOrDoubleOrNullSequence::OwningDoubleOrNullOrDoubleOrNullSequence(OwningDoubleOrNullOrDoubleOrNullSequence&& aOther)
  : mType(eUninitialized)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eNull: {
      MOZ_ASSERT(mType == eUninitialized);
      mType = eNull;
      break;
    }
    case eDouble: {
      mType = eDouble;
      mValue.mDouble.SetValue(std::move(aOther.mValue.mDouble.Value()));
      break;
    }
    case eDoubleOrNullSequence: {
      mType = eDoubleOrNullSequence;
      mValue.mDoubleOrNullSequence.SetValue(std::move(aOther.mValue.mDoubleOrNullSequence.Value()));
      break;
    }
  }
}





bool
OwningDoubleOrNullOrDoubleOrNullSequence::TrySetToDouble(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    double& memberSlot = RawSetAsDouble();
    if (!ValueToPrimitive<double, eDefault>(cx, value, "Double branch of (double? or sequence<double?>)", &memberSlot)) {
      return false;
    } else if (!std::isfinite(memberSlot)) {
      cx.ThrowErrorMessage<MSG_NOT_FINITE>("Double branch of (double? or sequence<double?>)");
      return false;
    }
  }
  return true;
}

bool
OwningDoubleOrNullOrDoubleOrNullSequence::TrySetToDouble(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToDouble(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] double&
OwningDoubleOrNullOrDoubleOrNullSequence::RawSetAsDouble()
{
  if (mType == eDouble) {
    return mValue.mDouble.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eDouble;
  return mValue.mDouble.SetValue();
}

[[nodiscard]] double&
OwningDoubleOrNullOrDoubleOrNullSequence::SetAsDouble()
{
  if (mType == eDouble) {
    return mValue.mDouble.Value();
  }
  Uninit();
  mType = eDouble;
  return mValue.mDouble.SetValue();
}


void
OwningDoubleOrNullOrDoubleOrNullSequence::DestroyDouble()
{
  MOZ_RELEASE_ASSERT(IsDouble(), "Wrong type!");
  mValue.mDouble.Destroy();
  mType = eUninitialized;
}



bool
OwningDoubleOrNullOrDoubleOrNullSequence::TrySetToDoubleOrNullSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    Sequence<Nullable<double>>& memberSlot = RawSetAsDoubleOrNullSequence();
    JS::ForOfIterator iter(cx);
    if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
      return false;
    }
    if (!iter.valueIsIterable()) {
      DestroyDoubleOrNullSequence();
      tryNext = true;
      return true;
    }
    Sequence<Nullable<double>> &arr = memberSlot;
    JS::Rooted<JS::Value> temp(cx);
    while (true) {
      bool done;
      if (!iter.next(&temp, &done)) {
        return false;
      }
      if (done) {
        break;
      }
      Nullable<double>* slotPtr = arr.AppendElement(mozilla::fallible);
      if (!slotPtr) {
        JS_ReportOutOfMemory(cx);
        return false;
      }
      Nullable<double>& slot = *slotPtr;
      if (temp.isNullOrUndefined()) {
        slot.SetNull();
      } else if (!ValueToPrimitive<double, eDefault>(cx, temp, "Element of sequence<double?> branch of (double? or sequence<double?>)", &slot.SetValue())) {
        return false;
      } else if (!std::isfinite(slot.Value())) {
        cx.ThrowErrorMessage<MSG_NOT_FINITE>("Element of sequence<double?> branch of (double? or sequence<double?>)");
        return false;
      }
    }
  }
  return true;
}

bool
OwningDoubleOrNullOrDoubleOrNullSequence::TrySetToDoubleOrNullSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToDoubleOrNullSequence(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] Sequence<Nullable<double>>&
OwningDoubleOrNullOrDoubleOrNullSequence::RawSetAsDoubleOrNullSequence()
{
  if (mType == eDoubleOrNullSequence) {
    return mValue.mDoubleOrNullSequence.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eDoubleOrNullSequence;
  return mValue.mDoubleOrNullSequence.SetValue();
}

[[nodiscard]] Sequence<Nullable<double>>&
OwningDoubleOrNullOrDoubleOrNullSequence::SetAsDoubleOrNullSequence()
{
  if (mType == eDoubleOrNullSequence) {
    return mValue.mDoubleOrNullSequence.Value();
  }
  Uninit();
  mType = eDoubleOrNullSequence;
  return mValue.mDoubleOrNullSequence.SetValue();
}


void
OwningDoubleOrNullOrDoubleOrNullSequence::DestroyDoubleOrNullSequence()
{
  MOZ_RELEASE_ASSERT(IsDoubleOrNullSequence(), "Wrong type!");
  mValue.mDoubleOrNullSequence.Destroy();
  mType = eUninitialized;
}



bool
OwningDoubleOrNullOrDoubleOrNullSequence::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  if (value.isNullOrUndefined()) {
    SetNull();
  } else {
    bool done = false, failed = false, tryNext;
    if (value.isObject()) {
      done = (failed = !TrySetToDoubleOrNullSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
    }
    if (!done) {
      do {
        done = (failed = !TrySetToDouble(cx, value, tryNext)) || !tryNext;
        break;
      } while (false);
    }
    if (failed) {
      return false;
    }
    if (!done) {
      cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<double?>");
      return false;
    }
  }
  return true;
}

bool
OwningDoubleOrNullOrDoubleOrNullSequence::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}

void
OwningDoubleOrNullOrDoubleOrNullSequence::Uninit()
{
  switch (mType) {
    case eUninitialized: {
      break;
    }
    case eNull: {
      break;
    }
    case eDouble: {
      DestroyDouble();
      break;
    }
    case eDoubleOrNullSequence: {
      DestroyDoubleOrNullSequence();
      break;
    }
  }
}

bool
OwningDoubleOrNullOrDoubleOrNullSequence::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
  switch (mType) {
    case eUninitialized: {
      return false;
    }
    case eNull: {
      rval.setNull();
      return true;
    }
    case eDouble: {
      rval.set(JS_NumberValue(double(mValue.mDouble.Value())));
      return true;
    }
    case eDoubleOrNullSequence: {

      uint32_t length = mValue.mDoubleOrNullSequence.Value().Length();
      JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
      if (!returnArray) {
        return false;
      }
      // Scope for 'tmp'
      {
        JS::Rooted<JS::Value> tmp(cx);
        for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
          // Control block to let us common up the JS_DefineElement calls when there
          // are different ways to succeed at wrapping the object.
          do {
            if (mValue.mDoubleOrNullSequence.Value()[sequenceIdx0].IsNull()) {
              tmp.setNull();
              break;
            }
            tmp.set(JS_NumberValue(double(mValue.mDoubleOrNullSequence.Value()[sequenceIdx0].Value())));
            break;
          } while (false);
          if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
                                JSPROP_ENUMERATE)) {
            return false;
          }
        }
      }
      rval.setObject(*returnArray);
      return true;
    }
    default: {
      return false;
    }
  }
}

OwningDoubleOrNullOrDoubleOrNullSequence&
OwningDoubleOrNullOrDoubleOrNullSequence::operator=(OwningDoubleOrNullOrDoubleOrNullSequence&& aOther)
{
  this->~OwningDoubleOrNullOrDoubleOrNullSequence();
  new (this) OwningDoubleOrNullOrDoubleOrNullSequence (std::move(aOther));
  return *this;
}


OwningDoubleOrNullOrDoubleOrNullSequence&
OwningDoubleOrNullOrDoubleOrNullSequence::operator=(const OwningDoubleOrNullOrDoubleOrNullSequence& aOther)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eNull: {
      MOZ_ASSERT(mType == eUninitialized);
      mType = eNull;
      break;
    }
    case eDouble: {
      SetAsDouble() = aOther.GetAsDouble();
      break;
    }
    case eDoubleOrNullSequence: {
      SetAsDoubleOrNullSequence() = aOther.GetAsDoubleOrNullSequence();
      break;
    }
  }
  return *this;
}



BaseComputedKeyframe::BaseComputedKeyframe()
  : BaseKeyframe(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init();
}




bool
BaseComputedKeyframe::InitIds(JSContext* cx, BaseComputedKeyframeAtoms* atomsCache)
{
  MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->computedOffset_id.init(cx, "computedOffset")) {
    return false;
  }
  return true;
}

bool
BaseComputedKeyframe::Init(const char* sourceDescription, bool passedToJSImpl)
{
  // We init the parent's members first
  if (!BaseKeyframe::Init(nullptr, JS::NullHandleValue)) {
    return false;
  }

  return true;
}

bool
BaseComputedKeyframe::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  BaseComputedKeyframeAtoms* atomsCache = GetAtomCache<BaseComputedKeyframeAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  // Per spec, we define the parent's members first
  if (!BaseKeyframe::ToObjectInternal(cx, rval)) {
    return false;
  }
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());

  if (mComputedOffset.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      double const & currentValue = mComputedOffset.InternalValue();
      temp.set(JS_NumberValue(double(currentValue)));
      if (!JS_DefinePropertyById(cx, obj, atomsCache->computedOffset_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

void
BaseComputedKeyframe::TraceDictionary(JSTracer* trc)
{
  BaseKeyframe::TraceDictionary(trc);
}

BaseComputedKeyframe&
BaseComputedKeyframe::operator=(const BaseComputedKeyframe& aOther)
{
  BaseKeyframe::operator=(aOther);
  mComputedOffset.Reset();
  if (aOther.mComputedOffset.WasPassed()) {
    mComputedOffset.Construct(aOther.mComputedOffset.Value());
  }
  return *this;
}



BasePropertyIndexedKeyframe::BasePropertyIndexedKeyframe()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




bool
BasePropertyIndexedKeyframe::InitIds(JSContext* cx, BasePropertyIndexedKeyframeAtoms* atomsCache)
{
  MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->offset_id.init(cx, "offset") ||
      !atomsCache->easing_id.init(cx, "easing") ||
      !atomsCache->composite_id.init(cx, "composite")) {
    return false;
  }
  return true;
}

bool
BasePropertyIndexedKeyframe::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  BasePropertyIndexedKeyframeAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<BasePropertyIndexedKeyframeAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->composite_id, temp.ptr())) {
      return false;
    }
  }
  mComposite.Uninit();
  if (!(!isNull && !temp->isUndefined())) {
    (void)mComposite.RawSetAsCompositeOperationOrAutoSequence();
  } else {
    if (!mComposite.Init(cx, temp.ref(), "'composite' member of BasePropertyIndexedKeyframe", passedToJSImpl)) {
      return false;
    }
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->easing_id, temp.ptr())) {
      return false;
    }
  }
  mEasing.Uninit();
  if (!(!isNull && !temp->isUndefined())) {
    (void)mEasing.RawSetAsUTF8StringSequence();
  } else {
    if (!mEasing.Init(cx, temp.ref(), "'easing' member of BasePropertyIndexedKeyframe", passedToJSImpl)) {
      return false;
    }
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->offset_id, temp.ptr())) {
      return false;
    }
  }
  mOffset.Uninit();
  if (!(!isNull && !temp->isUndefined())) {
    (void)mOffset.RawSetAsDoubleOrNullSequence();
  } else {
    if (!mOffset.Init(cx, temp.ref(), "'offset' member of BasePropertyIndexedKeyframe", passedToJSImpl)) {
      return false;
    }
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
BasePropertyIndexedKeyframe::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
BasePropertyIndexedKeyframe::TraceDictionary(JSTracer* trc)
{
}

BasePropertyIndexedKeyframe&
BasePropertyIndexedKeyframe::operator=(const BasePropertyIndexedKeyframe& aOther)
{
  DictionaryBase::operator=(aOther);
  mComposite = aOther.mComposite;
  mEasing = aOther.mEasing;
  mOffset = aOther.mOffset;
  return *this;
}


} // namespace dom


} // namespace mozilla
