/*
    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 "JSHTMLHtmlElement.h"

#include "HTMLNames.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructor.h"
#include "URL.h"
#include <runtime/JSString.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

// Attributes

JSC::EncodedJSValue jsHTMLHtmlElementVersion(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSHTMLHtmlElementVersion(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsHTMLHtmlElementManifest(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSHTMLHtmlElementManifest(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsHTMLHtmlElementConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSHTMLHtmlElementConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);

class JSHTMLHtmlElementPrototype : public JSC::JSNonFinalObject {
public:
    typedef JSC::JSNonFinalObject Base;
    static JSHTMLHtmlElementPrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
    {
        JSHTMLHtmlElementPrototype* ptr = new (NotNull, JSC::allocateCell<JSHTMLHtmlElementPrototype>(vm.heap)) JSHTMLHtmlElementPrototype(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:
    JSHTMLHtmlElementPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
        : JSC::JSNonFinalObject(vm, structure)
    {
    }

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

typedef JSDOMConstructorNotConstructable<JSHTMLHtmlElement> JSHTMLHtmlElementConstructor;

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

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

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

/* Hash table for prototype */

static const HashTableValue JSHTMLHtmlElementPrototypeTableValues[] =
{
    { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLHtmlElementConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSHTMLHtmlElementConstructor) } },
    { "version", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLHtmlElementVersion), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSHTMLHtmlElementVersion) } },
    { "manifest", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLHtmlElementManifest), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSHTMLHtmlElementManifest) } },
};

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

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

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

JSHTMLHtmlElement::JSHTMLHtmlElement(Structure* structure, JSDOMGlobalObject& globalObject, Ref<HTMLHtmlElement>&& impl)
    : JSHTMLElement(structure, globalObject, WTFMove(impl))
{
}

JSObject* JSHTMLHtmlElement::createPrototype(VM& vm, JSGlobalObject* globalObject)
{
    return JSHTMLHtmlElementPrototype::create(vm, globalObject, JSHTMLHtmlElementPrototype::createStructure(vm, globalObject, JSHTMLElement::prototype(vm, globalObject)));
}

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

EncodedJSValue jsHTMLHtmlElementVersion(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<JSHTMLHtmlElement*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "HTMLHtmlElement", "version");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.attributeWithoutSynchronization(WebCore::HTMLNames::versionAttr));
    return JSValue::encode(result);
}


EncodedJSValue jsHTMLHtmlElementManifest(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<JSHTMLHtmlElement*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "HTMLHtmlElement", "manifest");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.getURLAttribute(WebCore::HTMLNames::manifestAttr));
    return JSValue::encode(result);
}


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

bool setJSHTMLHtmlElementConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSValue value = JSValue::decode(encodedValue);
    JSHTMLHtmlElementPrototype* domObject = jsDynamicCast<JSHTMLHtmlElementPrototype*>(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 setJSHTMLHtmlElementVersion(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);
    JSHTMLHtmlElement* castedThis = jsDynamicCast<JSHTMLHtmlElement*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "HTMLHtmlElement", "version");
    }
    auto& impl = castedThis->wrapped();
    auto nativeValue = value.toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, false);
    impl.setAttributeWithoutSynchronization(WebCore::HTMLNames::versionAttr, WTFMove(nativeValue));
    return true;
}


bool setJSHTMLHtmlElementManifest(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);
    JSHTMLHtmlElement* castedThis = jsDynamicCast<JSHTMLHtmlElement*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "HTMLHtmlElement", "manifest");
    }
    auto& impl = castedThis->wrapped();
    auto nativeValue = value.toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, false);
    impl.setAttributeWithoutSynchronization(WebCore::HTMLNames::manifestAttr, WTFMove(nativeValue));
    return true;
}


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

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


}
