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

#include "ExceptionCode.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructor.h"
#include "JSDOMConvert.h"
#include "JSDOMMimeTypeArray.h"
#include "JSDOMPluginArray.h"
#include "NavigatorBattery.h"
#include "NavigatorGeolocation.h"
#include "NavigatorMediaDevices.h"
#include "URL.h"
#include <runtime/Error.h>
#include <runtime/FunctionPrototype.h>
#include <runtime/JSString.h>
#include <wtf/GetPtr.h>

#if (ENABLE(CUSTOM_SCHEME_HANDLER) && ENABLE(NAVIGATOR_CONTENT_UTILS)) || ENABLE(NAVIGATOR_CONTENT_UTILS)
#include "NavigatorContentUtils.h"
#endif

#if ENABLE(BATTERY_STATUS)
#include "JSBatteryManager.h"
#endif

#if ENABLE(GEOLOCATION)
#include "JSGeolocation.h"
#endif

#if ENABLE(MEDIA_STREAM)
#include "JSMediaDevices.h"
#include "NavigatorUserMediaBuiltins.h"
#endif

#if ENABLE(VIBRATION)
#include "NavigatorVibration.h"
#endif

#if ENABLE(WEB_REPLAY)
#include "MemoizedDOMResult.h"
#include <replay/InputCursor.h>
#include <wtf/NeverDestroyed.h>
#endif

using namespace JSC;

namespace WebCore {

// Functions

JSC::EncodedJSValue JSC_HOST_CALL jsNavigatorPrototypeFunctionJavaEnabled(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsNavigatorPrototypeFunctionGetStorageUpdates(JSC::ExecState*);
#if ENABLE(NAVIGATOR_CONTENT_UTILS)
JSC::EncodedJSValue JSC_HOST_CALL jsNavigatorPrototypeFunctionRegisterProtocolHandler(JSC::ExecState*);
#endif
#if ENABLE(CUSTOM_SCHEME_HANDLER) && ENABLE(NAVIGATOR_CONTENT_UTILS)
JSC::EncodedJSValue JSC_HOST_CALL jsNavigatorPrototypeFunctionIsProtocolHandlerRegistered(JSC::ExecState*);
#endif
#if ENABLE(CUSTOM_SCHEME_HANDLER) && ENABLE(NAVIGATOR_CONTENT_UTILS)
JSC::EncodedJSValue JSC_HOST_CALL jsNavigatorPrototypeFunctionUnregisterProtocolHandler(JSC::ExecState*);
#endif
#if ENABLE(VIBRATION)
JSC::EncodedJSValue JSC_HOST_CALL jsNavigatorPrototypeFunctionVibrate(JSC::ExecState*);
#endif

// Attributes

JSC::EncodedJSValue jsNavigatorPlugins(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsNavigatorMimeTypes(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsNavigatorCookieEnabled(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
#if ENABLE(BATTERY_STATUS)
JSC::EncodedJSValue jsNavigatorWebkitBattery(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
#endif
#if ENABLE(GEOLOCATION)
JSC::EncodedJSValue jsNavigatorGeolocation(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
#endif
#if ENABLE(MEDIA_STREAM)
JSC::EncodedJSValue jsNavigatorMediaDevices(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
#endif
#if ENABLE(NAVIGATOR_HWCONCURRENCY)
JSC::EncodedJSValue jsNavigatorHardwareConcurrency(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
#endif
JSC::EncodedJSValue jsNavigatorAppCodeName(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsNavigatorAppName(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsNavigatorAppVersion(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsNavigatorPlatform(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsNavigatorProduct(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsNavigatorProductSub(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsNavigatorUserAgent(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsNavigatorVendor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsNavigatorVendorSub(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsNavigatorLanguage(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsNavigatorOnLine(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsNavigatorConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSNavigatorConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);

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

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

typedef JSDOMConstructorNotConstructable<JSNavigator> JSNavigatorConstructor;

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

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

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

/* Hash table for prototype */

static const HashTableValue JSNavigatorPrototypeTableValues[] =
{
    { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSNavigatorConstructor) } },
    { "plugins", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorPlugins), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "mimeTypes", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorMimeTypes), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "cookieEnabled", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorCookieEnabled), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
#if ENABLE(BATTERY_STATUS)
    { "webkitBattery", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorWebkitBattery), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
#else
    { 0, 0, NoIntrinsic, { 0, 0 } },
#endif
#if ENABLE(GEOLOCATION)
    { "geolocation", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorGeolocation), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
#else
    { 0, 0, NoIntrinsic, { 0, 0 } },
#endif
#if ENABLE(MEDIA_STREAM)
    { "mediaDevices", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorMediaDevices), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
#else
    { 0, 0, NoIntrinsic, { 0, 0 } },
#endif
#if ENABLE(NAVIGATOR_HWCONCURRENCY)
    { "hardwareConcurrency", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorHardwareConcurrency), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
#else
    { 0, 0, NoIntrinsic, { 0, 0 } },
#endif
    { "appCodeName", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorAppCodeName), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "appName", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorAppName), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "appVersion", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorAppVersion), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "platform", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorPlatform), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "product", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorProduct), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "productSub", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorProductSub), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "userAgent", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorUserAgent), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "vendor", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorVendor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "vendorSub", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorVendorSub), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "language", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorLanguage), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "onLine", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorOnLine), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "javaEnabled", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsNavigatorPrototypeFunctionJavaEnabled), (intptr_t) (0) } },
    { "getStorageUpdates", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsNavigatorPrototypeFunctionGetStorageUpdates), (intptr_t) (0) } },
#if ENABLE(MEDIA_STREAM)
    { "webkitGetUserMedia", JSC::Builtin, NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(navigatorUserMediaWebkitGetUserMediaCodeGenerator), (intptr_t) (3) } },
#else
    { 0, 0, NoIntrinsic, { 0, 0 } },
#endif
#if ENABLE(NAVIGATOR_CONTENT_UTILS)
    { "registerProtocolHandler", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsNavigatorPrototypeFunctionRegisterProtocolHandler), (intptr_t) (3) } },
#else
    { 0, 0, NoIntrinsic, { 0, 0 } },
#endif
#if ENABLE(CUSTOM_SCHEME_HANDLER) && ENABLE(NAVIGATOR_CONTENT_UTILS)
    { "isProtocolHandlerRegistered", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsNavigatorPrototypeFunctionIsProtocolHandlerRegistered), (intptr_t) (2) } },
#else
    { 0, 0, NoIntrinsic, { 0, 0 } },
#endif
#if ENABLE(CUSTOM_SCHEME_HANDLER) && ENABLE(NAVIGATOR_CONTENT_UTILS)
    { "unregisterProtocolHandler", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsNavigatorPrototypeFunctionUnregisterProtocolHandler), (intptr_t) (2) } },
#else
    { 0, 0, NoIntrinsic, { 0, 0 } },
#endif
#if ENABLE(VIBRATION)
    { "vibrate", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsNavigatorPrototypeFunctionVibrate), (intptr_t) (1) } },
#else
    { 0, 0, NoIntrinsic, { 0, 0 } },
#endif
};

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

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

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

JSNavigator::JSNavigator(Structure* structure, JSDOMGlobalObject& globalObject, Ref<Navigator>&& impl)
    : JSDOMWrapper<Navigator>(structure, globalObject, WTFMove(impl))
{
}

JSObject* JSNavigator::createPrototype(VM& vm, JSGlobalObject* globalObject)
{
    return JSNavigatorPrototype::create(vm, globalObject, JSNavigatorPrototype::createStructure(vm, globalObject, globalObject->objectPrototype()));
}

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

void JSNavigator::destroy(JSC::JSCell* cell)
{
    JSNavigator* thisObject = static_cast<JSNavigator*>(cell);
    thisObject->JSNavigator::~JSNavigator();
}

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


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


EncodedJSValue jsNavigatorCookieEnabled(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<JSNavigator*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Navigator", "cookieEnabled");
    }
#if ENABLE(WEB_REPLAY)
    JSGlobalObject* globalObject = state->lexicalGlobalObject();
    InputCursor& cursor = globalObject->inputCursor();
    static NeverDestroyed<const AtomicString> bindingName("Navigator.cookieEnabled", AtomicString::ConstructFromLiteral);
    if (cursor.isCapturing()) {
        bool memoizedResult = castedThis->wrapped().cookieEnabled();
        cursor.appendInput<MemoizedDOMResult<bool>>(bindingName.get().string(), memoizedResult, 0);
        JSValue result = jsBoolean(memoizedResult);
        return JSValue::encode(result);
    }

    if (cursor.isReplaying()) {
        bool memoizedResult;
        MemoizedDOMResultBase* input = cursor.fetchInput<MemoizedDOMResultBase>();
        if (input && input->convertTo<bool>(memoizedResult)) {
            JSValue result = jsBoolean(memoizedResult);
            return JSValue::encode(result);
        }
    }
#endif
    auto& impl = castedThis->wrapped();
    JSValue result = jsBoolean(impl.cookieEnabled());
    return JSValue::encode(result);
}


#if ENABLE(BATTERY_STATUS)
EncodedJSValue jsNavigatorWebkitBattery(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<JSNavigator*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Navigator", "webkitBattery");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = toJS(state, castedThis->globalObject(), WebCore::NavigatorBattery::webkitBattery(impl));
    return JSValue::encode(result);
}

#endif

#if ENABLE(GEOLOCATION)
EncodedJSValue jsNavigatorGeolocation(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<JSNavigator*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Navigator", "geolocation");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = toJS(state, castedThis->globalObject(), WebCore::NavigatorGeolocation::geolocation(impl));
    return JSValue::encode(result);
}

#endif

#if ENABLE(MEDIA_STREAM)
EncodedJSValue jsNavigatorMediaDevices(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<JSNavigator*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Navigator", "mediaDevices");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = toJS(state, castedThis->globalObject(), WebCore::NavigatorMediaDevices::mediaDevices(impl));
    return JSValue::encode(result);
}

#endif

#if ENABLE(NAVIGATOR_HWCONCURRENCY)
EncodedJSValue jsNavigatorHardwareConcurrency(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<JSNavigator*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Navigator", "hardwareConcurrency");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsNumber(impl.hardwareConcurrency());
    return JSValue::encode(result);
}

#endif

EncodedJSValue jsNavigatorAppCodeName(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<JSNavigator*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Navigator", "appCodeName");
    }
#if ENABLE(WEB_REPLAY)
    JSGlobalObject* globalObject = state->lexicalGlobalObject();
    InputCursor& cursor = globalObject->inputCursor();
    static NeverDestroyed<const AtomicString> bindingName("Navigator.appCodeName", AtomicString::ConstructFromLiteral);
    if (cursor.isCapturing()) {
        String memoizedResult = castedThis->wrapped().appCodeName();
        cursor.appendInput<MemoizedDOMResult<String>>(bindingName.get().string(), memoizedResult, 0);
        JSValue result = jsStringWithCache(state, memoizedResult);
        return JSValue::encode(result);
    }

    if (cursor.isReplaying()) {
        String memoizedResult;
        MemoizedDOMResultBase* input = cursor.fetchInput<MemoizedDOMResultBase>();
        if (input && input->convertTo<String>(memoizedResult)) {
            JSValue result = jsStringWithCache(state, memoizedResult);
            return JSValue::encode(result);
        }
    }
#endif
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.appCodeName());
    return JSValue::encode(result);
}


EncodedJSValue jsNavigatorAppName(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<JSNavigator*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Navigator", "appName");
    }
#if ENABLE(WEB_REPLAY)
    JSGlobalObject* globalObject = state->lexicalGlobalObject();
    InputCursor& cursor = globalObject->inputCursor();
    static NeverDestroyed<const AtomicString> bindingName("Navigator.appName", AtomicString::ConstructFromLiteral);
    if (cursor.isCapturing()) {
        String memoizedResult = castedThis->wrapped().appName();
        cursor.appendInput<MemoizedDOMResult<String>>(bindingName.get().string(), memoizedResult, 0);
        JSValue result = jsStringWithCache(state, memoizedResult);
        return JSValue::encode(result);
    }

    if (cursor.isReplaying()) {
        String memoizedResult;
        MemoizedDOMResultBase* input = cursor.fetchInput<MemoizedDOMResultBase>();
        if (input && input->convertTo<String>(memoizedResult)) {
            JSValue result = jsStringWithCache(state, memoizedResult);
            return JSValue::encode(result);
        }
    }
#endif
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.appName());
    return JSValue::encode(result);
}


EncodedJSValue jsNavigatorAppVersion(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<JSNavigator*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Navigator", "appVersion");
    }
#if ENABLE(WEB_REPLAY)
    JSGlobalObject* globalObject = state->lexicalGlobalObject();
    InputCursor& cursor = globalObject->inputCursor();
    static NeverDestroyed<const AtomicString> bindingName("Navigator.appVersion", AtomicString::ConstructFromLiteral);
    if (cursor.isCapturing()) {
        String memoizedResult = castedThis->wrapped().appVersion();
        cursor.appendInput<MemoizedDOMResult<String>>(bindingName.get().string(), memoizedResult, 0);
        JSValue result = jsStringWithCache(state, memoizedResult);
        return JSValue::encode(result);
    }

    if (cursor.isReplaying()) {
        String memoizedResult;
        MemoizedDOMResultBase* input = cursor.fetchInput<MemoizedDOMResultBase>();
        if (input && input->convertTo<String>(memoizedResult)) {
            JSValue result = jsStringWithCache(state, memoizedResult);
            return JSValue::encode(result);
        }
    }
#endif
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.appVersion());
    return JSValue::encode(result);
}


EncodedJSValue jsNavigatorPlatform(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<JSNavigator*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Navigator", "platform");
    }
#if ENABLE(WEB_REPLAY)
    JSGlobalObject* globalObject = state->lexicalGlobalObject();
    InputCursor& cursor = globalObject->inputCursor();
    static NeverDestroyed<const AtomicString> bindingName("Navigator.platform", AtomicString::ConstructFromLiteral);
    if (cursor.isCapturing()) {
        String memoizedResult = castedThis->wrapped().platform();
        cursor.appendInput<MemoizedDOMResult<String>>(bindingName.get().string(), memoizedResult, 0);
        JSValue result = jsStringWithCache(state, memoizedResult);
        return JSValue::encode(result);
    }

    if (cursor.isReplaying()) {
        String memoizedResult;
        MemoizedDOMResultBase* input = cursor.fetchInput<MemoizedDOMResultBase>();
        if (input && input->convertTo<String>(memoizedResult)) {
            JSValue result = jsStringWithCache(state, memoizedResult);
            return JSValue::encode(result);
        }
    }
#endif
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.platform());
    return JSValue::encode(result);
}


EncodedJSValue jsNavigatorProduct(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<JSNavigator*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Navigator", "product");
    }
#if ENABLE(WEB_REPLAY)
    JSGlobalObject* globalObject = state->lexicalGlobalObject();
    InputCursor& cursor = globalObject->inputCursor();
    static NeverDestroyed<const AtomicString> bindingName("Navigator.product", AtomicString::ConstructFromLiteral);
    if (cursor.isCapturing()) {
        String memoizedResult = castedThis->wrapped().product();
        cursor.appendInput<MemoizedDOMResult<String>>(bindingName.get().string(), memoizedResult, 0);
        JSValue result = jsStringWithCache(state, memoizedResult);
        return JSValue::encode(result);
    }

    if (cursor.isReplaying()) {
        String memoizedResult;
        MemoizedDOMResultBase* input = cursor.fetchInput<MemoizedDOMResultBase>();
        if (input && input->convertTo<String>(memoizedResult)) {
            JSValue result = jsStringWithCache(state, memoizedResult);
            return JSValue::encode(result);
        }
    }
#endif
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.product());
    return JSValue::encode(result);
}


EncodedJSValue jsNavigatorProductSub(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<JSNavigator*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Navigator", "productSub");
    }
#if ENABLE(WEB_REPLAY)
    JSGlobalObject* globalObject = state->lexicalGlobalObject();
    InputCursor& cursor = globalObject->inputCursor();
    static NeverDestroyed<const AtomicString> bindingName("Navigator.productSub", AtomicString::ConstructFromLiteral);
    if (cursor.isCapturing()) {
        String memoizedResult = castedThis->wrapped().productSub();
        cursor.appendInput<MemoizedDOMResult<String>>(bindingName.get().string(), memoizedResult, 0);
        JSValue result = jsStringWithCache(state, memoizedResult);
        return JSValue::encode(result);
    }

    if (cursor.isReplaying()) {
        String memoizedResult;
        MemoizedDOMResultBase* input = cursor.fetchInput<MemoizedDOMResultBase>();
        if (input && input->convertTo<String>(memoizedResult)) {
            JSValue result = jsStringWithCache(state, memoizedResult);
            return JSValue::encode(result);
        }
    }
#endif
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.productSub());
    return JSValue::encode(result);
}


EncodedJSValue jsNavigatorUserAgent(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<JSNavigator*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Navigator", "userAgent");
    }
#if ENABLE(WEB_REPLAY)
    JSGlobalObject* globalObject = state->lexicalGlobalObject();
    InputCursor& cursor = globalObject->inputCursor();
    static NeverDestroyed<const AtomicString> bindingName("Navigator.userAgent", AtomicString::ConstructFromLiteral);
    if (cursor.isCapturing()) {
        String memoizedResult = castedThis->wrapped().userAgent();
        cursor.appendInput<MemoizedDOMResult<String>>(bindingName.get().string(), memoizedResult, 0);
        JSValue result = jsStringWithCache(state, memoizedResult);
        return JSValue::encode(result);
    }

    if (cursor.isReplaying()) {
        String memoizedResult;
        MemoizedDOMResultBase* input = cursor.fetchInput<MemoizedDOMResultBase>();
        if (input && input->convertTo<String>(memoizedResult)) {
            JSValue result = jsStringWithCache(state, memoizedResult);
            return JSValue::encode(result);
        }
    }
#endif
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.userAgent());
    return JSValue::encode(result);
}


EncodedJSValue jsNavigatorVendor(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<JSNavigator*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Navigator", "vendor");
    }
#if ENABLE(WEB_REPLAY)
    JSGlobalObject* globalObject = state->lexicalGlobalObject();
    InputCursor& cursor = globalObject->inputCursor();
    static NeverDestroyed<const AtomicString> bindingName("Navigator.vendor", AtomicString::ConstructFromLiteral);
    if (cursor.isCapturing()) {
        String memoizedResult = castedThis->wrapped().vendor();
        cursor.appendInput<MemoizedDOMResult<String>>(bindingName.get().string(), memoizedResult, 0);
        JSValue result = jsStringWithCache(state, memoizedResult);
        return JSValue::encode(result);
    }

    if (cursor.isReplaying()) {
        String memoizedResult;
        MemoizedDOMResultBase* input = cursor.fetchInput<MemoizedDOMResultBase>();
        if (input && input->convertTo<String>(memoizedResult)) {
            JSValue result = jsStringWithCache(state, memoizedResult);
            return JSValue::encode(result);
        }
    }
#endif
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.vendor());
    return JSValue::encode(result);
}


EncodedJSValue jsNavigatorVendorSub(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<JSNavigator*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Navigator", "vendorSub");
    }
#if ENABLE(WEB_REPLAY)
    JSGlobalObject* globalObject = state->lexicalGlobalObject();
    InputCursor& cursor = globalObject->inputCursor();
    static NeverDestroyed<const AtomicString> bindingName("Navigator.vendorSub", AtomicString::ConstructFromLiteral);
    if (cursor.isCapturing()) {
        String memoizedResult = castedThis->wrapped().vendorSub();
        cursor.appendInput<MemoizedDOMResult<String>>(bindingName.get().string(), memoizedResult, 0);
        JSValue result = jsStringWithCache(state, memoizedResult);
        return JSValue::encode(result);
    }

    if (cursor.isReplaying()) {
        String memoizedResult;
        MemoizedDOMResultBase* input = cursor.fetchInput<MemoizedDOMResultBase>();
        if (input && input->convertTo<String>(memoizedResult)) {
            JSValue result = jsStringWithCache(state, memoizedResult);
            return JSValue::encode(result);
        }
    }
#endif
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.vendorSub());
    return JSValue::encode(result);
}


EncodedJSValue jsNavigatorLanguage(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<JSNavigator*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Navigator", "language");
    }
#if ENABLE(WEB_REPLAY)
    JSGlobalObject* globalObject = state->lexicalGlobalObject();
    InputCursor& cursor = globalObject->inputCursor();
    static NeverDestroyed<const AtomicString> bindingName("Navigator.language", AtomicString::ConstructFromLiteral);
    if (cursor.isCapturing()) {
        String memoizedResult = castedThis->wrapped().language();
        cursor.appendInput<MemoizedDOMResult<String>>(bindingName.get().string(), memoizedResult, 0);
        JSValue result = jsStringWithCache(state, memoizedResult);
        return JSValue::encode(result);
    }

    if (cursor.isReplaying()) {
        String memoizedResult;
        MemoizedDOMResultBase* input = cursor.fetchInput<MemoizedDOMResultBase>();
        if (input && input->convertTo<String>(memoizedResult)) {
            JSValue result = jsStringWithCache(state, memoizedResult);
            return JSValue::encode(result);
        }
    }
#endif
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.language());
    return JSValue::encode(result);
}


EncodedJSValue jsNavigatorOnLine(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<JSNavigator*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Navigator", "onLine");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsBoolean(impl.onLine());
    return JSValue::encode(result);
}


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

bool setJSNavigatorConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSValue value = JSValue::decode(encodedValue);
    JSNavigatorPrototype* domObject = jsDynamicCast<JSNavigatorPrototype*>(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 JSNavigator::getConstructor(VM& vm, const JSGlobalObject* globalObject)
{
    return getDOMConstructor<JSNavigatorConstructor>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
}

EncodedJSValue JSC_HOST_CALL jsNavigatorPrototypeFunctionJavaEnabled(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSNavigator*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "Navigator", "javaEnabled");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSNavigator::info());
    auto& impl = castedThis->wrapped();
    JSValue result;
#if ENABLE(WEB_REPLAY)
    InputCursor& cursor = state->lexicalGlobalObject()->inputCursor();
    static NeverDestroyed<const AtomicString> bindingName("Navigator.javaEnabled", AtomicString::ConstructFromLiteral);
    if (cursor.isCapturing()) {
        bool memoizedResult = impl.javaEnabled();
        cursor.appendInput<MemoizedDOMResult<bool>>(bindingName.get().string(), memoizedResult, 0);
        result = jsBoolean(memoizedResult);
    } else if (cursor.isReplaying()) {
        MemoizedDOMResultBase* input = cursor.fetchInput<MemoizedDOMResultBase>();
        bool memoizedResult;
        if (input && input->convertTo<bool>(memoizedResult)) {
            result = jsBoolean(memoizedResult);
        } else
            result = jsBoolean(impl.javaEnabled());
    } else
        result = jsBoolean(impl.javaEnabled());
#else
    result = jsBoolean(impl.javaEnabled());
#endif
    return JSValue::encode(result);
}

EncodedJSValue JSC_HOST_CALL jsNavigatorPrototypeFunctionGetStorageUpdates(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSNavigator*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "Navigator", "getStorageUpdates");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSNavigator::info());
    auto& impl = castedThis->wrapped();
    impl.getStorageUpdates();
    return JSValue::encode(jsUndefined());
}

#if ENABLE(NAVIGATOR_CONTENT_UTILS)
EncodedJSValue JSC_HOST_CALL jsNavigatorPrototypeFunctionRegisterProtocolHandler(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSNavigator*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "Navigator", "registerProtocolHandler");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSNavigator::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 3))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto scheme = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    auto url = state->uncheckedArgument(1).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    auto title = state->uncheckedArgument(2).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    WebCore::NavigatorContentUtils::registerProtocolHandler(impl, WTFMove(scheme), WTFMove(url), WTFMove(title), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

#endif

#if ENABLE(CUSTOM_SCHEME_HANDLER) && ENABLE(NAVIGATOR_CONTENT_UTILS)
EncodedJSValue JSC_HOST_CALL jsNavigatorPrototypeFunctionIsProtocolHandlerRegistered(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSNavigator*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "Navigator", "isProtocolHandlerRegistered");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSNavigator::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 2))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto scheme = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    auto url = state->uncheckedArgument(1).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    JSValue result = jsStringWithCache(state, WebCore::NavigatorContentUtils::isProtocolHandlerRegistered(impl, WTFMove(scheme), WTFMove(url), ec));

    setDOMException(state, throwScope, ec);
    return JSValue::encode(result);
}

#endif

#if ENABLE(CUSTOM_SCHEME_HANDLER) && ENABLE(NAVIGATOR_CONTENT_UTILS)
EncodedJSValue JSC_HOST_CALL jsNavigatorPrototypeFunctionUnregisterProtocolHandler(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSNavigator*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "Navigator", "unregisterProtocolHandler");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSNavigator::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 2))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto scheme = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    auto url = state->uncheckedArgument(1).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    WebCore::NavigatorContentUtils::unregisterProtocolHandler(impl, WTFMove(scheme), WTFMove(url), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

#endif

#if ENABLE(VIBRATION)
static inline EncodedJSValue jsNavigatorPrototypeFunctionVibrate1(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSNavigator*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "Navigator", "vibrate");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSNavigator::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    auto pattern = toNativeArray<uint32_t>(*state, state->uncheckedArgument(0));
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    JSValue result = jsBoolean(WebCore::NavigatorVibration::vibrate(impl, WTFMove(pattern)));
    return JSValue::encode(result);
}

#endif

#if ENABLE(VIBRATION)
static inline EncodedJSValue jsNavigatorPrototypeFunctionVibrate2(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSNavigator*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "Navigator", "vibrate");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSNavigator::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    auto time = convert<uint32_t>(*state, state->uncheckedArgument(0), NormalConversion);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    JSValue result = jsBoolean(WebCore::NavigatorVibration::vibrate(impl, WTFMove(time)));
    return JSValue::encode(result);
}

#endif

#if ENABLE(VIBRATION)
EncodedJSValue JSC_HOST_CALL jsNavigatorPrototypeFunctionVibrate(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    size_t argsCount = std::min<size_t>(1, state->argumentCount());
    if (argsCount == 1) {
        JSValue distinguishingArg = state->uncheckedArgument(0);
#if ENABLE(VIBRATION)
        if (hasIteratorMethod(*state, distinguishingArg))
            return jsNavigatorPrototypeFunctionVibrate1(state);
#endif
#if ENABLE(VIBRATION)
        if (distinguishingArg.isNumber())
            return jsNavigatorPrototypeFunctionVibrate2(state);
#endif
#if ENABLE(VIBRATION)
        return jsNavigatorPrototypeFunctionVibrate2(state);
#endif
    }
    return argsCount < 1 ? throwVMError(state, throwScope, createNotEnoughArgumentsError(state)) : throwVMTypeError(state, throwScope);
}
#endif

bool JSNavigatorOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
{
    auto* jsNavigator = jsCast<JSNavigator*>(handle.slot()->asCell());
    Frame* root = WTF::getPtr(jsNavigator->wrapped().frame());
    if (!root)
        return false;
    return visitor.containsOpaqueRoot(root);
}

void JSNavigatorOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
{
    auto* jsNavigator = jsCast<JSNavigator*>(handle.slot()->asCell());
    auto& world = *static_cast<DOMWrapperWorld*>(context);
    uncacheWrapper(world, &jsNavigator->wrapped(), jsNavigator);
}

#if ENABLE(BINDING_INTEGRITY)
#if PLATFORM(WIN)
#pragma warning(disable: 4483)
extern "C" { extern void (*const __identifier("??_7Navigator@WebCore@@6B@")[])(); }
#else
extern "C" { extern void* _ZTVN7WebCore9NavigatorE[]; }
#endif
#endif

JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref<Navigator>&& impl)
{

#if ENABLE(BINDING_INTEGRITY)
    void* actualVTablePointer = *(reinterpret_cast<void**>(impl.ptr()));
#if PLATFORM(WIN)
    void* expectedVTablePointer = reinterpret_cast<void*>(__identifier("??_7Navigator@WebCore@@6B@"));
#else
    void* expectedVTablePointer = &_ZTVN7WebCore9NavigatorE[2];
#if COMPILER(CLANG)
    // If this fails Navigator does not have a vtable, so you need to add the
    // ImplementationLacksVTable attribute to the interface definition
    static_assert(__is_polymorphic(Navigator), "Navigator is not polymorphic");
#endif
#endif
    // If you hit this assertion you either have a use after free bug, or
    // Navigator has subclasses. If Navigator has subclasses that get passed
    // to toJS() we currently require Navigator you to opt out of binding hardening
    // by adding the SkipVTableValidation attribute to the interface IDL definition
    RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
#endif
    return createWrapper<Navigator>(globalObject, WTFMove(impl));
}

JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, Navigator& impl)
{
    return wrap(state, globalObject, impl);
}

Navigator* JSNavigator::toWrapped(JSC::JSValue value)
{
    if (auto* wrapper = jsDynamicCast<JSNavigator*>(value))
        return &wrapper->wrapped();
    return nullptr;
}

}
