/*
    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 "HTMLDocument.h"
#include "JSDocument.h"

namespace WebCore {

class JSHTMLDocument : public JSDocument {
public:
    typedef JSDocument Base;
    typedef HTMLDocument DOMWrapped;
    static JSHTMLDocument* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<HTMLDocument>&& impl)
    {
        JSHTMLDocument* ptr = new (NotNull, JSC::allocateCell<JSHTMLDocument>(globalObject->vm().heap)) JSHTMLDocument(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*);
    static bool getOwnPropertySlot(JSC::JSObject*, JSC::ExecState*, JSC::PropertyName, JSC::PropertySlot&);
    static bool getOwnPropertySlotByIndex(JSC::JSObject*, JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&);

    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(JSDocumentWrapperType), StructureFlags), info());
    }

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


    // Custom attributes
    JSC::JSValue all(JSC::ExecState&) const;
    void setAll(JSC::ExecState&, JSC::JSValue);

    // Custom functions
    JSC::JSValue open(JSC::ExecState&);
    JSC::JSValue write(JSC::ExecState&);
    JSC::JSValue writeln(JSC::ExecState&);
    HTMLDocument& wrapped() const
    {
        return static_cast<HTMLDocument&>(Base::wrapped());
    }
public:
    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpure | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::NewImpurePropertyFiresWatchpoints | JSC::OverridesGetOwnPropertySlot | Base::StructureFlags;
protected:
    JSHTMLDocument(JSC::Structure*, JSDOMGlobalObject&, Ref<HTMLDocument>&&);

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

private:
    bool nameGetter(JSC::ExecState*, JSC::PropertyName, JSC::JSValue&);
};

JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, HTMLDocument&);
inline JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, HTMLDocument* impl) { return impl ? toJS(state, globalObject, *impl) : JSC::jsNull(); }
JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject*, Ref<HTMLDocument>&&);
inline JSC::JSValue toJSNewlyCreated(JSC::ExecState* state, JSDOMGlobalObject* globalObject, RefPtr<HTMLDocument>&& impl) { return impl ? toJSNewlyCreated(state, globalObject, impl.releaseNonNull()) : JSC::jsNull(); }

// Functions

JSC::EncodedJSValue JSC_HOST_CALL jsHTMLDocumentPrototypeFunctionOpen(JSC::ExecState*);

template<> struct JSDOMWrapperConverterTraits<HTMLDocument> {
    using WrapperClass = JSHTMLDocument;
};

} // namespace WebCore
