/*
    This file is part of the WebKit open source project.
    This file has been generated by generate-bindings.pl. DO NOT MODIFY!

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "config.h"
#include "JSXMLHttpRequestEventTarget.h"

#include "EventNames.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructor.h"
#include "JSEventListener.h"
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

// Attributes

JSC::EncodedJSValue jsXMLHttpRequestEventTargetOnloadstart(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSXMLHttpRequestEventTargetOnloadstart(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsXMLHttpRequestEventTargetOnprogress(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSXMLHttpRequestEventTargetOnprogress(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsXMLHttpRequestEventTargetOnabort(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSXMLHttpRequestEventTargetOnabort(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsXMLHttpRequestEventTargetOnerror(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSXMLHttpRequestEventTargetOnerror(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsXMLHttpRequestEventTargetOnload(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSXMLHttpRequestEventTargetOnload(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsXMLHttpRequestEventTargetOntimeout(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSXMLHttpRequestEventTargetOntimeout(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsXMLHttpRequestEventTargetOnloadend(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSXMLHttpRequestEventTargetOnloadend(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsXMLHttpRequestEventTargetConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSXMLHttpRequestEventTargetConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);

class JSXMLHttpRequestEventTargetPrototype : public JSC::JSNonFinalObject {
public:
    typedef JSC::JSNonFinalObject Base;
    static JSXMLHttpRequestEventTargetPrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
    {
        JSXMLHttpRequestEventTargetPrototype* ptr = new (NotNull, JSC::allocateCell<JSXMLHttpRequestEventTargetPrototype>(vm.heap)) JSXMLHttpRequestEventTargetPrototype(vm, globalObject, structure);
        ptr->finishCreation(vm);
        return ptr;
    }

    DECLARE_INFO;
    static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
    {
        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
    }

private:
    JSXMLHttpRequestEventTargetPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
        : JSC::JSNonFinalObject(vm, structure)
    {
    }

    void finishCreation(JSC::VM&);
};

typedef JSDOMConstructorNotConstructable<JSXMLHttpRequestEventTarget> JSXMLHttpRequestEventTargetConstructor;

template<> JSValue JSXMLHttpRequestEventTargetConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
{
    return JSEventTarget::getConstructor(vm, &globalObject);
}

template<> void JSXMLHttpRequestEventTargetConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
{
    putDirect(vm, vm.propertyNames->prototype, JSXMLHttpRequestEventTarget::prototype(vm, &globalObject), DontDelete | ReadOnly | DontEnum);
    putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String(ASCIILiteral("XMLHttpRequestEventTarget"))), ReadOnly | DontEnum);
    putDirect(vm, vm.propertyNames->length, jsNumber(0), ReadOnly | DontEnum);
}

template<> const ClassInfo JSXMLHttpRequestEventTargetConstructor::s_info = { "XMLHttpRequestEventTarget", &Base::s_info, 0, CREATE_METHOD_TABLE(JSXMLHttpRequestEventTargetConstructor) };

/* Hash table for prototype */

static const HashTableValue JSXMLHttpRequestEventTargetPrototypeTableValues[] =
{
    { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsXMLHttpRequestEventTargetConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSXMLHttpRequestEventTargetConstructor) } },
    { "onloadstart", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsXMLHttpRequestEventTargetOnloadstart), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSXMLHttpRequestEventTargetOnloadstart) } },
    { "onprogress", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsXMLHttpRequestEventTargetOnprogress), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSXMLHttpRequestEventTargetOnprogress) } },
    { "onabort", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsXMLHttpRequestEventTargetOnabort), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSXMLHttpRequestEventTargetOnabort) } },
    { "onerror", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsXMLHttpRequestEventTargetOnerror), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSXMLHttpRequestEventTargetOnerror) } },
    { "onload", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsXMLHttpRequestEventTargetOnload), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSXMLHttpRequestEventTargetOnload) } },
    { "ontimeout", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsXMLHttpRequestEventTargetOntimeout), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSXMLHttpRequestEventTargetOntimeout) } },
    { "onloadend", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsXMLHttpRequestEventTargetOnloadend), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSXMLHttpRequestEventTargetOnloadend) } },
};

const ClassInfo JSXMLHttpRequestEventTargetPrototype::s_info = { "XMLHttpRequestEventTargetPrototype", &Base::s_info, 0, CREATE_METHOD_TABLE(JSXMLHttpRequestEventTargetPrototype) };

void JSXMLHttpRequestEventTargetPrototype::finishCreation(VM& vm)
{
    Base::finishCreation(vm);
    reifyStaticProperties(vm, JSXMLHttpRequestEventTargetPrototypeTableValues, *this);
}

const ClassInfo JSXMLHttpRequestEventTarget::s_info = { "XMLHttpRequestEventTarget", &Base::s_info, 0, CREATE_METHOD_TABLE(JSXMLHttpRequestEventTarget) };

JSXMLHttpRequestEventTarget::JSXMLHttpRequestEventTarget(Structure* structure, JSDOMGlobalObject& globalObject, Ref<XMLHttpRequestEventTarget>&& impl)
    : JSEventTarget(structure, globalObject, WTFMove(impl))
{
}

JSObject* JSXMLHttpRequestEventTarget::createPrototype(VM& vm, JSGlobalObject* globalObject)
{
    return JSXMLHttpRequestEventTargetPrototype::create(vm, globalObject, JSXMLHttpRequestEventTargetPrototype::createStructure(vm, globalObject, JSEventTarget::prototype(vm, globalObject)));
}

JSObject* JSXMLHttpRequestEventTarget::prototype(VM& vm, JSGlobalObject* globalObject)
{
    return getDOMPrototype<JSXMLHttpRequestEventTarget>(vm, globalObject);
}

EncodedJSValue jsXMLHttpRequestEventTargetOnloadstart(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSXMLHttpRequestEventTarget*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "XMLHttpRequestEventTarget", "onloadstart");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().loadstartEvent));
}


EncodedJSValue jsXMLHttpRequestEventTargetOnprogress(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSXMLHttpRequestEventTarget*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "XMLHttpRequestEventTarget", "onprogress");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().progressEvent));
}


EncodedJSValue jsXMLHttpRequestEventTargetOnabort(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSXMLHttpRequestEventTarget*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "XMLHttpRequestEventTarget", "onabort");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().abortEvent));
}


EncodedJSValue jsXMLHttpRequestEventTargetOnerror(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSXMLHttpRequestEventTarget*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "XMLHttpRequestEventTarget", "onerror");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().errorEvent));
}


EncodedJSValue jsXMLHttpRequestEventTargetOnload(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSXMLHttpRequestEventTarget*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "XMLHttpRequestEventTarget", "onload");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().loadEvent));
}


EncodedJSValue jsXMLHttpRequestEventTargetOntimeout(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSXMLHttpRequestEventTarget*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "XMLHttpRequestEventTarget", "ontimeout");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().timeoutEvent));
}


EncodedJSValue jsXMLHttpRequestEventTargetOnloadend(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSXMLHttpRequestEventTarget*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "XMLHttpRequestEventTarget", "onloadend");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().loadendEvent));
}


EncodedJSValue jsXMLHttpRequestEventTargetConstructor(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSXMLHttpRequestEventTargetPrototype* domObject = jsDynamicCast<JSXMLHttpRequestEventTargetPrototype*>(JSValue::decode(thisValue));
    if (UNLIKELY(!domObject))
        return throwVMTypeError(state, throwScope);
    return JSValue::encode(JSXMLHttpRequestEventTarget::getConstructor(state->vm(), domObject->globalObject()));
}

bool setJSXMLHttpRequestEventTargetConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSValue value = JSValue::decode(encodedValue);
    JSXMLHttpRequestEventTargetPrototype* domObject = jsDynamicCast<JSXMLHttpRequestEventTargetPrototype*>(JSValue::decode(thisValue));
    if (UNLIKELY(!domObject)) {
        throwVMTypeError(state, throwScope);
        return false;
    }
    // Shadowing a built-in constructor
    return domObject->putDirect(state->vm(), state->propertyNames().constructor, value);
}

bool setJSXMLHttpRequestEventTargetOnloadstart(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSXMLHttpRequestEventTarget* castedThis = jsDynamicCast<JSXMLHttpRequestEventTarget*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "XMLHttpRequestEventTarget", "onloadstart");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().loadstartEvent, value);
    return true;
}


bool setJSXMLHttpRequestEventTargetOnprogress(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSXMLHttpRequestEventTarget* castedThis = jsDynamicCast<JSXMLHttpRequestEventTarget*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "XMLHttpRequestEventTarget", "onprogress");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().progressEvent, value);
    return true;
}


bool setJSXMLHttpRequestEventTargetOnabort(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSXMLHttpRequestEventTarget* castedThis = jsDynamicCast<JSXMLHttpRequestEventTarget*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "XMLHttpRequestEventTarget", "onabort");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().abortEvent, value);
    return true;
}


bool setJSXMLHttpRequestEventTargetOnerror(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSXMLHttpRequestEventTarget* castedThis = jsDynamicCast<JSXMLHttpRequestEventTarget*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "XMLHttpRequestEventTarget", "onerror");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().errorEvent, value);
    return true;
}


bool setJSXMLHttpRequestEventTargetOnload(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSXMLHttpRequestEventTarget* castedThis = jsDynamicCast<JSXMLHttpRequestEventTarget*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "XMLHttpRequestEventTarget", "onload");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().loadEvent, value);
    return true;
}


bool setJSXMLHttpRequestEventTargetOntimeout(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSXMLHttpRequestEventTarget* castedThis = jsDynamicCast<JSXMLHttpRequestEventTarget*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "XMLHttpRequestEventTarget", "ontimeout");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().timeoutEvent, value);
    return true;
}


bool setJSXMLHttpRequestEventTargetOnloadend(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSXMLHttpRequestEventTarget* castedThis = jsDynamicCast<JSXMLHttpRequestEventTarget*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "XMLHttpRequestEventTarget", "onloadend");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().loadendEvent, value);
    return true;
}


JSValue JSXMLHttpRequestEventTarget::getConstructor(VM& vm, const JSGlobalObject* globalObject)
{
    return getDOMConstructor<JSXMLHttpRequestEventTargetConstructor>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
}

void JSXMLHttpRequestEventTarget::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
    auto* thisObject = jsCast<JSXMLHttpRequestEventTarget*>(cell);
    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
    Base::visitChildren(thisObject, visitor);
    thisObject->wrapped().visitJSEventListeners(visitor);
}

XMLHttpRequestEventTarget* JSXMLHttpRequestEventTarget::toWrapped(JSC::JSValue value)
{
    if (auto* wrapper = jsDynamicCast<JSXMLHttpRequestEventTarget*>(value))
        return &wrapper->wrapped();
    return nullptr;
}

}
