123b3eb3cSopenharmony_ci/*
223b3eb3cSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
323b3eb3cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
423b3eb3cSopenharmony_ci * you may not use this file except in compliance with the License.
523b3eb3cSopenharmony_ci * You may obtain a copy of the License at
623b3eb3cSopenharmony_ci *
723b3eb3cSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
823b3eb3cSopenharmony_ci *
923b3eb3cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1023b3eb3cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1123b3eb3cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1223b3eb3cSopenharmony_ci * See the License for the specific language governing permissions and
1323b3eb3cSopenharmony_ci * limitations under the License.
1423b3eb3cSopenharmony_ci */
1523b3eb3cSopenharmony_ci
1623b3eb3cSopenharmony_ci
1723b3eb3cSopenharmony_ci#include "interfaces/napi/kits/utils/napi_utils.h"
1823b3eb3cSopenharmony_ci
1923b3eb3cSopenharmony_ci#include "core/common/ace_engine.h"
2023b3eb3cSopenharmony_ci#include "frameworks/bridge/common/utils/engine_helper.h"
2123b3eb3cSopenharmony_ci
2223b3eb3cSopenharmony_cinamespace OHOS::Ace::Napi {
2323b3eb3cSopenharmony_ciconst char EN_ALERT_APPROVE[] = "enableAlertBeforeBackPage:ok";
2423b3eb3cSopenharmony_ciconst char EN_ALERT_REJECT[] = "enableAlertBeforeBackPage:fail cancel";
2523b3eb3cSopenharmony_ciconst char DIS_ALERT_SUCCESS[] = "disableAlertBeforeBackPage:ok";
2623b3eb3cSopenharmony_ci
2723b3eb3cSopenharmony_cistatic constexpr size_t ARGC_WITH_MODE = 2;
2823b3eb3cSopenharmony_cistatic constexpr size_t ARGC_WITH_ROUTER_PARAMTER = 2;
2923b3eb3cSopenharmony_cistatic constexpr size_t ARGC_WITH_MODE_AND_CALLBACK = 3;
3023b3eb3cSopenharmony_cistatic constexpr uint32_t STANDARD = 0;
3123b3eb3cSopenharmony_cistatic constexpr uint32_t SINGLE = 1;
3223b3eb3cSopenharmony_cistatic constexpr uint32_t INVALID = 2;
3323b3eb3cSopenharmony_cistatic constexpr uint32_t RESULT_ARRAY_INDEX_INDEX = 0;
3423b3eb3cSopenharmony_cistatic constexpr uint32_t RESULT_ARRAY_NAME_INDEX = 1;
3523b3eb3cSopenharmony_cistatic constexpr uint32_t RESULT_ARRAY_PATH_INDEX = 2;
3623b3eb3cSopenharmony_cistatic constexpr uint32_t RESULT_ARRAY_LENGTH = 3;
3723b3eb3cSopenharmony_ci
3823b3eb3cSopenharmony_cistatic void ParseUri(napi_env env, napi_value uriNApi, std::string& uriString)
3923b3eb3cSopenharmony_ci{
4023b3eb3cSopenharmony_ci    if (uriNApi != nullptr) {
4123b3eb3cSopenharmony_ci        size_t uriLen = 0;
4223b3eb3cSopenharmony_ci        napi_get_value_string_utf8(env, uriNApi, nullptr, 0, &uriLen);
4323b3eb3cSopenharmony_ci        std::unique_ptr<char[]> uri = std::make_unique<char[]>(uriLen + 1);
4423b3eb3cSopenharmony_ci        napi_get_value_string_utf8(env, uriNApi, uri.get(), uriLen + 1, &uriLen);
4523b3eb3cSopenharmony_ci        uriString = uri.get();
4623b3eb3cSopenharmony_ci    }
4723b3eb3cSopenharmony_ci}
4823b3eb3cSopenharmony_ci
4923b3eb3cSopenharmony_cistatic void ParseParams(napi_env env, napi_value params, std::string& paramsString)
5023b3eb3cSopenharmony_ci{
5123b3eb3cSopenharmony_ci    if (params == nullptr) {
5223b3eb3cSopenharmony_ci        return;
5323b3eb3cSopenharmony_ci    }
5423b3eb3cSopenharmony_ci    napi_value globalValue;
5523b3eb3cSopenharmony_ci    napi_get_global(env, &globalValue);
5623b3eb3cSopenharmony_ci    napi_value jsonValue;
5723b3eb3cSopenharmony_ci    napi_get_named_property(env, globalValue, "JSON", &jsonValue);
5823b3eb3cSopenharmony_ci    napi_value stringifyValue;
5923b3eb3cSopenharmony_ci    napi_get_named_property(env, jsonValue, "stringify", &stringifyValue);
6023b3eb3cSopenharmony_ci    napi_value funcArgv[1] = { params };
6123b3eb3cSopenharmony_ci    napi_value returnValue;
6223b3eb3cSopenharmony_ci    if (napi_call_function(env, jsonValue, stringifyValue, 1, funcArgv, &returnValue) != napi_ok) {
6323b3eb3cSopenharmony_ci        TAG_LOGE(AceLogTag::ACE_ROUTER,
6423b3eb3cSopenharmony_ci            "Router parse param failed, probably caused by invalid format of JSON object 'params'");
6523b3eb3cSopenharmony_ci    }
6623b3eb3cSopenharmony_ci    size_t len = 0;
6723b3eb3cSopenharmony_ci    napi_get_value_string_utf8(env, returnValue, nullptr, 0, &len);
6823b3eb3cSopenharmony_ci    std::unique_ptr<char[]> paramsChar = std::make_unique<char[]>(len + 1);
6923b3eb3cSopenharmony_ci    napi_get_value_string_utf8(env, returnValue, paramsChar.get(), len + 1, &len);
7023b3eb3cSopenharmony_ci    paramsString = paramsChar.get();
7123b3eb3cSopenharmony_ci}
7223b3eb3cSopenharmony_ci
7323b3eb3cSopenharmony_cistatic napi_value ParseJSONParams(napi_env env, const std::string& paramsStr)
7423b3eb3cSopenharmony_ci{
7523b3eb3cSopenharmony_ci    napi_value globalValue;
7623b3eb3cSopenharmony_ci    napi_get_global(env, &globalValue);
7723b3eb3cSopenharmony_ci    napi_value jsonValue;
7823b3eb3cSopenharmony_ci    napi_get_named_property(env, globalValue, "JSON", &jsonValue);
7923b3eb3cSopenharmony_ci    napi_value parseValue;
8023b3eb3cSopenharmony_ci    napi_get_named_property(env, jsonValue, "parse", &parseValue);
8123b3eb3cSopenharmony_ci
8223b3eb3cSopenharmony_ci    napi_value paramsNApi;
8323b3eb3cSopenharmony_ci    napi_create_string_utf8(env, paramsStr.c_str(), NAPI_AUTO_LENGTH, &paramsNApi);
8423b3eb3cSopenharmony_ci    napi_value funcArgv[1] = { paramsNApi };
8523b3eb3cSopenharmony_ci    napi_value result;
8623b3eb3cSopenharmony_ci    napi_call_function(env, jsonValue, parseValue, 1, funcArgv, &result);
8723b3eb3cSopenharmony_ci
8823b3eb3cSopenharmony_ci    napi_valuetype valueType = napi_undefined;
8923b3eb3cSopenharmony_ci    napi_typeof(env, result, &valueType);
9023b3eb3cSopenharmony_ci    if (valueType != napi_object) {
9123b3eb3cSopenharmony_ci        return nullptr;
9223b3eb3cSopenharmony_ci    }
9323b3eb3cSopenharmony_ci
9423b3eb3cSopenharmony_ci    return result;
9523b3eb3cSopenharmony_ci}
9623b3eb3cSopenharmony_ci
9723b3eb3cSopenharmony_cistatic void ParseRecoverable(napi_env env, napi_value recoverableNApi, bool& recoverable)
9823b3eb3cSopenharmony_ci{
9923b3eb3cSopenharmony_ci    if (recoverableNApi == nullptr) {
10023b3eb3cSopenharmony_ci        return;
10123b3eb3cSopenharmony_ci    }
10223b3eb3cSopenharmony_ci    napi_get_value_bool(env, recoverableNApi, &recoverable);
10323b3eb3cSopenharmony_ci}
10423b3eb3cSopenharmony_ci
10523b3eb3cSopenharmony_cistruct RouterAsyncContext {
10623b3eb3cSopenharmony_ci    napi_env env = nullptr;
10723b3eb3cSopenharmony_ci    napi_ref callbackSuccess = nullptr;
10823b3eb3cSopenharmony_ci    napi_ref callbackFail = nullptr;
10923b3eb3cSopenharmony_ci    napi_ref callbackComplete = nullptr;
11023b3eb3cSopenharmony_ci    int32_t callbackType = 0;
11123b3eb3cSopenharmony_ci    std::string keyForUrl;
11223b3eb3cSopenharmony_ci    std::string paramsString;
11323b3eb3cSopenharmony_ci    std::string uriString;
11423b3eb3cSopenharmony_ci    bool recoverable = true;
11523b3eb3cSopenharmony_ci    uint32_t mode = STANDARD;
11623b3eb3cSopenharmony_ci    napi_deferred deferred = nullptr;
11723b3eb3cSopenharmony_ci    napi_ref callbackRef = nullptr;
11823b3eb3cSopenharmony_ci    int32_t callbackCode = 0;
11923b3eb3cSopenharmony_ci    std::string callbackMsg;
12023b3eb3cSopenharmony_ci    int32_t instanceId = -1;
12123b3eb3cSopenharmony_ci    ~RouterAsyncContext()
12223b3eb3cSopenharmony_ci    {
12323b3eb3cSopenharmony_ci        if (callbackRef) {
12423b3eb3cSopenharmony_ci            napi_delete_reference(env, callbackRef);
12523b3eb3cSopenharmony_ci        }
12623b3eb3cSopenharmony_ci        if (callbackSuccess) {
12723b3eb3cSopenharmony_ci            napi_delete_reference(env, callbackSuccess);
12823b3eb3cSopenharmony_ci        }
12923b3eb3cSopenharmony_ci        if (callbackFail) {
13023b3eb3cSopenharmony_ci            napi_delete_reference(env, callbackFail);
13123b3eb3cSopenharmony_ci        }
13223b3eb3cSopenharmony_ci        if (callbackComplete) {
13323b3eb3cSopenharmony_ci            napi_delete_reference(env, callbackComplete);
13423b3eb3cSopenharmony_ci        }
13523b3eb3cSopenharmony_ci    }
13623b3eb3cSopenharmony_ci};
13723b3eb3cSopenharmony_ci
13823b3eb3cSopenharmony_ciusing RouterFunc = std::function<void(const std::string&, const std::string&, int32_t)>;
13923b3eb3cSopenharmony_ci
14023b3eb3cSopenharmony_cistatic void CommonRouterProcess(napi_env env, napi_callback_info info, const RouterFunc& callback)
14123b3eb3cSopenharmony_ci{
14223b3eb3cSopenharmony_ci    size_t requireArgc = 1;
14323b3eb3cSopenharmony_ci    size_t argc = ARGC_WITH_MODE;
14423b3eb3cSopenharmony_ci    napi_value argv[ARGC_WITH_MODE] = { 0 };
14523b3eb3cSopenharmony_ci    napi_value thisVar = nullptr;
14623b3eb3cSopenharmony_ci    void* data = nullptr;
14723b3eb3cSopenharmony_ci    napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
14823b3eb3cSopenharmony_ci    if (argc < requireArgc) {
14923b3eb3cSopenharmony_ci        return;
15023b3eb3cSopenharmony_ci    }
15123b3eb3cSopenharmony_ci    napi_value uriNApi = nullptr;
15223b3eb3cSopenharmony_ci    napi_value params = nullptr;
15323b3eb3cSopenharmony_ci    napi_valuetype valueType = napi_undefined;
15423b3eb3cSopenharmony_ci    napi_typeof(env, argv[0], &valueType);
15523b3eb3cSopenharmony_ci    if (valueType == napi_object) {
15623b3eb3cSopenharmony_ci        napi_get_named_property(env, argv[0], "url", &uriNApi);
15723b3eb3cSopenharmony_ci        napi_typeof(env, uriNApi, &valueType);
15823b3eb3cSopenharmony_ci        if (valueType != napi_string) {
15923b3eb3cSopenharmony_ci            return;
16023b3eb3cSopenharmony_ci        }
16123b3eb3cSopenharmony_ci        napi_get_named_property(env, argv[0], "params", &params);
16223b3eb3cSopenharmony_ci    }
16323b3eb3cSopenharmony_ci    std::string paramsString;
16423b3eb3cSopenharmony_ci    ParseParams(env, params, paramsString);
16523b3eb3cSopenharmony_ci    std::string uriString;
16623b3eb3cSopenharmony_ci    napi_typeof(env, uriNApi, &valueType);
16723b3eb3cSopenharmony_ci    if (valueType == napi_string) {
16823b3eb3cSopenharmony_ci        ParseUri(env, uriNApi, uriString);
16923b3eb3cSopenharmony_ci    }
17023b3eb3cSopenharmony_ci
17123b3eb3cSopenharmony_ci    uint32_t mode = INVALID;
17223b3eb3cSopenharmony_ci    napi_typeof(env, argv[1], &valueType);
17323b3eb3cSopenharmony_ci    if (argc == ARGC_WITH_MODE && valueType == napi_number) {
17423b3eb3cSopenharmony_ci        napi_get_value_uint32(env, argv[1], &mode);
17523b3eb3cSopenharmony_ci    }
17623b3eb3cSopenharmony_ci    callback(uriString, paramsString, mode);
17723b3eb3cSopenharmony_ci}
17823b3eb3cSopenharmony_ci
17923b3eb3cSopenharmony_cistatic napi_value JSRouterPush(napi_env env, napi_callback_info info)
18023b3eb3cSopenharmony_ci{
18123b3eb3cSopenharmony_ci    auto callback = [](const std::string& uri, const std::string& params, uint32_t mode) {
18223b3eb3cSopenharmony_ci        auto delegate = EngineHelper::GetCurrentDelegateSafely();
18323b3eb3cSopenharmony_ci        if (!delegate) {
18423b3eb3cSopenharmony_ci            return;
18523b3eb3cSopenharmony_ci        }
18623b3eb3cSopenharmony_ci        if (mode == INVALID) {
18723b3eb3cSopenharmony_ci            delegate->Push(uri, params);
18823b3eb3cSopenharmony_ci        } else {
18923b3eb3cSopenharmony_ci            delegate->PushWithMode(uri, params, mode);
19023b3eb3cSopenharmony_ci        }
19123b3eb3cSopenharmony_ci    };
19223b3eb3cSopenharmony_ci    CommonRouterProcess(env, info, callback);
19323b3eb3cSopenharmony_ci    return nullptr;
19423b3eb3cSopenharmony_ci}
19523b3eb3cSopenharmony_ci
19623b3eb3cSopenharmony_cistatic napi_value JSRouterReplace(napi_env env, napi_callback_info info)
19723b3eb3cSopenharmony_ci{
19823b3eb3cSopenharmony_ci    auto callback = [](const std::string& uri, const std::string& params, uint32_t mode) {
19923b3eb3cSopenharmony_ci        auto delegate = EngineHelper::GetCurrentDelegateSafely();
20023b3eb3cSopenharmony_ci        if (!delegate) {
20123b3eb3cSopenharmony_ci            return;
20223b3eb3cSopenharmony_ci        }
20323b3eb3cSopenharmony_ci        if (mode == INVALID) {
20423b3eb3cSopenharmony_ci            delegate->Replace(uri, params);
20523b3eb3cSopenharmony_ci        } else {
20623b3eb3cSopenharmony_ci            delegate->ReplaceWithMode(uri, params, mode);
20723b3eb3cSopenharmony_ci        }
20823b3eb3cSopenharmony_ci    };
20923b3eb3cSopenharmony_ci    CommonRouterProcess(env, info, callback);
21023b3eb3cSopenharmony_ci    return nullptr;
21123b3eb3cSopenharmony_ci}
21223b3eb3cSopenharmony_ci
21323b3eb3cSopenharmony_cibool ParseParamWithCallback(napi_env env, std::shared_ptr<RouterAsyncContext> asyncContext, const size_t argc,
21423b3eb3cSopenharmony_ci    napi_value* argv, napi_value* result)
21523b3eb3cSopenharmony_ci{
21623b3eb3cSopenharmony_ci    asyncContext->env = env;
21723b3eb3cSopenharmony_ci    for (size_t i = 0; i < argc; i++) {
21823b3eb3cSopenharmony_ci        napi_valuetype valueType = napi_undefined;
21923b3eb3cSopenharmony_ci        napi_typeof(env, argv[i], &valueType);
22023b3eb3cSopenharmony_ci        if (i == 0) {
22123b3eb3cSopenharmony_ci            if (valueType != napi_object) {
22223b3eb3cSopenharmony_ci                NapiThrow(env, "The type of parameters is incorrect.", ERROR_CODE_PARAM_INVALID);
22323b3eb3cSopenharmony_ci                return false;
22423b3eb3cSopenharmony_ci            }
22523b3eb3cSopenharmony_ci            napi_value uriNApi = nullptr;
22623b3eb3cSopenharmony_ci            napi_value params = nullptr;
22723b3eb3cSopenharmony_ci            napi_value recoverable = nullptr;
22823b3eb3cSopenharmony_ci            napi_get_named_property(env, argv[i], asyncContext->keyForUrl.c_str(), &uriNApi);
22923b3eb3cSopenharmony_ci            napi_typeof(env, uriNApi, &valueType);
23023b3eb3cSopenharmony_ci            if (valueType != napi_string) {
23123b3eb3cSopenharmony_ci                NapiThrow(env, "The type of the url parameter is not string.", ERROR_CODE_PARAM_INVALID);
23223b3eb3cSopenharmony_ci                return false;
23323b3eb3cSopenharmony_ci            }
23423b3eb3cSopenharmony_ci            ParseUri(env, uriNApi, asyncContext->uriString);
23523b3eb3cSopenharmony_ci            napi_get_named_property(env, argv[i], "params", &params);
23623b3eb3cSopenharmony_ci            ParseParams(env, params, asyncContext->paramsString);
23723b3eb3cSopenharmony_ci            napi_get_named_property(env, argv[i], "recoverable", &recoverable);
23823b3eb3cSopenharmony_ci            ParseRecoverable(env, recoverable, asyncContext->recoverable);
23923b3eb3cSopenharmony_ci        } else if (valueType == napi_number) {
24023b3eb3cSopenharmony_ci            napi_get_value_uint32(env, argv[i], &asyncContext->mode);
24123b3eb3cSopenharmony_ci        } else if (valueType == napi_function) {
24223b3eb3cSopenharmony_ci            napi_create_reference(env, argv[i], 1, &asyncContext->callbackRef);
24323b3eb3cSopenharmony_ci        } else {
24423b3eb3cSopenharmony_ci            NapiThrow(env, "The type of parameters is incorrect.", ERROR_CODE_PARAM_INVALID);
24523b3eb3cSopenharmony_ci            return false;
24623b3eb3cSopenharmony_ci        }
24723b3eb3cSopenharmony_ci    }
24823b3eb3cSopenharmony_ci
24923b3eb3cSopenharmony_ci    if (asyncContext->callbackRef == nullptr) {
25023b3eb3cSopenharmony_ci        if (argc > ARGC_WITH_MODE) {
25123b3eb3cSopenharmony_ci            NapiThrow(env, "The largest number of parameters is 2 in Promise.", ERROR_CODE_PARAM_INVALID);
25223b3eb3cSopenharmony_ci            return false;
25323b3eb3cSopenharmony_ci        }
25423b3eb3cSopenharmony_ci        napi_create_promise(env, &asyncContext->deferred, result);
25523b3eb3cSopenharmony_ci    }
25623b3eb3cSopenharmony_ci    return true;
25723b3eb3cSopenharmony_ci}
25823b3eb3cSopenharmony_ci
25923b3eb3cSopenharmony_civoid TriggerCallback(std::shared_ptr<RouterAsyncContext> asyncContext)
26023b3eb3cSopenharmony_ci{
26123b3eb3cSopenharmony_ci    napi_handle_scope scope = nullptr;
26223b3eb3cSopenharmony_ci    napi_open_handle_scope(asyncContext->env, &scope);
26323b3eb3cSopenharmony_ci    if (scope == nullptr) {
26423b3eb3cSopenharmony_ci        return;
26523b3eb3cSopenharmony_ci    }
26623b3eb3cSopenharmony_ci
26723b3eb3cSopenharmony_ci    if (asyncContext->callbackCode == ERROR_CODE_NO_ERROR) {
26823b3eb3cSopenharmony_ci        napi_value result = nullptr;
26923b3eb3cSopenharmony_ci        napi_get_undefined(asyncContext->env, &result);
27023b3eb3cSopenharmony_ci        if (asyncContext->deferred) {
27123b3eb3cSopenharmony_ci            napi_resolve_deferred(asyncContext->env, asyncContext->deferred, result);
27223b3eb3cSopenharmony_ci        } else {
27323b3eb3cSopenharmony_ci            napi_value callback = nullptr;
27423b3eb3cSopenharmony_ci            napi_get_reference_value(asyncContext->env, asyncContext->callbackRef, &callback);
27523b3eb3cSopenharmony_ci            napi_value ret;
27623b3eb3cSopenharmony_ci            napi_call_function(asyncContext->env, nullptr, callback, 1, &result, &ret);
27723b3eb3cSopenharmony_ci        }
27823b3eb3cSopenharmony_ci    } else {
27923b3eb3cSopenharmony_ci        napi_value code = nullptr;
28023b3eb3cSopenharmony_ci        std::string strCode = std::to_string(asyncContext->callbackCode);
28123b3eb3cSopenharmony_ci        napi_create_string_utf8(asyncContext->env, strCode.c_str(), strCode.length(), &code);
28223b3eb3cSopenharmony_ci
28323b3eb3cSopenharmony_ci        napi_value msg = nullptr;
28423b3eb3cSopenharmony_ci        std::string strMsg = ErrorToMessage(asyncContext->callbackCode) + asyncContext->callbackMsg;
28523b3eb3cSopenharmony_ci        napi_create_string_utf8(asyncContext->env, strMsg.c_str(), strMsg.length(), &msg);
28623b3eb3cSopenharmony_ci
28723b3eb3cSopenharmony_ci        napi_value error = nullptr;
28823b3eb3cSopenharmony_ci        napi_create_error(asyncContext->env, code, msg, &error);
28923b3eb3cSopenharmony_ci        if (asyncContext->deferred) {
29023b3eb3cSopenharmony_ci            napi_reject_deferred(asyncContext->env, asyncContext->deferred, error);
29123b3eb3cSopenharmony_ci        } else {
29223b3eb3cSopenharmony_ci            napi_value callback = nullptr;
29323b3eb3cSopenharmony_ci            napi_get_reference_value(asyncContext->env, asyncContext->callbackRef, &callback);
29423b3eb3cSopenharmony_ci            napi_value ret;
29523b3eb3cSopenharmony_ci            napi_call_function(asyncContext->env, nullptr, callback, 1, &error, &ret);
29623b3eb3cSopenharmony_ci        }
29723b3eb3cSopenharmony_ci    }
29823b3eb3cSopenharmony_ci    napi_close_handle_scope(asyncContext->env, scope);
29923b3eb3cSopenharmony_ci}
30023b3eb3cSopenharmony_ci
30123b3eb3cSopenharmony_ciusing ErrorCallback = std::function<void(const std::string&, int32_t)>;
30223b3eb3cSopenharmony_ciusing RouterWithCallbackFunc = std::function<void(std::shared_ptr<RouterAsyncContext>, const ErrorCallback&)>;
30323b3eb3cSopenharmony_ci
30423b3eb3cSopenharmony_cistatic napi_value CommonRouterWithCallbackProcess(
30523b3eb3cSopenharmony_ci    napi_env env, napi_callback_info info, const RouterWithCallbackFunc& callback, const std::string& keyForUrl)
30623b3eb3cSopenharmony_ci{
30723b3eb3cSopenharmony_ci    napi_value result = nullptr;
30823b3eb3cSopenharmony_ci    napi_get_undefined(env, &result);
30923b3eb3cSopenharmony_ci    size_t requireArgc = 1;
31023b3eb3cSopenharmony_ci    size_t argc = ARGC_WITH_MODE_AND_CALLBACK;
31123b3eb3cSopenharmony_ci    napi_value argv[ARGC_WITH_MODE_AND_CALLBACK] = { 0 };
31223b3eb3cSopenharmony_ci    napi_value thisVar = nullptr;
31323b3eb3cSopenharmony_ci    void* data = nullptr;
31423b3eb3cSopenharmony_ci    napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
31523b3eb3cSopenharmony_ci    if (argc < requireArgc) {
31623b3eb3cSopenharmony_ci        NapiThrow(
31723b3eb3cSopenharmony_ci            env, "The number of parameters must be greater than or equal to 1.", ERROR_CODE_PARAM_INVALID);
31823b3eb3cSopenharmony_ci        return result;
31923b3eb3cSopenharmony_ci    } else if (argc > ARGC_WITH_MODE_AND_CALLBACK) {
32023b3eb3cSopenharmony_ci        NapiThrow(env, "The largest number of parameters is 3.", ERROR_CODE_PARAM_INVALID);
32123b3eb3cSopenharmony_ci        return result;
32223b3eb3cSopenharmony_ci    }
32323b3eb3cSopenharmony_ci
32423b3eb3cSopenharmony_ci    auto asyncContext = std::make_shared<RouterAsyncContext>();
32523b3eb3cSopenharmony_ci    asyncContext->keyForUrl = keyForUrl;
32623b3eb3cSopenharmony_ci    if (!ParseParamWithCallback(env, asyncContext, argc, argv, &result)) {
32723b3eb3cSopenharmony_ci        return result;
32823b3eb3cSopenharmony_ci    }
32923b3eb3cSopenharmony_ci
33023b3eb3cSopenharmony_ci    auto errorCallback = [asyncContext](const std::string& message, int32_t errCode) mutable {
33123b3eb3cSopenharmony_ci        if (!asyncContext) {
33223b3eb3cSopenharmony_ci            return;
33323b3eb3cSopenharmony_ci        }
33423b3eb3cSopenharmony_ci        asyncContext->callbackCode = errCode;
33523b3eb3cSopenharmony_ci        asyncContext->callbackMsg = message;
33623b3eb3cSopenharmony_ci        TriggerCallback(asyncContext);
33723b3eb3cSopenharmony_ci        asyncContext = nullptr;
33823b3eb3cSopenharmony_ci    };
33923b3eb3cSopenharmony_ci    callback(asyncContext, errorCallback);
34023b3eb3cSopenharmony_ci    return result;
34123b3eb3cSopenharmony_ci}
34223b3eb3cSopenharmony_ci
34323b3eb3cSopenharmony_cistatic napi_value JSRouterPushWithCallback(napi_env env, napi_callback_info info)
34423b3eb3cSopenharmony_ci{
34523b3eb3cSopenharmony_ci    auto callback = [](std::shared_ptr<RouterAsyncContext> context, const ErrorCallback& errorCallback) {
34623b3eb3cSopenharmony_ci        auto delegate = EngineHelper::GetCurrentDelegateSafely();
34723b3eb3cSopenharmony_ci        auto defaultDelegate = EngineHelper::GetDefaultDelegate();
34823b3eb3cSopenharmony_ci        if (!delegate && !defaultDelegate) {
34923b3eb3cSopenharmony_ci            NapiThrow(context->env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
35023b3eb3cSopenharmony_ci            return;
35123b3eb3cSopenharmony_ci        }
35223b3eb3cSopenharmony_ci        if (delegate) {
35323b3eb3cSopenharmony_ci            delegate->PushWithCallback(context->uriString, context->paramsString,
35423b3eb3cSopenharmony_ci                context->recoverable, errorCallback, context->mode);
35523b3eb3cSopenharmony_ci        } else {
35623b3eb3cSopenharmony_ci            defaultDelegate->PushWithCallback(context->uriString, context->paramsString,
35723b3eb3cSopenharmony_ci                context->recoverable, errorCallback, context->mode);
35823b3eb3cSopenharmony_ci        }
35923b3eb3cSopenharmony_ci    };
36023b3eb3cSopenharmony_ci    return CommonRouterWithCallbackProcess(env, info, callback, "url");
36123b3eb3cSopenharmony_ci}
36223b3eb3cSopenharmony_ci
36323b3eb3cSopenharmony_cistatic napi_value JSRouterReplaceWithCallback(napi_env env, napi_callback_info info)
36423b3eb3cSopenharmony_ci{
36523b3eb3cSopenharmony_ci    auto callback = [](std::shared_ptr<RouterAsyncContext> context, const ErrorCallback& errorCallback) {
36623b3eb3cSopenharmony_ci        auto delegate = EngineHelper::GetCurrentDelegateSafely();
36723b3eb3cSopenharmony_ci        auto defaultDelegate = EngineHelper::GetDefaultDelegate();
36823b3eb3cSopenharmony_ci        if (!delegate && !defaultDelegate) {
36923b3eb3cSopenharmony_ci            NapiThrow(context->env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
37023b3eb3cSopenharmony_ci            return;
37123b3eb3cSopenharmony_ci        }
37223b3eb3cSopenharmony_ci        if (delegate) {
37323b3eb3cSopenharmony_ci            delegate->ReplaceWithCallback(context->uriString, context->paramsString,
37423b3eb3cSopenharmony_ci                context->recoverable, errorCallback, context->mode);
37523b3eb3cSopenharmony_ci        } else {
37623b3eb3cSopenharmony_ci            defaultDelegate->ReplaceWithCallback(context->uriString, context->paramsString,
37723b3eb3cSopenharmony_ci                context->recoverable, errorCallback, context->mode);
37823b3eb3cSopenharmony_ci        }
37923b3eb3cSopenharmony_ci    };
38023b3eb3cSopenharmony_ci    return CommonRouterWithCallbackProcess(env, info, callback, "url");
38123b3eb3cSopenharmony_ci}
38223b3eb3cSopenharmony_ci
38323b3eb3cSopenharmony_cistatic napi_value JSPushNamedRoute(napi_env env, napi_callback_info info)
38423b3eb3cSopenharmony_ci{
38523b3eb3cSopenharmony_ci    auto callback = [](std::shared_ptr<RouterAsyncContext> context, const ErrorCallback& errorCallback) {
38623b3eb3cSopenharmony_ci        auto delegate = EngineHelper::GetCurrentDelegateSafely();
38723b3eb3cSopenharmony_ci        if (!delegate) {
38823b3eb3cSopenharmony_ci            NapiThrow(context->env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
38923b3eb3cSopenharmony_ci            return;
39023b3eb3cSopenharmony_ci        }
39123b3eb3cSopenharmony_ci        delegate->PushNamedRoute(context->uriString, context->paramsString,
39223b3eb3cSopenharmony_ci            context->recoverable, errorCallback, context->mode);
39323b3eb3cSopenharmony_ci    };
39423b3eb3cSopenharmony_ci    return CommonRouterWithCallbackProcess(env, info, callback, "name");
39523b3eb3cSopenharmony_ci}
39623b3eb3cSopenharmony_ci
39723b3eb3cSopenharmony_cistatic napi_value JSReplaceNamedRoute(napi_env env, napi_callback_info info)
39823b3eb3cSopenharmony_ci{
39923b3eb3cSopenharmony_ci    auto callback = [](std::shared_ptr<RouterAsyncContext> context, const ErrorCallback& errorCallback) {
40023b3eb3cSopenharmony_ci        auto delegate = EngineHelper::GetCurrentDelegateSafely();
40123b3eb3cSopenharmony_ci        if (!delegate) {
40223b3eb3cSopenharmony_ci            NapiThrow(context->env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
40323b3eb3cSopenharmony_ci            return;
40423b3eb3cSopenharmony_ci        }
40523b3eb3cSopenharmony_ci        delegate->ReplaceNamedRoute(context->uriString, context->paramsString,
40623b3eb3cSopenharmony_ci            context->recoverable, errorCallback, context->mode);
40723b3eb3cSopenharmony_ci    };
40823b3eb3cSopenharmony_ci    return CommonRouterWithCallbackProcess(env, info, callback, "name");
40923b3eb3cSopenharmony_ci}
41023b3eb3cSopenharmony_ci
41123b3eb3cSopenharmony_cistatic napi_value JsBackToIndex(napi_env env, napi_callback_info info)
41223b3eb3cSopenharmony_ci{
41323b3eb3cSopenharmony_ci    size_t argc = ARGC_WITH_ROUTER_PARAMTER;
41423b3eb3cSopenharmony_ci    napi_value argv[ARGC_WITH_ROUTER_PARAMTER] = { nullptr };
41523b3eb3cSopenharmony_ci    napi_value thisVar = nullptr;
41623b3eb3cSopenharmony_ci    void* data = nullptr;
41723b3eb3cSopenharmony_ci    napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
41823b3eb3cSopenharmony_ci
41923b3eb3cSopenharmony_ci    auto delegate = EngineHelper::GetCurrentDelegateSafely();
42023b3eb3cSopenharmony_ci    if (!delegate) {
42123b3eb3cSopenharmony_ci        NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
42223b3eb3cSopenharmony_ci        return nullptr;
42323b3eb3cSopenharmony_ci    }
42423b3eb3cSopenharmony_ci    std::string paramsString;
42523b3eb3cSopenharmony_ci    int32_t routeIndex = 0;
42623b3eb3cSopenharmony_ci    napi_valuetype valueType = napi_undefined;
42723b3eb3cSopenharmony_ci    napi_typeof(env, argv[0], &valueType);
42823b3eb3cSopenharmony_ci    if (valueType == napi_number) {
42923b3eb3cSopenharmony_ci        napi_get_value_int32(env, argv[0], &routeIndex);
43023b3eb3cSopenharmony_ci    } else {
43123b3eb3cSopenharmony_ci        TAG_LOGE(AceLogTag::ACE_ROUTER, "Index is not of type number");
43223b3eb3cSopenharmony_ci        return nullptr;
43323b3eb3cSopenharmony_ci    }
43423b3eb3cSopenharmony_ci    napi_typeof(env, argv[1], &valueType);
43523b3eb3cSopenharmony_ci    if (valueType == napi_object) {
43623b3eb3cSopenharmony_ci        ParseParams(env, argv[1], paramsString);
43723b3eb3cSopenharmony_ci    }
43823b3eb3cSopenharmony_ci    delegate->BackToIndex(routeIndex, paramsString);
43923b3eb3cSopenharmony_ci    return nullptr;
44023b3eb3cSopenharmony_ci}
44123b3eb3cSopenharmony_ci
44223b3eb3cSopenharmony_cistatic napi_value JSRouterBack(napi_env env, napi_callback_info info)
44323b3eb3cSopenharmony_ci{
44423b3eb3cSopenharmony_ci    size_t argc = ARGC_WITH_ROUTER_PARAMTER;
44523b3eb3cSopenharmony_ci    napi_value argv[ARGC_WITH_ROUTER_PARAMTER] = { nullptr };
44623b3eb3cSopenharmony_ci    napi_value thisVar = nullptr;
44723b3eb3cSopenharmony_ci    void* data = nullptr;
44823b3eb3cSopenharmony_ci    napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
44923b3eb3cSopenharmony_ci
45023b3eb3cSopenharmony_ci    napi_valuetype valueType = napi_undefined;
45123b3eb3cSopenharmony_ci    napi_typeof(env, argv[0], &valueType);
45223b3eb3cSopenharmony_ci    if (argc == ARGC_WITH_ROUTER_PARAMTER || valueType == napi_number) {
45323b3eb3cSopenharmony_ci        return JsBackToIndex(env, info);
45423b3eb3cSopenharmony_ci    }
45523b3eb3cSopenharmony_ci    auto delegate = EngineHelper::GetCurrentDelegateSafely();
45623b3eb3cSopenharmony_ci    if (!delegate) {
45723b3eb3cSopenharmony_ci        NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
45823b3eb3cSopenharmony_ci        return nullptr;
45923b3eb3cSopenharmony_ci    }
46023b3eb3cSopenharmony_ci    std::string uriString = "";
46123b3eb3cSopenharmony_ci    std::string paramsString = "";
46223b3eb3cSopenharmony_ci    napi_value uriNApi = nullptr;
46323b3eb3cSopenharmony_ci    napi_value params = nullptr;
46423b3eb3cSopenharmony_ci    if (valueType == napi_object) {
46523b3eb3cSopenharmony_ci        napi_get_named_property(env, argv[0], "url", &uriNApi);
46623b3eb3cSopenharmony_ci        napi_typeof(env, uriNApi, &valueType);
46723b3eb3cSopenharmony_ci        if (valueType == napi_undefined) {
46823b3eb3cSopenharmony_ci            napi_get_named_property(env, argv[0], "path", &uriNApi);
46923b3eb3cSopenharmony_ci            napi_typeof(env, uriNApi, &valueType);
47023b3eb3cSopenharmony_ci        }
47123b3eb3cSopenharmony_ci        if (valueType == napi_string) {
47223b3eb3cSopenharmony_ci            ParseUri(env, uriNApi, uriString);
47323b3eb3cSopenharmony_ci        }
47423b3eb3cSopenharmony_ci
47523b3eb3cSopenharmony_ci        napi_get_named_property(env, argv[0], "params", &params);
47623b3eb3cSopenharmony_ci        napi_typeof(env, params, &valueType);
47723b3eb3cSopenharmony_ci        if (valueType == napi_object) {
47823b3eb3cSopenharmony_ci            ParseParams(env, params, paramsString);
47923b3eb3cSopenharmony_ci        }
48023b3eb3cSopenharmony_ci    }
48123b3eb3cSopenharmony_ci    delegate->Back(uriString, paramsString);
48223b3eb3cSopenharmony_ci    return nullptr;
48323b3eb3cSopenharmony_ci}
48423b3eb3cSopenharmony_ci
48523b3eb3cSopenharmony_cistatic napi_value JSRouterClear(napi_env env, napi_callback_info info)
48623b3eb3cSopenharmony_ci{
48723b3eb3cSopenharmony_ci    auto delegate = EngineHelper::GetCurrentDelegateSafely();
48823b3eb3cSopenharmony_ci    if (!delegate) {
48923b3eb3cSopenharmony_ci        NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
49023b3eb3cSopenharmony_ci        return nullptr;
49123b3eb3cSopenharmony_ci    }
49223b3eb3cSopenharmony_ci    delegate->Clear();
49323b3eb3cSopenharmony_ci    return nullptr;
49423b3eb3cSopenharmony_ci}
49523b3eb3cSopenharmony_ci
49623b3eb3cSopenharmony_cistatic napi_value JSRouterGetLength(napi_env env, napi_callback_info info)
49723b3eb3cSopenharmony_ci{
49823b3eb3cSopenharmony_ci    auto delegate = EngineHelper::GetCurrentDelegateSafely();
49923b3eb3cSopenharmony_ci    if (!delegate) {
50023b3eb3cSopenharmony_ci        NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
50123b3eb3cSopenharmony_ci        return nullptr;
50223b3eb3cSopenharmony_ci    }
50323b3eb3cSopenharmony_ci    int32_t routeNumber = delegate->GetStackSize();
50423b3eb3cSopenharmony_ci    napi_value routeNApiNum = nullptr;
50523b3eb3cSopenharmony_ci    napi_create_int32(env, routeNumber, &routeNApiNum);
50623b3eb3cSopenharmony_ci    napi_value result = nullptr;
50723b3eb3cSopenharmony_ci    napi_coerce_to_string(env, routeNApiNum, &result);
50823b3eb3cSopenharmony_ci    return result;
50923b3eb3cSopenharmony_ci}
51023b3eb3cSopenharmony_ci
51123b3eb3cSopenharmony_cistatic napi_value JSRouterGetState(napi_env env, napi_callback_info info)
51223b3eb3cSopenharmony_ci{
51323b3eb3cSopenharmony_ci    int32_t routeIndex = 0;
51423b3eb3cSopenharmony_ci    std::string routeName;
51523b3eb3cSopenharmony_ci    std::string routePath;
51623b3eb3cSopenharmony_ci    auto delegate = EngineHelper::GetCurrentDelegateSafely();
51723b3eb3cSopenharmony_ci    if (!delegate) {
51823b3eb3cSopenharmony_ci        NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
51923b3eb3cSopenharmony_ci        return nullptr;
52023b3eb3cSopenharmony_ci    }
52123b3eb3cSopenharmony_ci    delegate->GetState(routeIndex, routeName, routePath);
52223b3eb3cSopenharmony_ci    size_t routeNameLen = routeName.length();
52323b3eb3cSopenharmony_ci    size_t routePathLen = routePath.length();
52423b3eb3cSopenharmony_ci
52523b3eb3cSopenharmony_ci    std::string paramsStr = delegate->GetParams();
52623b3eb3cSopenharmony_ci    napi_value params = paramsStr.empty() ? nullptr : ParseJSONParams(env, paramsStr);
52723b3eb3cSopenharmony_ci    napi_value resultArray[RESULT_ARRAY_LENGTH] = { 0 };
52823b3eb3cSopenharmony_ci    napi_create_int32(env, routeIndex, &resultArray[RESULT_ARRAY_INDEX_INDEX]);
52923b3eb3cSopenharmony_ci    napi_create_string_utf8(env, routeName.c_str(), routeNameLen, &resultArray[RESULT_ARRAY_NAME_INDEX]);
53023b3eb3cSopenharmony_ci    napi_create_string_utf8(env, routePath.c_str(), routePathLen, &resultArray[RESULT_ARRAY_PATH_INDEX]);
53123b3eb3cSopenharmony_ci
53223b3eb3cSopenharmony_ci    napi_value result = nullptr;
53323b3eb3cSopenharmony_ci    napi_create_object(env, &result);
53423b3eb3cSopenharmony_ci    napi_set_named_property(env, result, "index", resultArray[RESULT_ARRAY_INDEX_INDEX]);
53523b3eb3cSopenharmony_ci    napi_set_named_property(env, result, "name", resultArray[RESULT_ARRAY_NAME_INDEX]);
53623b3eb3cSopenharmony_ci    napi_set_named_property(env, result, "path", resultArray[RESULT_ARRAY_PATH_INDEX]);
53723b3eb3cSopenharmony_ci    napi_set_named_property(env, result, "params", params);
53823b3eb3cSopenharmony_ci    return result;
53923b3eb3cSopenharmony_ci}
54023b3eb3cSopenharmony_ci
54123b3eb3cSopenharmony_cistatic napi_value JSGetStateByIndex(napi_env env, napi_callback_info info)
54223b3eb3cSopenharmony_ci{
54323b3eb3cSopenharmony_ci    size_t argc = 1;
54423b3eb3cSopenharmony_ci    napi_value argv = nullptr;
54523b3eb3cSopenharmony_ci    napi_value thisVar = nullptr;
54623b3eb3cSopenharmony_ci    void* data = nullptr;
54723b3eb3cSopenharmony_ci    napi_get_cb_info(env, info, &argc, &argv, &thisVar, &data);
54823b3eb3cSopenharmony_ci
54923b3eb3cSopenharmony_ci    int32_t routeIndex = 0;
55023b3eb3cSopenharmony_ci    std::string routeName;
55123b3eb3cSopenharmony_ci    std::string routePath;
55223b3eb3cSopenharmony_ci    std::string routeParams;
55323b3eb3cSopenharmony_ci    napi_valuetype valueType = napi_undefined;
55423b3eb3cSopenharmony_ci    napi_typeof(env, argv, &valueType);
55523b3eb3cSopenharmony_ci    if (valueType == napi_number) {
55623b3eb3cSopenharmony_ci        napi_get_value_int32(env, argv, &routeIndex);
55723b3eb3cSopenharmony_ci    }
55823b3eb3cSopenharmony_ci    auto delegate = EngineHelper::GetCurrentDelegateSafely();
55923b3eb3cSopenharmony_ci    if (!delegate) {
56023b3eb3cSopenharmony_ci        NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
56123b3eb3cSopenharmony_ci        return nullptr;
56223b3eb3cSopenharmony_ci    }
56323b3eb3cSopenharmony_ci
56423b3eb3cSopenharmony_ci    delegate->GetRouterStateByIndex(routeIndex, routeName, routePath, routeParams);
56523b3eb3cSopenharmony_ci    if (routeName.empty()) {
56623b3eb3cSopenharmony_ci        napi_value undefined;
56723b3eb3cSopenharmony_ci        napi_get_undefined(env, &undefined);
56823b3eb3cSopenharmony_ci        return undefined;
56923b3eb3cSopenharmony_ci    }
57023b3eb3cSopenharmony_ci    size_t routeNameLen = routeName.length();
57123b3eb3cSopenharmony_ci    size_t routePathLen = routePath.length();
57223b3eb3cSopenharmony_ci
57323b3eb3cSopenharmony_ci    napi_value resultArray[RESULT_ARRAY_LENGTH] = { 0 };
57423b3eb3cSopenharmony_ci    napi_create_int32(env, routeIndex, &resultArray[RESULT_ARRAY_INDEX_INDEX]);
57523b3eb3cSopenharmony_ci    napi_create_string_utf8(env, routeName.c_str(), routeNameLen, &resultArray[RESULT_ARRAY_NAME_INDEX]);
57623b3eb3cSopenharmony_ci    napi_create_string_utf8(env, routePath.c_str(), routePathLen, &resultArray[RESULT_ARRAY_PATH_INDEX]);
57723b3eb3cSopenharmony_ci
57823b3eb3cSopenharmony_ci    napi_value parsedParams = nullptr;
57923b3eb3cSopenharmony_ci    if (!routeParams.empty()) {
58023b3eb3cSopenharmony_ci        parsedParams = ParseJSONParams(env, routeParams);
58123b3eb3cSopenharmony_ci    } else {
58223b3eb3cSopenharmony_ci        napi_create_object(env, &parsedParams);
58323b3eb3cSopenharmony_ci    }
58423b3eb3cSopenharmony_ci
58523b3eb3cSopenharmony_ci    napi_value result = nullptr;
58623b3eb3cSopenharmony_ci    napi_create_object(env, &result);
58723b3eb3cSopenharmony_ci    napi_set_named_property(env, result, "index", resultArray[RESULT_ARRAY_INDEX_INDEX]);
58823b3eb3cSopenharmony_ci    napi_set_named_property(env, result, "name", resultArray[RESULT_ARRAY_NAME_INDEX]);
58923b3eb3cSopenharmony_ci    napi_set_named_property(env, result, "path", resultArray[RESULT_ARRAY_PATH_INDEX]);
59023b3eb3cSopenharmony_ci    napi_set_named_property(env, result, "params", parsedParams);
59123b3eb3cSopenharmony_ci    return result;
59223b3eb3cSopenharmony_ci}
59323b3eb3cSopenharmony_ci
59423b3eb3cSopenharmony_cistatic napi_value JSGetStateByUrl(napi_env env, napi_callback_info info)
59523b3eb3cSopenharmony_ci{
59623b3eb3cSopenharmony_ci    size_t argc = 1;
59723b3eb3cSopenharmony_ci    napi_value argv = nullptr;
59823b3eb3cSopenharmony_ci    napi_value thisVar = nullptr;
59923b3eb3cSopenharmony_ci    void* data = nullptr;
60023b3eb3cSopenharmony_ci    napi_get_cb_info(env, info, &argc, &argv, &thisVar, &data);
60123b3eb3cSopenharmony_ci
60223b3eb3cSopenharmony_ci    auto delegate = EngineHelper::GetCurrentDelegateSafely();
60323b3eb3cSopenharmony_ci    if (!delegate) {
60423b3eb3cSopenharmony_ci        NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
60523b3eb3cSopenharmony_ci        return nullptr;
60623b3eb3cSopenharmony_ci    }
60723b3eb3cSopenharmony_ci    std::string uriString;
60823b3eb3cSopenharmony_ci    napi_valuetype valueType = napi_undefined;
60923b3eb3cSopenharmony_ci    napi_typeof(env, argv, &valueType);
61023b3eb3cSopenharmony_ci    if (valueType == napi_string) {
61123b3eb3cSopenharmony_ci        ParseUri(env, argv, uriString);
61223b3eb3cSopenharmony_ci    }
61323b3eb3cSopenharmony_ci    std::vector<Framework::StateInfo> stateArray;
61423b3eb3cSopenharmony_ci    delegate->GetRouterStateByUrl(uriString, stateArray);
61523b3eb3cSopenharmony_ci
61623b3eb3cSopenharmony_ci    napi_value result = nullptr;
61723b3eb3cSopenharmony_ci    napi_create_array(env, &result);
61823b3eb3cSopenharmony_ci    int32_t index = 0;
61923b3eb3cSopenharmony_ci    for (const auto& info : stateArray) {
62023b3eb3cSopenharmony_ci        napi_value pageObj = nullptr;
62123b3eb3cSopenharmony_ci        napi_create_object(env, &pageObj);
62223b3eb3cSopenharmony_ci        int32_t routeIndex = info.index;
62323b3eb3cSopenharmony_ci        std::string routeName = info.name;
62423b3eb3cSopenharmony_ci        std::string routePath = info.path;
62523b3eb3cSopenharmony_ci        std::string routeParams = info.params;
62623b3eb3cSopenharmony_ci        napi_value indexValue = nullptr;
62723b3eb3cSopenharmony_ci        napi_value nameValue = nullptr;
62823b3eb3cSopenharmony_ci        napi_value pathValue = nullptr;
62923b3eb3cSopenharmony_ci
63023b3eb3cSopenharmony_ci        napi_create_int32(env, routeIndex, &indexValue);
63123b3eb3cSopenharmony_ci        napi_create_string_utf8(env, routeName.c_str(), NAPI_AUTO_LENGTH, &nameValue);
63223b3eb3cSopenharmony_ci        napi_create_string_utf8(env, routePath.c_str(), NAPI_AUTO_LENGTH, &pathValue);
63323b3eb3cSopenharmony_ci        napi_value parsedParams = nullptr;
63423b3eb3cSopenharmony_ci        if (!routeParams.empty()) {
63523b3eb3cSopenharmony_ci            parsedParams = ParseJSONParams(env, routeParams);
63623b3eb3cSopenharmony_ci        } else {
63723b3eb3cSopenharmony_ci            napi_create_object(env, &parsedParams);
63823b3eb3cSopenharmony_ci        }
63923b3eb3cSopenharmony_ci        napi_set_named_property(env, pageObj, "index", indexValue);
64023b3eb3cSopenharmony_ci        napi_set_named_property(env, pageObj, "name", nameValue);
64123b3eb3cSopenharmony_ci        napi_set_named_property(env, pageObj, "path", pathValue);
64223b3eb3cSopenharmony_ci        napi_set_named_property(env, pageObj, "params", parsedParams);
64323b3eb3cSopenharmony_ci        napi_set_element(env, result, index++, pageObj);
64423b3eb3cSopenharmony_ci    }
64523b3eb3cSopenharmony_ci    return result;
64623b3eb3cSopenharmony_ci}
64723b3eb3cSopenharmony_ci
64823b3eb3cSopenharmony_civoid CallBackToJSTread(std::shared_ptr<RouterAsyncContext> context)
64923b3eb3cSopenharmony_ci{
65023b3eb3cSopenharmony_ci    auto container = AceEngine::Get().GetContainer(context->instanceId);
65123b3eb3cSopenharmony_ci    if (!container) {
65223b3eb3cSopenharmony_ci        return;
65323b3eb3cSopenharmony_ci    }
65423b3eb3cSopenharmony_ci
65523b3eb3cSopenharmony_ci    auto taskExecutor = container->GetTaskExecutor();
65623b3eb3cSopenharmony_ci    if (!taskExecutor) {
65723b3eb3cSopenharmony_ci        return;
65823b3eb3cSopenharmony_ci    }
65923b3eb3cSopenharmony_ci    taskExecutor->PostTask(
66023b3eb3cSopenharmony_ci        [context]() {
66123b3eb3cSopenharmony_ci            napi_handle_scope scope = nullptr;
66223b3eb3cSopenharmony_ci            napi_open_handle_scope(context->env, &scope);
66323b3eb3cSopenharmony_ci            if (scope == nullptr) {
66423b3eb3cSopenharmony_ci                return;
66523b3eb3cSopenharmony_ci            }
66623b3eb3cSopenharmony_ci
66723b3eb3cSopenharmony_ci            napi_value result = nullptr;
66823b3eb3cSopenharmony_ci            napi_value callback = nullptr;
66923b3eb3cSopenharmony_ci            napi_value ret = nullptr;
67023b3eb3cSopenharmony_ci            if (Framework::AlertState(context->callbackType) == Framework::AlertState::USER_CONFIRM) {
67123b3eb3cSopenharmony_ci                if (context->callbackSuccess) {
67223b3eb3cSopenharmony_ci                    napi_create_string_utf8(context->env, EN_ALERT_APPROVE, NAPI_AUTO_LENGTH, &result);
67323b3eb3cSopenharmony_ci                    napi_value argv[1] = { result };
67423b3eb3cSopenharmony_ci                    napi_get_reference_value(context->env, context->callbackSuccess, &callback);
67523b3eb3cSopenharmony_ci                    napi_call_function(context->env, nullptr, callback, 1, argv, &ret);
67623b3eb3cSopenharmony_ci                }
67723b3eb3cSopenharmony_ci                if (context->callbackComplete) {
67823b3eb3cSopenharmony_ci                    napi_get_reference_value(context->env, context->callbackComplete, &callback);
67923b3eb3cSopenharmony_ci                    napi_call_function(context->env, nullptr, callback, 0, nullptr, &ret);
68023b3eb3cSopenharmony_ci                }
68123b3eb3cSopenharmony_ci            }
68223b3eb3cSopenharmony_ci            if (Framework::AlertState(context->callbackType) == Framework::AlertState::USER_CANCEL) {
68323b3eb3cSopenharmony_ci                if (context->callbackFail) {
68423b3eb3cSopenharmony_ci                    napi_create_string_utf8(context->env, EN_ALERT_REJECT, NAPI_AUTO_LENGTH, &result);
68523b3eb3cSopenharmony_ci                    napi_value argv[1] = { result };
68623b3eb3cSopenharmony_ci                    napi_get_reference_value(context->env, context->callbackFail, &callback);
68723b3eb3cSopenharmony_ci                    napi_call_function(context->env, nullptr, callback, 1, argv, &ret);
68823b3eb3cSopenharmony_ci                }
68923b3eb3cSopenharmony_ci                if (context->callbackComplete) {
69023b3eb3cSopenharmony_ci                    napi_get_reference_value(context->env, context->callbackComplete, &callback);
69123b3eb3cSopenharmony_ci                    napi_call_function(context->env, nullptr, callback, 0, nullptr, &ret);
69223b3eb3cSopenharmony_ci                }
69323b3eb3cSopenharmony_ci            }
69423b3eb3cSopenharmony_ci
69523b3eb3cSopenharmony_ci            napi_close_handle_scope(context->env, scope);
69623b3eb3cSopenharmony_ci        },
69723b3eb3cSopenharmony_ci        TaskExecutor::TaskType::JS, "ArkUIRouterAlertCallback");
69823b3eb3cSopenharmony_ci}
69923b3eb3cSopenharmony_ci
70023b3eb3cSopenharmony_cistatic napi_value JSRouterEnableAlertBeforeBackPage(napi_env env, napi_callback_info info)
70123b3eb3cSopenharmony_ci{
70223b3eb3cSopenharmony_ci    size_t argc = 1;
70323b3eb3cSopenharmony_ci    napi_value argv = nullptr;
70423b3eb3cSopenharmony_ci    napi_value thisVar = nullptr;
70523b3eb3cSopenharmony_ci    void* data = nullptr;
70623b3eb3cSopenharmony_ci    napi_get_cb_info(env, info, &argc, &argv, &thisVar, &data);
70723b3eb3cSopenharmony_ci
70823b3eb3cSopenharmony_ci    napi_valuetype valueType = napi_undefined;
70923b3eb3cSopenharmony_ci    napi_typeof(env, argv, &valueType);
71023b3eb3cSopenharmony_ci    if (valueType != napi_object) {
71123b3eb3cSopenharmony_ci        NapiThrow(env, "The type of the parameter is not object.", ERROR_CODE_PARAM_INVALID);
71223b3eb3cSopenharmony_ci        return nullptr;
71323b3eb3cSopenharmony_ci    }
71423b3eb3cSopenharmony_ci
71523b3eb3cSopenharmony_ci    napi_value messageNapi = nullptr;
71623b3eb3cSopenharmony_ci    std::unique_ptr<char[]> messageChar;
71723b3eb3cSopenharmony_ci    napi_get_named_property(env, argv, "message", &messageNapi);
71823b3eb3cSopenharmony_ci    napi_typeof(env, messageNapi, &valueType);
71923b3eb3cSopenharmony_ci    if (valueType == napi_string) {
72023b3eb3cSopenharmony_ci        size_t length = 0;
72123b3eb3cSopenharmony_ci        napi_get_value_string_utf8(env, messageNapi, nullptr, 0, &length);
72223b3eb3cSopenharmony_ci        messageChar = std::make_unique<char[]>(length + 1);
72323b3eb3cSopenharmony_ci        napi_get_value_string_utf8(env, messageNapi, messageChar.get(), length + 1, &length);
72423b3eb3cSopenharmony_ci    } else {
72523b3eb3cSopenharmony_ci        NapiThrow(env, "The type of the message is not string.", ERROR_CODE_PARAM_INVALID);
72623b3eb3cSopenharmony_ci        return nullptr;
72723b3eb3cSopenharmony_ci    }
72823b3eb3cSopenharmony_ci
72923b3eb3cSopenharmony_ci    auto delegate = EngineHelper::GetCurrentDelegateSafely();
73023b3eb3cSopenharmony_ci    if (!delegate) {
73123b3eb3cSopenharmony_ci        NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
73223b3eb3cSopenharmony_ci        return nullptr;
73323b3eb3cSopenharmony_ci    }
73423b3eb3cSopenharmony_ci
73523b3eb3cSopenharmony_ci    auto context = std::make_shared<RouterAsyncContext>();
73623b3eb3cSopenharmony_ci    context->env = env;
73723b3eb3cSopenharmony_ci    context->instanceId = Container::CurrentIdSafely();
73823b3eb3cSopenharmony_ci    napi_value successFunc = nullptr;
73923b3eb3cSopenharmony_ci    napi_value failFunc = nullptr;
74023b3eb3cSopenharmony_ci    napi_value completeFunc = nullptr;
74123b3eb3cSopenharmony_ci    napi_get_named_property(env, argv, "success", &successFunc);
74223b3eb3cSopenharmony_ci    napi_get_named_property(env, argv, "cancel", &failFunc);
74323b3eb3cSopenharmony_ci    napi_get_named_property(env, argv, "complete", &completeFunc);
74423b3eb3cSopenharmony_ci    bool isNeedCallBack = false;
74523b3eb3cSopenharmony_ci    napi_typeof(env, successFunc, &valueType);
74623b3eb3cSopenharmony_ci    if (valueType == napi_function) {
74723b3eb3cSopenharmony_ci        napi_create_reference(env, successFunc, 1, &context->callbackSuccess);
74823b3eb3cSopenharmony_ci        isNeedCallBack = true;
74923b3eb3cSopenharmony_ci    }
75023b3eb3cSopenharmony_ci
75123b3eb3cSopenharmony_ci    napi_typeof(env, failFunc, &valueType);
75223b3eb3cSopenharmony_ci    if (valueType == napi_function) {
75323b3eb3cSopenharmony_ci        napi_create_reference(env, failFunc, 1, &context->callbackFail);
75423b3eb3cSopenharmony_ci        isNeedCallBack = true;
75523b3eb3cSopenharmony_ci    }
75623b3eb3cSopenharmony_ci    napi_typeof(env, completeFunc, &valueType);
75723b3eb3cSopenharmony_ci    if (valueType == napi_function) {
75823b3eb3cSopenharmony_ci        napi_create_reference(env, completeFunc, 1, &context->callbackComplete);
75923b3eb3cSopenharmony_ci        isNeedCallBack = true;
76023b3eb3cSopenharmony_ci    }
76123b3eb3cSopenharmony_ci
76223b3eb3cSopenharmony_ci    auto dilogCallback = [context, isNeedCallBack](int32_t callbackType) mutable {
76323b3eb3cSopenharmony_ci        if (context && isNeedCallBack) {
76423b3eb3cSopenharmony_ci            if (Framework::AlertState(callbackType) == Framework::AlertState::RECOVERY) {
76523b3eb3cSopenharmony_ci                context = nullptr;
76623b3eb3cSopenharmony_ci                return;
76723b3eb3cSopenharmony_ci            }
76823b3eb3cSopenharmony_ci            context->callbackType = callbackType;
76923b3eb3cSopenharmony_ci            CallBackToJSTread(context);
77023b3eb3cSopenharmony_ci        }
77123b3eb3cSopenharmony_ci    };
77223b3eb3cSopenharmony_ci    delegate->EnableAlertBeforeBackPage(messageChar.get(), std::move(dilogCallback));
77323b3eb3cSopenharmony_ci
77423b3eb3cSopenharmony_ci    return nullptr;
77523b3eb3cSopenharmony_ci}
77623b3eb3cSopenharmony_ci
77723b3eb3cSopenharmony_cistatic napi_value JSRouterDisableAlertBeforeBackPage(napi_env env, napi_callback_info info)
77823b3eb3cSopenharmony_ci{
77923b3eb3cSopenharmony_ci    auto delegate = EngineHelper::GetCurrentDelegateSafely();
78023b3eb3cSopenharmony_ci    if (delegate) {
78123b3eb3cSopenharmony_ci        delegate->DisableAlertBeforeBackPage();
78223b3eb3cSopenharmony_ci    } else {
78323b3eb3cSopenharmony_ci        NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
78423b3eb3cSopenharmony_ci        return nullptr;
78523b3eb3cSopenharmony_ci    }
78623b3eb3cSopenharmony_ci
78723b3eb3cSopenharmony_ci    size_t argc = 1;
78823b3eb3cSopenharmony_ci    napi_value argv = nullptr;
78923b3eb3cSopenharmony_ci    napi_value thisVar = nullptr;
79023b3eb3cSopenharmony_ci    void* data = nullptr;
79123b3eb3cSopenharmony_ci    napi_get_cb_info(env, info, &argc, &argv, &thisVar, &data);
79223b3eb3cSopenharmony_ci    napi_valuetype valueType = napi_undefined;
79323b3eb3cSopenharmony_ci    napi_typeof(env, argv, &valueType);
79423b3eb3cSopenharmony_ci    if (valueType == napi_object) {
79523b3eb3cSopenharmony_ci        napi_value successFunc = nullptr;
79623b3eb3cSopenharmony_ci        napi_value completeFunc = nullptr;
79723b3eb3cSopenharmony_ci        napi_get_named_property(env, argv, "success", &successFunc);
79823b3eb3cSopenharmony_ci        napi_get_named_property(env, argv, "complete", &completeFunc);
79923b3eb3cSopenharmony_ci
80023b3eb3cSopenharmony_ci        napi_value result = nullptr;
80123b3eb3cSopenharmony_ci        napi_value ret = nullptr;
80223b3eb3cSopenharmony_ci        napi_create_string_utf8(env, DIS_ALERT_SUCCESS, NAPI_AUTO_LENGTH, &result);
80323b3eb3cSopenharmony_ci        napi_value argv[1] = { result };
80423b3eb3cSopenharmony_ci
80523b3eb3cSopenharmony_ci        napi_typeof(env, successFunc, &valueType);
80623b3eb3cSopenharmony_ci        if (valueType == napi_function) {
80723b3eb3cSopenharmony_ci            napi_call_function(env, nullptr, successFunc, 1, argv, &ret);
80823b3eb3cSopenharmony_ci        }
80923b3eb3cSopenharmony_ci        napi_typeof(env, completeFunc, &valueType);
81023b3eb3cSopenharmony_ci        if (valueType == napi_function) {
81123b3eb3cSopenharmony_ci            napi_call_function(env, nullptr, completeFunc, 1, argv, &ret);
81223b3eb3cSopenharmony_ci        }
81323b3eb3cSopenharmony_ci    }
81423b3eb3cSopenharmony_ci    return nullptr;
81523b3eb3cSopenharmony_ci}
81623b3eb3cSopenharmony_ci
81723b3eb3cSopenharmony_cistatic napi_value JSRouterGetParams(napi_env env, napi_callback_info info)
81823b3eb3cSopenharmony_ci{
81923b3eb3cSopenharmony_ci    auto delegate = EngineHelper::GetCurrentDelegateSafely();
82023b3eb3cSopenharmony_ci    if (!delegate) {
82123b3eb3cSopenharmony_ci        NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
82223b3eb3cSopenharmony_ci        return nullptr;
82323b3eb3cSopenharmony_ci    }
82423b3eb3cSopenharmony_ci    std::string paramsStr = delegate->GetParams();
82523b3eb3cSopenharmony_ci    if (paramsStr.empty()) {
82623b3eb3cSopenharmony_ci        return nullptr;
82723b3eb3cSopenharmony_ci    }
82823b3eb3cSopenharmony_ci    napi_value result = ParseJSONParams(env, paramsStr);
82923b3eb3cSopenharmony_ci    return result;
83023b3eb3cSopenharmony_ci}
83123b3eb3cSopenharmony_ci
83223b3eb3cSopenharmony_cistatic napi_value RouterExport(napi_env env, napi_value exports)
83323b3eb3cSopenharmony_ci{
83423b3eb3cSopenharmony_ci    napi_value routerMode = nullptr;
83523b3eb3cSopenharmony_ci    napi_create_object(env, &routerMode);
83623b3eb3cSopenharmony_ci    napi_value prop = nullptr;
83723b3eb3cSopenharmony_ci    napi_create_uint32(env, STANDARD, &prop);
83823b3eb3cSopenharmony_ci    napi_set_named_property(env, routerMode, "Standard", prop);
83923b3eb3cSopenharmony_ci    napi_create_uint32(env, SINGLE, &prop);
84023b3eb3cSopenharmony_ci    napi_set_named_property(env, routerMode, "Single", prop);
84123b3eb3cSopenharmony_ci
84223b3eb3cSopenharmony_ci    napi_property_descriptor routerDesc[] = {
84323b3eb3cSopenharmony_ci        DECLARE_NAPI_FUNCTION("push", JSRouterPush),
84423b3eb3cSopenharmony_ci        DECLARE_NAPI_FUNCTION("pushUrl", JSRouterPushWithCallback),
84523b3eb3cSopenharmony_ci        DECLARE_NAPI_FUNCTION("replace", JSRouterReplace),
84623b3eb3cSopenharmony_ci        DECLARE_NAPI_FUNCTION("replaceUrl", JSRouterReplaceWithCallback),
84723b3eb3cSopenharmony_ci        DECLARE_NAPI_FUNCTION("back", JSRouterBack),
84823b3eb3cSopenharmony_ci        DECLARE_NAPI_FUNCTION("clear", JSRouterClear),
84923b3eb3cSopenharmony_ci        DECLARE_NAPI_FUNCTION("getLength", JSRouterGetLength),
85023b3eb3cSopenharmony_ci        DECLARE_NAPI_FUNCTION("getState", JSRouterGetState),
85123b3eb3cSopenharmony_ci        DECLARE_NAPI_FUNCTION("getStateByIndex", JSGetStateByIndex),
85223b3eb3cSopenharmony_ci        DECLARE_NAPI_FUNCTION("getStateByUrl", JSGetStateByUrl),
85323b3eb3cSopenharmony_ci        DECLARE_NAPI_FUNCTION("enableAlertBeforeBackPage", JSRouterEnableAlertBeforeBackPage),
85423b3eb3cSopenharmony_ci        DECLARE_NAPI_FUNCTION("enableBackPageAlert", JSRouterEnableAlertBeforeBackPage),
85523b3eb3cSopenharmony_ci        DECLARE_NAPI_FUNCTION("showAlertBeforeBackPage", JSRouterEnableAlertBeforeBackPage),
85623b3eb3cSopenharmony_ci        DECLARE_NAPI_FUNCTION("disableAlertBeforeBackPage", JSRouterDisableAlertBeforeBackPage),
85723b3eb3cSopenharmony_ci        DECLARE_NAPI_FUNCTION("hideAlertBeforeBackPage", JSRouterDisableAlertBeforeBackPage),
85823b3eb3cSopenharmony_ci        DECLARE_NAPI_FUNCTION("getParams", JSRouterGetParams),
85923b3eb3cSopenharmony_ci        DECLARE_NAPI_FUNCTION("pushNamedRoute", JSPushNamedRoute),
86023b3eb3cSopenharmony_ci        DECLARE_NAPI_FUNCTION("replaceNamedRoute", JSReplaceNamedRoute),
86123b3eb3cSopenharmony_ci        DECLARE_NAPI_PROPERTY("RouterMode", routerMode),
86223b3eb3cSopenharmony_ci    };
86323b3eb3cSopenharmony_ci    NAPI_CALL(env, napi_define_properties(env, exports, sizeof(routerDesc) / sizeof(routerDesc[0]), routerDesc));
86423b3eb3cSopenharmony_ci
86523b3eb3cSopenharmony_ci    return exports;
86623b3eb3cSopenharmony_ci}
86723b3eb3cSopenharmony_ci
86823b3eb3cSopenharmony_cistatic napi_module routerModule = {
86923b3eb3cSopenharmony_ci    .nm_version = 1,
87023b3eb3cSopenharmony_ci    .nm_flags = 0,
87123b3eb3cSopenharmony_ci    .nm_filename = nullptr,
87223b3eb3cSopenharmony_ci    .nm_register_func = RouterExport,
87323b3eb3cSopenharmony_ci    .nm_modname = "router",
87423b3eb3cSopenharmony_ci    .nm_priv = ((void*)0),
87523b3eb3cSopenharmony_ci    .reserved = { 0 },
87623b3eb3cSopenharmony_ci};
87723b3eb3cSopenharmony_ci
87823b3eb3cSopenharmony_ciextern "C" __attribute__((constructor)) void RouterRegister()
87923b3eb3cSopenharmony_ci{
88023b3eb3cSopenharmony_ci    napi_module_register(&routerModule);
88123b3eb3cSopenharmony_ci}
88223b3eb3cSopenharmony_ci
88323b3eb3cSopenharmony_ci} // namespace OHOS::Ace::Napi
884