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

#include "JSDOMConstructor.h"
#include "ScriptExecutionContext.h"
#include <runtime/JSLock.h>
#include <runtime/ObjectPrototype.h>

using namespace JSC;

namespace WebCore {

JSNodeFilter::JSNodeFilter(JSObject* callback, JSDOMGlobalObject* globalObject)
    : NodeFilter()
    , ActiveDOMCallback(globalObject->scriptExecutionContext())
    , m_data(new JSCallbackDataWeak(callback, this))
{
}

JSNodeFilter::~JSNodeFilter()
{
    ScriptExecutionContext* context = scriptExecutionContext();
    // When the context is destroyed, all tasks with a reference to a callback
    // should be deleted. So if the context is 0, we are on the context thread.
    if (!context || context->isContextThread())
        delete m_data;
    else
        context->postTask(DeleteCallbackDataTask(m_data));
#ifndef NDEBUG
    m_data = nullptr;
#endif
}

typedef JSDOMConstructorNotConstructable<JSNodeFilter> JSNodeFilterConstructor;

/* Hash table for constructor */

static const HashTableValue JSNodeFilterConstructorTableValues[] =
{
    { "FILTER_ACCEPT", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(1) } },
    { "FILTER_REJECT", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(2) } },
    { "FILTER_SKIP", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(3) } },
    { "SHOW_ALL", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(0xFFFFFFFF) } },
    { "SHOW_ELEMENT", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(0x00000001) } },
    { "SHOW_ATTRIBUTE", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(0x00000002) } },
    { "SHOW_TEXT", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(0x00000004) } },
    { "SHOW_CDATA_SECTION", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(0x00000008) } },
    { "SHOW_ENTITY_REFERENCE", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(0x00000010) } },
    { "SHOW_ENTITY", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(0x00000020) } },
    { "SHOW_PROCESSING_INSTRUCTION", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(0x00000040) } },
    { "SHOW_COMMENT", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(0x00000080) } },
    { "SHOW_DOCUMENT", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(0x00000100) } },
    { "SHOW_DOCUMENT_TYPE", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(0x00000200) } },
    { "SHOW_DOCUMENT_FRAGMENT", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(0x00000400) } },
    { "SHOW_NOTATION", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(0x00000800) } },
};

static_assert(NodeFilter::FILTER_ACCEPT == 1, "FILTER_ACCEPT in NodeFilter does not match value from IDL");
static_assert(NodeFilter::FILTER_REJECT == 2, "FILTER_REJECT in NodeFilter does not match value from IDL");
static_assert(NodeFilter::FILTER_SKIP == 3, "FILTER_SKIP in NodeFilter does not match value from IDL");
static_assert(NodeFilter::SHOW_ALL == 0xFFFFFFFF, "SHOW_ALL in NodeFilter does not match value from IDL");
static_assert(NodeFilter::SHOW_ELEMENT == 0x00000001, "SHOW_ELEMENT in NodeFilter does not match value from IDL");
static_assert(NodeFilter::SHOW_ATTRIBUTE == 0x00000002, "SHOW_ATTRIBUTE in NodeFilter does not match value from IDL");
static_assert(NodeFilter::SHOW_TEXT == 0x00000004, "SHOW_TEXT in NodeFilter does not match value from IDL");
static_assert(NodeFilter::SHOW_CDATA_SECTION == 0x00000008, "SHOW_CDATA_SECTION in NodeFilter does not match value from IDL");
static_assert(NodeFilter::SHOW_ENTITY_REFERENCE == 0x00000010, "SHOW_ENTITY_REFERENCE in NodeFilter does not match value from IDL");
static_assert(NodeFilter::SHOW_ENTITY == 0x00000020, "SHOW_ENTITY in NodeFilter does not match value from IDL");
static_assert(NodeFilter::SHOW_PROCESSING_INSTRUCTION == 0x00000040, "SHOW_PROCESSING_INSTRUCTION in NodeFilter does not match value from IDL");
static_assert(NodeFilter::SHOW_COMMENT == 0x00000080, "SHOW_COMMENT in NodeFilter does not match value from IDL");
static_assert(NodeFilter::SHOW_DOCUMENT == 0x00000100, "SHOW_DOCUMENT in NodeFilter does not match value from IDL");
static_assert(NodeFilter::SHOW_DOCUMENT_TYPE == 0x00000200, "SHOW_DOCUMENT_TYPE in NodeFilter does not match value from IDL");
static_assert(NodeFilter::SHOW_DOCUMENT_FRAGMENT == 0x00000400, "SHOW_DOCUMENT_FRAGMENT in NodeFilter does not match value from IDL");
static_assert(NodeFilter::SHOW_NOTATION == 0x00000800, "SHOW_NOTATION in NodeFilter does not match value from IDL");

template<> JSValue JSNodeFilterConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
{
    UNUSED_PARAM(vm);
    return globalObject.objectPrototype();
}

template<> void JSNodeFilterConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
{
    UNUSED_PARAM(globalObject);
    putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String(ASCIILiteral("NodeFilter"))), ReadOnly | DontEnum);
    putDirect(vm, vm.propertyNames->length, jsNumber(0), ReadOnly | DontEnum);
    reifyStaticProperties(vm, JSNodeFilterConstructorTableValues, *this);
}

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

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


// Functions

JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, NodeFilter& impl)
{
    if (!static_cast<JSNodeFilter&>(impl).callbackData())
        return jsNull();

    return static_cast<JSNodeFilter&>(impl).callbackData()->callback();

}

}
