/*
    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.
*/

#pragma once

#include "HTMLOptGroupElement.h"
#include "JSHTMLElement.h"

namespace WebCore {

class JSHTMLOptGroupElement : public JSHTMLElement {
public:
    typedef JSHTMLElement Base;
    typedef HTMLOptGroupElement DOMWrapped;
    static JSHTMLOptGroupElement* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<HTMLOptGroupElement>&& impl)
    {
        JSHTMLOptGroupElement* ptr = new (NotNull, JSC::allocateCell<JSHTMLOptGroupElement>(globalObject->vm().heap)) JSHTMLOptGroupElement(structure, *globalObject, WTFMove(impl));
        ptr->finishCreation(globalObject->vm());
        return ptr;
    }

    static JSC::JSObject* createPrototype(JSC::VM&, JSC::JSGlobalObject*);
    static JSC::JSObject* prototype(JSC::VM&, JSC::JSGlobalObject*);

    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::JSType(JSElementType), StructureFlags), info());
    }

    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
    static void visitChildren(JSCell*, JSC::SlotVisitor&);

    HTMLOptGroupElement& wrapped() const
    {
        return static_cast<HTMLOptGroupElement&>(Base::wrapped());
    }
protected:
    JSHTMLOptGroupElement(JSC::Structure*, JSDOMGlobalObject&, Ref<HTMLOptGroupElement>&&);

    void finishCreation(JSC::VM& vm)
    {
        Base::finishCreation(vm);
        ASSERT(inherits(info()));
    }

};


template<> struct JSDOMWrapperConverterTraits<HTMLOptGroupElement> {
    using WrapperClass = JSHTMLOptGroupElement;
};

} // namespace WebCore
