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

#if ENABLE(NOTIFICATIONS)

#include "ActiveDOMCallback.h"
#include "JSCallbackData.h"
#include "NotificationPermissionCallback.h"
#include <wtf/Forward.h>

namespace WebCore {

class JSNotificationPermissionCallback : public NotificationPermissionCallback, public ActiveDOMCallback {
public:
    static Ref<JSNotificationPermissionCallback> create(JSC::JSObject* callback, JSDOMGlobalObject* globalObject)
    {
        return adoptRef(*new JSNotificationPermissionCallback(callback, globalObject));
    }

    virtual ScriptExecutionContext* scriptExecutionContext() const { return ContextDestructionObserver::scriptExecutionContext(); }

    virtual ~JSNotificationPermissionCallback();
    JSCallbackDataStrong* callbackData() { return m_data; }

    // Functions
    virtual bool handleEvent(const String& permission);

private:
    JSNotificationPermissionCallback(JSC::JSObject* callback, JSDOMGlobalObject*);

    JSCallbackDataStrong* m_data;
};

JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, NotificationPermissionCallback&);
inline JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, NotificationPermissionCallback* impl) { return impl ? toJS(state, globalObject, *impl) : JSC::jsNull(); }

} // namespace WebCore

#endif // ENABLE(NOTIFICATIONS)
