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

#if ENABLE(CSS_REGIONS)

#include "JSWebKitCSSRegionRule.h"

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

using namespace JSC;

namespace WebCore {

// Attributes

JSC::EncodedJSValue jsWebKitCSSRegionRuleCssRules(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsWebKitCSSRegionRuleConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSWebKitCSSRegionRuleConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);

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

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

typedef JSDOMConstructorNotConstructable<JSWebKitCSSRegionRule> JSWebKitCSSRegionRuleConstructor;

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

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

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

/* Hash table for prototype */

static const HashTableValue JSWebKitCSSRegionRulePrototypeTableValues[] =
{
    { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWebKitCSSRegionRuleConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSWebKitCSSRegionRuleConstructor) } },
    { "cssRules", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWebKitCSSRegionRuleCssRules), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
};

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

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

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

JSWebKitCSSRegionRule::JSWebKitCSSRegionRule(Structure* structure, JSDOMGlobalObject& globalObject, Ref<WebKitCSSRegionRule>&& impl)
    : JSCSSRule(structure, globalObject, WTFMove(impl))
{
}

JSObject* JSWebKitCSSRegionRule::createPrototype(VM& vm, JSGlobalObject* globalObject)
{
    return JSWebKitCSSRegionRulePrototype::create(vm, globalObject, JSWebKitCSSRegionRulePrototype::createStructure(vm, globalObject, JSCSSRule::prototype(vm, globalObject)));
}

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

EncodedJSValue jsWebKitCSSRegionRuleCssRules(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<JSWebKitCSSRegionRule*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "WebKitCSSRegionRule", "cssRules");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = toJS(state, castedThis->globalObject(), impl.cssRules());
    return JSValue::encode(result);
}


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

bool setJSWebKitCSSRegionRuleConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSValue value = JSValue::decode(encodedValue);
    JSWebKitCSSRegionRulePrototype* domObject = jsDynamicCast<JSWebKitCSSRegionRulePrototype*>(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);
}

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


}

#endif // ENABLE(CSS_REGIONS)
