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

#include "EventHandlerBinding.h"
#include "mozilla/OwningNonNull.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/NonRefcountedDOMObject.h"
#include "mozilla/dom/Nullable.h"
#include "mozilla/dom/PrimitiveConversions.h"
#include "mozilla/dom/UnionConversions.h"

namespace mozilla {
namespace dom {

void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningEventOrString& aUnion, const char* aName, uint32_t aFlags)
{
  if (aUnion.IsEvent()) {
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsEvent(), "mEvent", aFlags);
  }
}


void
ImplCycleCollectionUnlink(OwningEventOrString& aUnion)
{
  aUnion.Uninit();
}


bool
EventOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
  switch (mType) {
    case eUninitialized: {
      return false;
      break;
    }
    case eEvent: {
      if (!GetOrCreateDOMReflector(cx, mValue.mEvent.Value(), rval)) {
        MOZ_ASSERT(true || JS_IsExceptionPending(cx));
        return false;
      }
      return true;
      break;
    }
    case eString: {
      if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
        return false;
      }
      return true;
      break;
    }
    default: {
      return false;
      break;
    }
  }

  return false;
}


OwningNonNull<mozilla::dom::Event>&
OwningEventOrString::RawSetAsEvent()
{
  if (mType == eEvent) {
    return mValue.mEvent.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eEvent;
  return mValue.mEvent.SetValue();
}

OwningNonNull<mozilla::dom::Event>&
OwningEventOrString::SetAsEvent()
{
  if (mType == eEvent) {
    return mValue.mEvent.Value();
  }
  Uninit();
  mType = eEvent;
  return mValue.mEvent.SetValue();
}

bool
OwningEventOrString::TrySetToEvent(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    OwningNonNull<mozilla::dom::Event>& memberSlot = RawSetAsEvent();
    static_assert(IsRefcounted<mozilla::dom::Event>::value, "We can only store refcounted classes.");{
      nsresult rv = UnwrapObject<prototypes::id::Event, mozilla::dom::Event>(value, memberSlot);
      if (NS_FAILED(rv)) {
        DestroyEvent();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

void
OwningEventOrString::DestroyEvent()
{
  MOZ_ASSERT(IsEvent(), "Wrong type!");
  mValue.mEvent.Destroy();
  mType = eUninitialized;
}




nsString&
OwningEventOrString::RawSetAsString()
{
  if (mType == eString) {
    return mValue.mString.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eString;
  return mValue.mString.SetValue();
}

nsString&
OwningEventOrString::SetAsString()
{
  if (mType == eString) {
    return mValue.mString.Value();
  }
  Uninit();
  mType = eString;
  return mValue.mString.SetValue();
}

bool
OwningEventOrString::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    nsString& memberSlot = RawSetAsString();
    if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
      return false;
    }
  }
  return true;
}


void
OwningEventOrString::DestroyString()
{
  MOZ_ASSERT(IsString(), "Wrong type!");
  mValue.mString.Destroy();
  mType = eUninitialized;
}




void
OwningEventOrString::Uninit()
{
  switch (mType) {
    case eUninitialized: {
      break;
    }
    case eEvent: {
      DestroyEvent();
      break;
    }
    case eString: {
      DestroyString();
      break;
    }
  }
}

bool
OwningEventOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
  switch (mType) {
    case eUninitialized: {
      return false;
      break;
    }
    case eEvent: {
      if (!GetOrCreateDOMReflector(cx, mValue.mEvent.Value(), rval)) {
        MOZ_ASSERT(true || JS_IsExceptionPending(cx));
        return false;
      }
      return true;
      break;
    }
    case eString: {
      if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
        return false;
      }
      return true;
      break;
    }
    default: {
      return false;
      break;
    }
  }

  return false;
}

void
OwningEventOrString::TraceUnion(JSTracer* trc)
{
}

void
OwningEventOrString::operator=(const OwningEventOrString& aOther)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eEvent: {
      SetAsEvent() = aOther.GetAsEvent();
      break;
    }
    case eString: {
      SetAsString() = aOther.GetAsString();
      break;
    }
  }
}


void
EventHandlerNonNull::Call(JSContext* cx, JS::Handle<JS::Value> aThisVal, Event& event, JS::MutableHandle<JS::Value> aRetVal, ErrorResult& aRv)
{
  JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
  JS::AutoValueVector argv(cx);
  if (!argv.resize(1)) {
    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    return;
  }
  unsigned argc = 1;

  do {
    if (!GetOrCreateDOMReflector(cx, event, argv[0])) {
      MOZ_ASSERT(true || JS_IsExceptionPending(cx));
      aRv.Throw(NS_ERROR_UNEXPECTED);
      return;
    }
    break;
  } while (0);

  JS::Rooted<JS::Value> callable(cx, JS::ObjectValue(*mCallback));
  if (JS::IsCallable(mCallback) && !JS::Call(cx, aThisVal, callable,
                JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    aRv.NoteJSContextException(cx);
    return;
  }
  JS::Rooted<JS::Value> rvalDecl(cx);
  if ((false) && !CallerSubsumes(rval)) {
    ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "return value of EventHandlerNonNull");
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }
  rvalDecl = rval;
  aRetVal.set(rvalDecl);
}



void
OnBeforeUnloadEventHandlerNonNull::Call(JSContext* cx, JS::Handle<JS::Value> aThisVal, Event& event, nsString& aRetVal, ErrorResult& aRv)
{
  JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
  JS::AutoValueVector argv(cx);
  if (!argv.resize(1)) {
    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    return;
  }
  unsigned argc = 1;

  do {
    if (!GetOrCreateDOMReflector(cx, event, argv[0])) {
      MOZ_ASSERT(true || JS_IsExceptionPending(cx));
      aRv.Throw(NS_ERROR_UNEXPECTED);
      return;
    }
    break;
  } while (0);

  JS::Rooted<JS::Value> callable(cx, JS::ObjectValue(*mCallback));
  if (JS::IsCallable(mCallback) && !JS::Call(cx, aThisVal, callable,
                JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    aRv.NoteJSContextException(cx);
    return;
  }
  binding_detail::FakeString rvalDecl;
  if (!ConvertJSValueToString(cx, rval, eNull, eNull, rvalDecl)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }
  aRetVal = rvalDecl;
}



bool
OnErrorEventHandlerNonNull::Call(JSContext* cx, JS::Handle<JS::Value> aThisVal, const EventOrString& event, const Optional<nsAString>& source, const Optional<uint32_t>& lineno, const Optional<uint32_t>& column, const Optional<JS::Handle<JS::Value>>& error, ErrorResult& aRv)
{
  JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
  JS::AutoValueVector argv(cx);
  if (!argv.resize(5)) {
    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    return bool(0);
  }
  unsigned argc = 5;

  do {
    if (error.WasPassed()) {
      JS::ExposeValueToActiveJS(error.Value());
      argv[4].set(error.Value());
      if (!MaybeWrapValue(cx, argv[4])) {
        aRv.Throw(NS_ERROR_UNEXPECTED);
        return bool(0);
      }
      break;
    } else if (argc == 5) {
      // This is our current trailing argument; reduce argc
      --argc;
    } else {
      argv[4].setUndefined();
    }
  } while (0);

  do {
    if (column.WasPassed()) {
      argv[3].setNumber(column.Value());
      break;
    } else if (argc == 4) {
      // This is our current trailing argument; reduce argc
      --argc;
    } else {
      argv[3].setUndefined();
    }
  } while (0);

  do {
    if (lineno.WasPassed()) {
      argv[2].setNumber(lineno.Value());
      break;
    } else if (argc == 3) {
      // This is our current trailing argument; reduce argc
      --argc;
    } else {
      argv[2].setUndefined();
    }
  } while (0);

  do {
    if (source.WasPassed()) {
      nsString mutableStr(source.Value());
      if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[1])) {
        aRv.Throw(NS_ERROR_UNEXPECTED);
        return bool(0);
      }
      break;
    } else if (argc == 2) {
      // This is our current trailing argument; reduce argc
      --argc;
    } else {
      argv[1].setUndefined();
    }
  } while (0);

  do {
    if (!event.ToJSVal(cx, CallbackKnownNotGray(), argv[0])) {
      aRv.Throw(NS_ERROR_UNEXPECTED);
      return bool(0);
    }
    break;
  } while (0);

  JS::Rooted<JS::Value> callable(cx, JS::ObjectValue(*mCallback));
  if (JS::IsCallable(mCallback) && !JS::Call(cx, aThisVal, callable,
                JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    aRv.NoteJSContextException(cx);
    return bool(0);
  }
  bool rvalDecl;
  if (!ValueToPrimitive<bool, eDefault>(cx, rval, &rvalDecl)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return bool(0);
  }
  return rvalDecl;
}



namespace binding_detail {
} // namespace binding_detail


namespace binding_detail {
} // namespace binding_detail


namespace binding_detail {
} // namespace binding_detail


} // namespace dom
} // namespace mozilla
