• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
17 
18 #include "arkts_utils.h"
19 #include "ecmascript/napi/include/jsnapi.h"
20 #include "jsnapi_expo.h"
21 
22 #include "base/utils/utils.h"
23 #include "bridge/declarative_frontend/engine/js_converter.h"
24 #include "frameworks/base/image/pixel_map.h"
25 #include "frameworks/base/utils/system_properties.h"
26 #include "frameworks/bridge/common/utils/engine_helper.h"
27 #include "frameworks/bridge/declarative_frontend/engine/jsi/js_ui_index.h"
28 #include "frameworks/bridge/declarative_frontend/jsview/js_utils.h"
29 #include "frameworks/core/common/card_scope.h"
30 #include "frameworks/core/common/resource/resource_configuration.h"
31 #include "frameworks/core/common/resource/resource_parse_utils.h"
32 #include "frameworks/core/components/text_overlay/text_overlay_theme.h"
33 
34 namespace OHOS::Ace::NG {
35 namespace {
GetBundleNameFromContainer()36 std::string GetBundleNameFromContainer()
37 {
38     auto container = Container::Current();
39     CHECK_NULL_RETURN(container, "");
40     return container->GetBundleName();
41 }
42 
GetModuleNameFromContainer()43 std::string GetModuleNameFromContainer()
44 {
45     auto container = Container::Current();
46     CHECK_NULL_RETURN(container, "");
47     return container->GetModuleName();
48 }
49 
50 enum class MenuItemType {
51     COPY,
52     PASTE,
53     CUT,
54     SELECT_ALL,
55     UNKNOWN,
56     CAMERA_INPUT,
57     AI_WRITER,
58     TRANSLATE,
59     SHARE,
60     SEARCH,
61     ASK_CELIA
62 };
63 
StringToMenuItemType(std::string_view id)64 MenuItemType StringToMenuItemType(std::string_view id)
65 {
66     static const std::unordered_map<std::string_view, MenuItemType> keyMenuItemMap = {
67         { "OH_DEFAULT_COPY", MenuItemType::COPY },
68         { "OH_DEFAULT_PASTE", MenuItemType::PASTE },
69         { "OH_DEFAULT_CUT", MenuItemType::CUT },
70         { "OH_DEFAULT_SELECT_ALL", MenuItemType::SELECT_ALL },
71         { "OH_DEFAULT_CAMERA_INPUT", MenuItemType::CAMERA_INPUT },
72         { "OH_DEFAULT_AI_WRITE", MenuItemType::AI_WRITER },
73         { "OH_DEFAULT_TRANSLATE", MenuItemType::TRANSLATE },
74         { "OH_DEFAULT_SHARE", MenuItemType::SHARE },
75         { "OH_DEFAULT_SEARCH", MenuItemType::SEARCH },
76         { "OH_DEFAULT_ASK_CELIA", MenuItemType::ASK_CELIA },
77     };
78 
79     auto item = keyMenuItemMap.find(id);
80     return item != keyMenuItemMap.end() ? item->second : MenuItemType::UNKNOWN;
81 }
82 
UpdateInfoById(NG::MenuOptionsParam & menuOptionsParam,std::string_view id)83 void UpdateInfoById(NG::MenuOptionsParam& menuOptionsParam, std::string_view id)
84 {
85     auto opType = StringToMenuItemType(id);
86     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
87     CHECK_NULL_VOID(pipeline);
88     auto theme = pipeline->GetTheme<TextOverlayTheme>();
89     CHECK_NULL_VOID(theme);
90     switch (opType) {
91         case MenuItemType::COPY:
92             menuOptionsParam.labelInfo = theme->GetCopyLabelInfo();
93             menuOptionsParam.symbolId = theme->GetCopySymbolId();
94             break;
95         case MenuItemType::PASTE:
96             menuOptionsParam.labelInfo = theme->GetPasteLabelInfo();
97             menuOptionsParam.symbolId = theme->GetPasteSymbolId();
98             break;
99         case MenuItemType::CUT:
100             menuOptionsParam.labelInfo = theme->GetCutLabelInfo();
101             menuOptionsParam.symbolId = theme->GetCutSymbolId();
102             break;
103         case MenuItemType::SELECT_ALL:
104             menuOptionsParam.labelInfo = theme->GetSelectAllLabelInfo();
105             menuOptionsParam.symbolId = theme->GetCopyAllSymbolId();
106             break;
107         case MenuItemType::CAMERA_INPUT:
108             menuOptionsParam.symbolId = theme->GetCameraInputSymbolId();
109             break;
110         case MenuItemType::AI_WRITER:
111             menuOptionsParam.symbolId = theme->GetAIWriteSymbolId();
112             break;
113         case MenuItemType::TRANSLATE:
114             menuOptionsParam.symbolId = theme->GetTranslateSymbolId();
115             break;
116         case MenuItemType::SHARE:
117             menuOptionsParam.symbolId = theme->GetShareSymbolId();
118             break;
119         case MenuItemType::SEARCH:
120             menuOptionsParam.symbolId = theme->GetSearchSymbolId();
121             break;
122         case MenuItemType::ASK_CELIA:
123             menuOptionsParam.symbolId = theme->GetAskCeliaSymbolId();
124             break;
125         default:
126             menuOptionsParam.labelInfo = menuOptionsParam.labelInfo.value_or("");
127             menuOptionsParam.symbolId = menuOptionsParam.symbolId.value_or(0);
128             break;
129     }
130 }
131 }
132 constexpr int NUM_0 = 0;
133 constexpr int NUM_1 = 1;
134 constexpr int NUM_2 = 2;
135 constexpr int NUM_3 = 3;
136 constexpr int NUM_4 = 4;
137 constexpr int PARAM_ARR_LENGTH_1 = 1;
138 constexpr int PARAM_ARR_LENGTH_2 = 2;
139 const std::regex RESOURCE_APP_STRING_PLACEHOLDER(R"(\%((\d+)(\$)){0,1}([dsf]))", std::regex::icase);
140 const std::regex FLOAT_PATTERN(R"(-?(0|[1-9]\d*)(\.\d+))", std::regex::icase);
141 const std::string RESOURCE_TOKEN_PATTERN = "(app|sys|\\[.+?\\])\\.(\\S+?)\\.(\\S+)";
142 const std::string RESOURCE_NAME_PATTERN = "\\[(.+?)\\]";
143 constexpr uint32_t COLOR_ALPHA_OFFSET = 24;
144 constexpr uint32_t COLOR_ALPHA_VALUE = 0xFF000000;
145 constexpr uint32_t RES_TYPE_INDEX = 2;
146 constexpr int32_t UNKNOWN_RESOURCE_ID = -1;
147 constexpr int32_t UNKNOWN_RESOURCE_TYPE = -1;
148 const std::string DEFAULT_STR = "-1";
149 constexpr  int32_t REPLACEHOLDER_INDEX = 2;
150 const Color DEFAULT_TEXT_SHADOW_COLOR = Color::BLACK;
151 constexpr bool DEFAULT_TEXT_SHADOW_FILL = false;
152 constexpr ShadowType DEFAULT_TEXT_SHADOW_TYPE = ShadowType::COLOR;
153 constexpr char JS_TEXT_MENU_ID_CLASS_NAME[] = "TextMenuItemId";
154 const std::string CUSTOM_SYMBOL_SUFFIX = "_CustomSymbol";
155 
ColorAlphaAdapt(uint32_t origin)156 uint32_t ArkTSUtils::ColorAlphaAdapt(uint32_t origin)
157 {
158     uint32_t result = origin;
159     if ((origin >> COLOR_ALPHA_OFFSET) == 0) {
160         result = origin | COLOR_ALPHA_VALUE;
161     }
162     return result;
163 }
164 
MakeNativeNodeInfo(ArkUINodeHandle node)165 NodeInfo ArkTSUtils::MakeNativeNodeInfo(ArkUINodeHandle node)
166 {
167     auto* frameNode = reinterpret_cast<FrameNode*>(node);
168     if (!frameNode) {
169         return { "", ColorMode::COLOR_MODE_UNDEFINED };
170     }
171     return { frameNode ? frameNode->GetTag() : "",
172         frameNode ? frameNode->GetLocalColorMode() : ColorMode::COLOR_MODE_UNDEFINED };
173 }
174 
CheckDarkResource(const RefPtr<ResourceObject> & resObj)175 bool ArkTSUtils::CheckDarkResource(const RefPtr<ResourceObject>& resObj)
176 {
177     if (!SystemProperties::GetResourceDecoupling() || !resObj) {
178         return false;
179     }
180     auto resourceAdapter = ResourceManager::GetInstance().GetOrCreateResourceAdapter(resObj);
181     CHECK_NULL_RETURN(resourceAdapter, false);
182 
183     int32_t resId = resObj->GetId();
184     bool hasDarkRes = false;
185     auto params = resObj->GetParams();
186     if (resId == -1 && !params.empty() && params.back().value.has_value()) {
187         hasDarkRes = resourceAdapter->ExistDarkResByName(params.back().value.value(),
188             std::to_string(resObj->GetType()));
189     } else {
190         hasDarkRes = resourceAdapter->ExistDarkResById(std::to_string(resId));
191     }
192     return hasDarkRes;
193 }
194 
CompleteResourceObjectFromColor(RefPtr<ResourceObject> & resObj,Color & color,bool state,const NodeInfo & nodeInfo)195 void ArkTSUtils::CompleteResourceObjectFromColor(RefPtr<ResourceObject>& resObj,
196     Color& color, bool state, const NodeInfo& nodeInfo)
197 {
198     if (!state || !SystemProperties::ConfigChangePerform()) {
199         return;
200     }
201 
202     auto instanceId = Container::CurrentIdSafely();
203     auto invertFunc = ColorInverter::GetInstance().GetInvertFunc(instanceId, nodeInfo.nodeTag);
204     CHECK_NULL_VOID(invertFunc);
205 
206     if (nodeInfo.localColorMode == ColorMode::LIGHT) {
207         resObj = nullptr;
208         return;
209     }
210     bool hasDarkRes = CheckDarkResource(resObj);
211     if (nodeInfo.localColorMode == ColorMode::DARK) {
212         if (!hasDarkRes) {
213             color = Color(invertFunc(color.GetValue()));
214         }
215         resObj = nullptr;
216         return;
217     }
218     auto colorMode = Container::CurrentColorMode();
219     Color curColor = color;
220     if ((colorMode == ColorMode::DARK) && !hasDarkRes) {
221         color = Color(invertFunc(color.GetValue()));
222     }
223     if (!resObj) {
224         resObj = AceType::MakeRefPtr<ResourceObject>();
225         resObj->SetIsResource(false);
226         resObj->SetInstanceId(instanceId);
227     }
228     resObj->SetNodeTag(nodeInfo.nodeTag);
229     resObj->SetColorMode(colorMode);
230     resObj->SetHasDarkRes(hasDarkRes);
231     resObj->SetColor((colorMode == ColorMode::DARK) ? curColor : color);
232 }
233 
ParseJsColor(const EcmaVM * vm,const Local<JSValueRef> & value,Color & result)234 bool ArkTSUtils::ParseJsColor(const EcmaVM* vm, const Local<JSValueRef>& value, Color& result)
235 {
236     RefPtr<ResourceObject> resourceObject;
237     NodeInfo nodeInfo = { "", ColorMode::COLOR_MODE_UNDEFINED };
238     return ParseJsColor(vm, value, result, resourceObject, nodeInfo);
239 }
240 
ParseJsColor(const EcmaVM * vm,const Local<JSValueRef> & value,Color & result,RefPtr<ResourceObject> & resourceObject,const NodeInfo & nodeInfo)241 bool ArkTSUtils::ParseJsColor(const EcmaVM* vm, const Local<JSValueRef>& value, Color& result,
242     RefPtr<ResourceObject>& resourceObject, const NodeInfo& nodeInfo)
243 {
244     bool state = false;
245     if (value->IsNumber()) {
246         result = Color(value->Uint32Value(vm));
247         CompleteResourceObjectFromColor(resourceObject, result, true, nodeInfo);
248         return true;
249     }
250     if (value->IsString(vm)) {
251         state = Color::ParseColorString(value->ToString(vm)->ToString(vm), result);
252         CompleteResourceObjectFromColor(resourceObject, result, state, nodeInfo);
253         return state;
254     }
255     if (value->IsObject(vm)) {
256         auto obj = value->ToObject(vm);
257         auto resId = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
258         if (!resId->IsNumber()) {
259             return false;
260         }
261         state = ParseJsColorFromResource(vm, value, result, resourceObject);
262         CompleteResourceObjectFromColor(resourceObject, result, state, nodeInfo);
263         return state;
264     }
265     return state;
266 }
267 
ParseJsSymbolColorAlpha(const EcmaVM * vm,const Local<JSValueRef> & value,Color & result)268 bool ArkTSUtils::ParseJsSymbolColorAlpha(const EcmaVM* vm, const Local<JSValueRef>& value, Color& result)
269 {
270     RefPtr<ResourceObject> resourceObject;
271     NodeInfo nodeInfo = { "", ColorMode::COLOR_MODE_UNDEFINED };
272     return ParseJsSymbolColorAlpha(vm, value, result, resourceObject, nodeInfo);
273 }
274 
ParseJsSymbolColorAlpha(const EcmaVM * vm,const Local<JSValueRef> & value,Color & result,RefPtr<ResourceObject> & resourceObject,const NodeInfo & nodeInfo)275 bool ArkTSUtils::ParseJsSymbolColorAlpha(const EcmaVM* vm, const Local<JSValueRef>& value, Color& result,
276     RefPtr<ResourceObject>& resourceObject, const NodeInfo& nodeInfo)
277 {
278     if (!value->IsNumber() && !value->IsString(vm) && !value->IsObject(vm)) {
279         return false;
280     }
281     if (value->IsNumber()) {
282         result = Color(ColorAlphaAdapt(value->Uint32Value(vm)));
283     } else if (value->IsString(vm)) {
284         Color::ParseColorString(value->ToString(vm)->ToString(vm), result);
285     } else if (value->IsObject(vm)) {
286         ParseJsColorFromResource(vm, value, result, resourceObject);
287     }
288     CompleteResourceObjectFromColor(resourceObject, result, true, nodeInfo);
289     return true;
290 }
291 
ParseJsColorAlpha(const EcmaVM * vm,const Local<JSValueRef> & value,Color & color,std::vector<RefPtr<ResourceObject>> & resObjs,const NodeInfo & nodeInfo)292 bool ArkTSUtils::ParseJsColorAlpha(const EcmaVM* vm, const Local<JSValueRef>& value, Color& color,
293     std::vector<RefPtr<ResourceObject>>& resObjs, const NodeInfo& nodeInfo)
294 {
295     RefPtr<ResourceObject> resObj;
296     bool result = ArkTSUtils::ParseJsColorAlpha(vm, value, color, resObj, nodeInfo);
297     if (SystemProperties::ConfigChangePerform()) {
298         if (resObj) {
299             resObjs.push_back(resObj);
300         } else {
301             resObjs.push_back(nullptr);
302         }
303     }
304     return result;
305 }
306 
ParseJsColorAlpha(const EcmaVM * vm,const Local<JSValueRef> & value,Color & result)307 bool ArkTSUtils::ParseJsColorAlpha(const EcmaVM* vm, const Local<JSValueRef>& value, Color& result)
308 {
309     RefPtr<ResourceObject> resourceObject;
310     NodeInfo nodeInfo = { "", ColorMode::COLOR_MODE_UNDEFINED };
311     return ParseJsColorAlpha(vm, value, result, resourceObject, nodeInfo);
312 }
313 
ParseJsColorAlpha(const EcmaVM * vm,const Local<JSValueRef> & value,Color & result,RefPtr<ResourceObject> & resourceObject,const NodeInfo & nodeInfo)314 bool ArkTSUtils::ParseJsColorAlpha(const EcmaVM* vm, const Local<JSValueRef>& value, Color& result,
315     RefPtr<ResourceObject>& resourceObject, const NodeInfo& nodeInfo)
316 {
317     bool state = false;
318     if (value->IsNumber()) {
319         result = Color(ColorAlphaAdapt(value->Uint32Value(vm)));
320         CompleteResourceObjectFromColor(resourceObject, result, true, nodeInfo);
321         return true;
322     }
323     if (value->IsString(vm)) {
324         state = Color::ParseColorString(value->ToString(vm)->ToString(vm), result);
325         CompleteResourceObjectFromColor(resourceObject, result, state, nodeInfo);
326         return state;
327     }
328     if (value->IsObject(vm)) {
329         if (ParseColorMetricsToColor(vm, value, result, resourceObject)) {
330             CompleteResourceObjectFromColor(resourceObject, result, true, nodeInfo);
331             return true;
332         }
333         state = ParseJsColorFromResource(vm, value, result, resourceObject);
334         CompleteResourceObjectFromColor(resourceObject, result, state, nodeInfo);
335         return state;
336     }
337     return false;
338 }
339 
ParseJsColorContent(const EcmaVM * vm,const Local<JSValueRef> & value)340 bool ArkTSUtils::ParseJsColorContent(const EcmaVM* vm, const Local<JSValueRef>& value)
341 {
342     if (!value->IsObject(vm)) {
343         return false;
344     }
345     auto obj = value->ToObject(vm);
346     auto colorContentValue = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "colorContent_"));
347     return !colorContentValue.IsEmpty() && colorContentValue->IsString(vm) &&
348            colorContentValue->ToString(vm)->ToString(vm) == "ORIGIN";
349 }
350 
ParseJsColorAlpha(const EcmaVM * vm,const Local<JSValueRef> & value,Color & result,const Color & defaultColor)351 bool ArkTSUtils::ParseJsColorAlpha(
352     const EcmaVM* vm, const Local<JSValueRef>& value, Color& result, const Color& defaultColor)
353 {
354     RefPtr<ResourceObject> resourceObject;
355     NodeInfo nodeInfo = { "", ColorMode::COLOR_MODE_UNDEFINED };
356     return ParseJsColorAlpha(vm, value, result, defaultColor, resourceObject, nodeInfo);
357 }
358 
ParseJsColorAlpha(const EcmaVM * vm,const Local<JSValueRef> & value,Color & result,const Color & defaultColor,RefPtr<ResourceObject> & resourceObject,const NodeInfo & nodeInfo)359 bool ArkTSUtils::ParseJsColorAlpha(const EcmaVM* vm, const Local<JSValueRef>& value,
360     Color& result, const Color& defaultColor, RefPtr<ResourceObject>& resourceObject,
361     const NodeInfo& nodeInfo)
362 {
363     bool state = false;
364     if (!value->IsNumber() && !value->IsString(vm) && !value->IsObject(vm)) {
365         return state;
366     }
367     if (value->IsNumber()) {
368         result = Color(ColorAlphaAdapt(value->Uint32Value(vm)));
369         CompleteResourceObjectFromColor(resourceObject, result, true, nodeInfo);
370         return true;
371     }
372     if (value->IsString(vm)) {
373         state = Color::ParseColorString(value->ToString(vm)->ToString(vm), result, defaultColor);
374         CompleteResourceObjectFromColor(resourceObject, result, state, nodeInfo);
375         return state;
376     }
377     state = ParseJsColorFromResource(vm, value, result, resourceObject);
378     CompleteResourceObjectFromColor(resourceObject, result, state, nodeInfo);
379     return state;
380 }
381 
ToString(const EcmaVM * vm,Local<JSValueRef> & jsVal)382 std::string ToString(const EcmaVM* vm,  Local<JSValueRef>& jsVal)
383 {
384     panda::LocalScope scope(vm);
385     if (jsVal->IsObject(vm)) {
386         return panda::JSON::Stringify(vm, jsVal)->ToString(vm)->ToString(vm);
387     }
388     return jsVal->ToString(vm)->ToString(vm);
389 }
390 
GetResourceObject(const EcmaVM * vm,const Local<JSValueRef> & jsObj)391 RefPtr<ResourceObject> GetResourceObject(const EcmaVM* vm, const Local<JSValueRef>& jsObj)
392 {
393     auto obj = jsObj->ToObject(vm);
394     auto id = obj->Get(vm, panda::ExternalStringCache::GetCachedString(vm,
395         static_cast<int32_t>(Framework::ArkUIIndex::ID)))->Int32Value(vm);
396     auto type = obj->Get(vm, panda::ExternalStringCache::GetCachedString(vm,
397         static_cast<int32_t>(Framework::ArkUIIndex::TYPE)))->Int32Value(vm);
398     auto args = obj->Get(vm, panda::ExternalStringCache::GetCachedString(vm,
399         static_cast<int32_t>(Framework::ArkUIIndex::PARAMS)));
400 
401     std::string bundleName;
402     std::string moduleName;
403     auto bundle = obj->Get(vm, panda::ExternalStringCache::GetCachedString(vm,
404         static_cast<int32_t>(Framework::ArkUIIndex::BUNDLE_NAME)));
405     auto module = obj->Get(vm, panda::ExternalStringCache::GetCachedString(vm,
406         static_cast<int32_t>(Framework::ArkUIIndex::MODULE_NAME)));
407     if (bundle->IsString(vm) && module->IsString(vm)) {
408         bundleName = bundle->ToString(vm)->ToString(vm);
409         moduleName = module->ToString(vm)->ToString(vm);
410     }
411 
412     Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
413     std::vector<ResourceObjectParams> resObjParamsList;
414     auto size = static_cast<int32_t>(params->Length(vm));
415     for (int32_t i = 0; i < size; i++) {
416         auto item = panda::ArrayRef::GetValueAt(vm, params, i);
417 
418         std::string valueString = ToString(vm, item).c_str();
419 
420         ResourceObjectParams resObjParams { .value = valueString };
421         if (item->IsString(vm)) {
422             resObjParams.type = ResourceObjectParamType::STRING;
423         } else if (item->IsNumber()) {
424             if (std::regex_match(item->ToString(vm)->ToString(vm), FLOAT_PATTERN)) {
425                 resObjParams.type = OHOS::Ace::ResourceObjectParamType::FLOAT;
426             } else {
427                 resObjParams.type = OHOS::Ace::ResourceObjectParamType::INT;
428             }
429         }
430         resObjParamsList.emplace_back(resObjParams);
431     }
432     auto resourceObject = AceType::MakeRefPtr<ResourceObject>(
433         id, type, resObjParamsList, bundleName, moduleName, Container::CurrentIdSafely());
434     return resourceObject;
435 }
436 
GetThemeConstants(const EcmaVM * vm,const Local<JSValueRef> & jsObj)437 RefPtr<OHOS::Ace::ThemeConstants> GetThemeConstants(const EcmaVM* vm, const Local<JSValueRef>& jsObj)
438 {
439     std::string bundleName;
440     std::string moduleName;
441     if (!jsObj->IsUndefined()) {
442         auto obj = jsObj->ToObject(vm);
443         auto bundle = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "bundleName"));
444         auto module = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "moduleName"));
445         if (bundle->IsString(vm) && module->IsString(vm)) {
446             bundleName = bundle->ToString(vm)->ToString(vm);
447             moduleName = module->ToString(vm)->ToString(vm);
448         }
449     }
450 
451     auto cardId = CardScope::CurrentId();
452     if (cardId != OHOS::Ace::INVALID_CARD_ID) {
453         auto container = Container::Current();
454         CHECK_NULL_RETURN(container, nullptr);
455         auto weak = container->GetCardPipeline(cardId);
456         auto cardPipelineContext = weak.Upgrade();
457         CHECK_NULL_RETURN(cardPipelineContext, nullptr);
458         auto cardThemeManager = cardPipelineContext->GetThemeManager();
459         CHECK_NULL_RETURN(cardThemeManager, nullptr);
460         return cardThemeManager->GetThemeConstants(bundleName, moduleName);
461     }
462 
463     auto container = Container::Current();
464     CHECK_NULL_RETURN(container, nullptr);
465     auto pipelineContext = container->GetPipelineContext();
466     CHECK_NULL_RETURN(pipelineContext, nullptr);
467     auto themeManager = pipelineContext->GetThemeManager();
468     CHECK_NULL_RETURN(themeManager, nullptr);
469     return themeManager->GetThemeConstants(bundleName, moduleName);
470 }
471 
CreateResourceWrapper(const EcmaVM * vm,const Local<JSValueRef> & jsObj,RefPtr<ResourceObject> & resourceObject)472 RefPtr<ResourceWrapper> CreateResourceWrapper(const EcmaVM* vm, const Local<JSValueRef>& jsObj,
473     RefPtr<ResourceObject>& resourceObject)
474 {
475     RefPtr<ResourceAdapter> resourceAdapter = nullptr;
476     RefPtr<ThemeConstants> themeConstants = nullptr;
477     if (SystemProperties::GetResourceDecoupling()) {
478         resourceAdapter = ResourceManager::GetInstance().GetOrCreateResourceAdapter(resourceObject);
479         if (!resourceAdapter) {
480             return nullptr;
481         }
482     } else {
483         themeConstants = GetThemeConstants(vm, jsObj);
484         if (!themeConstants) {
485             return nullptr;
486         }
487     }
488     auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
489     return resourceWrapper;
490 }
491 
IsGetResourceByName(const EcmaVM * vm,const Local<JSValueRef> & jsObj)492 bool IsGetResourceByName(const EcmaVM* vm, const Local<JSValueRef>& jsObj)
493 {
494     auto obj = jsObj->ToObject(vm);
495     auto args = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "params"));
496     if (!args->IsArray(vm)) {
497         return false;
498     }
499     auto bundleName = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "bundleName"));
500     auto moduleName = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "moduleName"));
501     if (!bundleName->IsString(vm) || !moduleName->IsString(vm)) {
502         return false;
503     }
504     Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
505     if (params->Length(vm) == 0) {
506         return false;
507     }
508     return true;
509 }
510 
ConvertResourceType(const std::string & typeName,ResourceType & resType)511 bool ConvertResourceType(const std::string& typeName, ResourceType& resType)
512 {
513     static const std::unordered_map<std::string, ResourceType> resTypeMap {
514         { "color", ResourceType::COLOR },
515         { "media", ResourceType::MEDIA },
516         { "float", ResourceType::FLOAT },
517         { "string", ResourceType::STRING },
518         { "plural", ResourceType::PLURAL },
519         { "pattern", ResourceType::PATTERN },
520         { "boolean", ResourceType::BOOLEAN },
521         { "integer", ResourceType::INTEGER },
522         { "strarray", ResourceType::STRARRAY },
523         { "intarray", ResourceType::INTARRAY },
524     };
525     auto it = resTypeMap.find(typeName);
526     if (it == resTypeMap.end()) {
527         return false;
528     }
529     resType = it->second;
530     return true;
531 }
532 
ParseDollarResource(std::string & targetModule,ResourceType & resType,std::string & resName,bool isParseType)533 bool ParseDollarResource(std::string& targetModule, ResourceType& resType,
534     std::string& resName, bool isParseType)
535 {
536     std::smatch results;
537     std::regex tokenRegex(RESOURCE_TOKEN_PATTERN);
538     if (!std::regex_match(resName, results, tokenRegex)) {
539         return false;
540     }
541     targetModule = results[1];
542     if (isParseType && !ConvertResourceType(results[RES_TYPE_INDEX], resType)) {
543         return false;
544     }
545     return true;
546 }
547 
CompleteResourceObjectFromParams(const EcmaVM * vm,Local<panda::ObjectRef> & jsObj,std::string & targetModule,ResourceType & resType,std::string & resName)548 void CompleteResourceObjectFromParams(const EcmaVM* vm, Local<panda::ObjectRef>& jsObj,
549     std::string& targetModule, ResourceType& resType, std::string& resName)
550 {
551     auto type = jsObj->Get(vm,
552         panda::ExternalStringCache::GetCachedString(vm, static_cast<int32_t>(Framework::ArkUIIndex::TYPE)));
553     int32_t typeNum = -1;
554     if (type->IsNumber()) {
555         typeNum = type->Int32Value(vm);
556     }
557     auto resId = jsObj->Get(vm,
558         panda::ExternalStringCache::GetCachedString(vm, static_cast<int32_t>(Framework::ArkUIIndex::ID)));
559     int32_t resIdValue = resId->Int32Value(vm);
560     if (resIdValue != UNKNOWN_RESOURCE_ID) {
561         return;
562     }
563     auto args = jsObj->Get(vm,
564         panda::ExternalStringCache::GetCachedString(vm, static_cast<int32_t>(Framework::ArkUIIndex::PARAMS)));
565     Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
566     auto identity = panda::ArrayRef::GetValueAt(vm, params, 0);
567     if (!identity->IsString(vm)) {
568         return;
569     }
570     resName = identity->ToString(vm)->ToString(vm);
571     bool isParseDollarResourceSuccess =
572         ParseDollarResource(targetModule, resType, resName, typeNum == UNKNOWN_RESOURCE_TYPE);
573     if (!isParseDollarResourceSuccess) {
574         return;
575     }
576 
577     auto moduleName = jsObj->Get(vm,
578         panda::ExternalStringCache::GetCachedString(vm,
579             static_cast<int32_t>(Framework::ArkUIIndex::MODULE_NAME)));
580     if (moduleName->IsString(vm) && moduleName->ToString(vm)->ToString(vm).empty()) {
581         std::regex resNameRegex(RESOURCE_NAME_PATTERN);
582         std::smatch resNameResults;
583         if (std::regex_match(targetModule, resNameResults, resNameRegex)) {
584             jsObj->Set(vm,
585                 panda::ExternalStringCache::GetCachedString(vm,
586                     static_cast<int32_t>(Framework::ArkUIIndex::MODULE_NAME)),
587                 panda::StringRef::NewFromUtf8(vm, resNameResults.str(1).c_str()));
588         } else {
589             jsObj->Set(vm,
590                 panda::ExternalStringCache::GetCachedString(vm,
591                     static_cast<int32_t>(Framework::ArkUIIndex::MODULE_NAME)),
592                 panda::StringRef::NewFromUtf8(vm, ""));
593         }
594     }
595     if (typeNum == UNKNOWN_RESOURCE_TYPE) {
596         jsObj->Set(vm, panda::ExternalStringCache::GetCachedString(vm,
597             static_cast<int32_t>(Framework::ArkUIIndex::TYPE)),
598             panda::NumberRef::New(vm, static_cast<int32_t>(resType)));
599     }
600 }
601 
CompleteResourceObjectFromId(const EcmaVM * vm,const Local<JSValueRef> & type,Local<panda::ObjectRef> & jsObj,ResourceType & resType,const std::string & resName)602 void CompleteResourceObjectFromId(const EcmaVM* vm, const Local<JSValueRef>& type, Local<panda::ObjectRef>& jsObj,
603     ResourceType& resType, const std::string& resName)
604 {
605     auto args = jsObj->Get(vm,
606         panda::ExternalStringCache::GetCachedString(vm, static_cast<int32_t>(Framework::ArkUIIndex::PARAMS)));
607     if (!args->IsArray(vm)) {
608         return;
609     }
610     Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
611     auto paramCount = params->Length(vm);
612     auto name = panda::StringRef::NewFromUtf8(vm, resName.c_str());
613     if (resType == ResourceType::PLURAL || resType == ResourceType::STRING) {
614         std::vector<Local<JSValueRef>> tmpParams;
615         for (uint32_t i = 0; i < paramCount; i++) {
616             auto param = panda::ArrayRef::GetValueAt(vm, params, i);
617             tmpParams.insert(tmpParams.end(), param);
618         }
619         panda::ArrayRef::SetValueAt(vm, params, 0, name);
620         uint32_t paramIndex = 1;
621         auto firstParam = jsObj->Get(vm,
622             panda::ExternalStringCache::GetCachedString(vm, static_cast<int32_t>(Framework::ArkUIIndex::TYPE)));
623         if (!firstParam->IsNull()) {
624             panda::ArrayRef::SetValueAt(vm, params, paramIndex, firstParam);
625             paramIndex++;
626         }
627         for (auto tmpParam : tmpParams) {
628             panda::ArrayRef::SetValueAt(vm, params, paramIndex, tmpParam);
629             paramIndex++;
630         }
631     } else {
632         panda::ArrayRef::SetValueAt(vm, params, 0, name);
633     }
634     jsObj->Set(vm, panda::ExternalStringCache::GetCachedString(vm, static_cast<int32_t>(Framework::ArkUIIndex::ID)),
635                 panda::NumberRef::New(vm, UNKNOWN_RESOURCE_ID));
636     jsObj->Set(vm, panda::ExternalStringCache::GetCachedString(vm, static_cast<int32_t>(Framework::ArkUIIndex::TYPE)),
637             panda::ExternalStringCache::GetCachedString(vm, static_cast<int32_t>(resType)));
638     if (!jsObj->Has(vm,
639         panda::ExternalStringCache::GetCachedString(vm, static_cast<int32_t>(Framework::ArkUIIndex::BUNDLE_NAME)))) {
640         jsObj->Set(vm,
641             panda::ExternalStringCache::GetCachedString(vm, static_cast<int32_t>(Framework::ArkUIIndex::BUNDLE_NAME)),
642             panda::StringRef::NewFromUtf8(vm, ""));
643     }
644     if (!jsObj->Has(vm,
645         panda::ExternalStringCache::GetCachedString(vm, static_cast<int32_t>(Framework::ArkUIIndex::MODULE_NAME)))) {
646         jsObj->Set(vm,
647             panda::ExternalStringCache::GetCachedString(vm, static_cast<int32_t>(Framework::ArkUIIndex::MODULE_NAME)),
648             panda::StringRef::NewFromUtf8(vm, ""));
649     }
650 }
651 
CompleteResourceObject(const EcmaVM * vm,Local<panda::ObjectRef> & jsObj)652 void ArkTSUtils::CompleteResourceObject(const EcmaVM* vm, Local<panda::ObjectRef>& jsObj)
653 {
654     // dynamic $r raw input format is
655     // {"id":"app.xxx.xxx", "params":[], "bundleName":"xxx", "moduleName":"xxx"}
656     auto resId = jsObj->Get(vm,
657         panda::ExternalStringCache::GetCachedString(vm, static_cast<int32_t>(Framework::ArkUIIndex::ID)));
658     ResourceType resType = ResourceType::NONE;
659     std::string targetModule;
660     std::string resName;
661     if (resId->IsString(vm)) {
662         auto type = jsObj->Get(vm,
663             panda::ExternalStringCache::GetCachedString(vm, static_cast<int32_t>(Framework::ArkUIIndex::TYPE)));
664         int32_t typeNum = -1;
665         if (type->IsNumber()) {
666             typeNum = type->Int32Value(vm);
667         }
668         resName = resId->ToString(vm)->ToString(vm);
669         if (!ParseDollarResource(targetModule, resType, resName, typeNum == UNKNOWN_RESOURCE_TYPE)) {
670             return;
671         }
672         CompleteResourceObjectFromId(vm, type, jsObj, resType, resName);
673     } else if (resId->IsNumber()) {
674         int32_t resIdValue = resId->Int32Value(vm);
675         if (resIdValue == -1) {
676             CompleteResourceObjectFromParams(vm, jsObj, targetModule, resType, resName);
677         }
678     }
679 
680     std::string bundleName;
681     std::string moduleName;
682     ArkTSUtils::GetJsMediaBundleInfo(vm, jsObj, bundleName, moduleName);
683     if ((bundleName.empty() && !moduleName.empty()) || bundleName == DEFAULT_HAR_BUNDLE_NAME) {
684         bundleName = GetBundleNameFromContainer();
685         jsObj->Set(vm,
686             panda::ExternalStringCache::GetCachedString(vm, static_cast<int32_t>(Framework::ArkUIIndex::BUNDLE_NAME)),
687             panda::StringRef::NewFromUtf8(vm, bundleName.c_str()));
688     }
689     if (moduleName == DEFAULT_HAR_MODULE_NAME) {
690         moduleName = GetModuleNameFromContainer();
691         jsObj->Set(vm,
692             panda::ExternalStringCache::GetCachedString(vm, static_cast<int32_t>(Framework::ArkUIIndex::MODULE_NAME)),
693             panda::StringRef::NewFromUtf8(vm, moduleName.c_str()));
694     }
695 }
696 
ParseJsColorFromResource(const EcmaVM * vm,const Local<JSValueRef> & jsObj,Color & result)697 bool ArkTSUtils::ParseJsColorFromResource(const EcmaVM* vm, const Local<JSValueRef>& jsObj, Color& result)
698 {
699     RefPtr<ResourceObject> resourceObject;
700     return ParseJsColorFromResource(vm, jsObj, result, resourceObject);
701 }
702 
ParseJsColorFromResource(const EcmaVM * vm,const Local<JSValueRef> & jsObj,Color & result,RefPtr<ResourceObject> & resourceObject)703 bool ArkTSUtils::ParseJsColorFromResource(const EcmaVM* vm, const Local<JSValueRef>& jsObj, Color& result,
704     RefPtr<ResourceObject>& resourceObject)
705 {
706     auto obj = jsObj ->ToObject(vm);
707     auto resId = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
708     if (!resId->IsNumber()) {
709         return false;
710     }
711 
712     CompleteResourceObject(vm, obj);
713     resourceObject = GetResourceObject(vm, jsObj);
714     auto resourceWrapper = CreateResourceWrapper(vm, jsObj, resourceObject);
715     if (!resourceWrapper) {
716         return false;
717     }
718 
719     auto resIdNum = resId->Int32Value(vm);
720     if (resIdNum == -1) {
721         if (!IsGetResourceByName(vm, jsObj)) {
722             return false;
723         }
724         auto args = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "params"));
725         if (!args->IsArray(vm)) {
726             return false;
727         }
728         Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
729         auto param = panda::ArrayRef::GetValueAt(vm, params, 0);
730         result = resourceWrapper->GetColorByName(param->ToString(vm)->ToString(vm));
731         return true;
732     }
733     auto type = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "type"));
734     if (type->IsNull() || !type->IsNumber()) {
735         return false;
736     }
737     if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::STRING)) {
738         auto value = resourceWrapper->GetString(resId->Int32Value(vm));
739         return Color::ParseColorString(value, result);
740     }
741     if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::INTEGER)) {
742         auto value = resourceWrapper->GetInt(resId->Int32Value(vm));
743         result = Color(ColorAlphaAdapt(value));
744         return true;
745     }
746     if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::COLOR)) {
747         result = resourceWrapper->GetColor(resId->ToNumber(vm)->Value());
748         result.SetResourceId(resId->Int32Value(vm));
749         return true;
750     }
751     return false;
752 }
753 
ParseColorMetricsToColor(const EcmaVM * vm,const Local<JSValueRef> & jsValue,Color & result)754 bool ArkTSUtils::ParseColorMetricsToColor(const EcmaVM* vm, const Local<JSValueRef>& jsValue, Color& result)
755 {
756     RefPtr<ResourceObject> resourceObject;
757     return ParseColorMetricsToColor(vm, jsValue, result, resourceObject);
758 }
759 
ParseColorMetricsToColor(const EcmaVM * vm,const Local<JSValueRef> & jsValue,Color & result,RefPtr<ResourceObject> & resourceObject)760 bool ArkTSUtils::ParseColorMetricsToColor(
761     const EcmaVM* vm, const Local<JSValueRef>& jsValue, Color& result, RefPtr<ResourceObject>& resourceObject)
762 {
763     if (!jsValue->IsObject(vm)) {
764         return false;
765     }
766     auto obj = jsValue->ToObject(vm);
767     auto toNumericProp = obj->Get(vm, "toNumeric");
768     auto colorSpaceProp = obj->Get(vm, "getColorSpace");
769     auto jsRes = obj->Get(vm, "res_");
770     if (SystemProperties::ConfigChangePerform() && !jsRes->IsUndefined() &&
771         !jsRes->IsNull() && jsRes->IsObject(vm)) {
772         auto jsObjRes = jsRes->ToObject(vm);
773         CompleteResourceObject(vm, jsObjRes);
774         resourceObject = GetResourceObject(vm, jsObjRes);
775     }
776     if (toNumericProp->IsFunction(vm) && colorSpaceProp->IsFunction(vm)) {
777         panda::Local<panda::FunctionRef> func = toNumericProp;
778         auto colorVal = func->Call(vm, obj, nullptr, 0);
779         result.SetValue(colorVal->Uint32Value(vm));
780 
781         func = colorSpaceProp;
782         auto colorSpaceVal = func->Call(vm, obj, nullptr, 0);
783         if (colorSpaceVal->IsNumber() &&
784             colorSpaceVal->Uint32Value(vm) == static_cast<uint32_t>(ColorSpace::DISPLAY_P3)) {
785             result.SetColorSpace(ColorSpace::DISPLAY_P3);
786         } else {
787             result.SetColorSpace(ColorSpace::SRGB);
788         }
789 
790         return true;
791     }
792     return false;
793 }
794 
ParseJsDimensionFromResource(const EcmaVM * vm,const Local<JSValueRef> & jsObj,DimensionUnit dimensionUnit,CalcDimension & result,RefPtr<ResourceObject> & resourceObject)795 bool ArkTSUtils::ParseJsDimensionFromResource(const EcmaVM* vm, const Local<JSValueRef>& jsObj,
796     DimensionUnit dimensionUnit, CalcDimension& result, RefPtr<ResourceObject>& resourceObject)
797 {
798     auto obj = jsObj->ToObject(vm);
799     auto resId = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
800     if (!resId->IsNumber()) {
801         return false;
802     }
803 
804     CompleteResourceObject(vm, obj);
805     resourceObject = GetResourceObject(vm, jsObj);
806 
807     auto resourceWrapper = CreateResourceWrapper(vm, jsObj, resourceObject);
808     if (!resourceWrapper) {
809         return false;
810     }
811     auto resIdNum = resId->Int32Value(vm);
812     if (resIdNum == -1) {
813         return ParseJsDimensionFromResourceByName(vm, obj, dimensionUnit, resourceObject, resourceWrapper, result);
814     }
815     auto type = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "type"));
816     if (type->IsNull() || !type->IsNumber()) {
817         return false;
818     }
819     if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::STRING)) {
820         auto value = resourceWrapper->GetString(resId->Int32Value(vm));
821         result = StringUtils::StringToCalcDimension(value, false, dimensionUnit);
822         return true;
823     }
824     if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::INTEGER)) {
825         auto value = std::to_string(resourceWrapper->GetInt(resId->Int32Value(vm)));
826         result = StringUtils::StringToDimensionWithUnit(value, dimensionUnit);
827         return true;
828     }
829     result = resourceWrapper->GetDimension(resId->Int32Value(vm));
830     return true;
831 }
832 
ParseJsDimensionFromResourceByName(const EcmaVM * vm,const Local<panda::ObjectRef> & jsObj,DimensionUnit dimensionUnit,const RefPtr<ResourceObject> & resourceObject,const RefPtr<ResourceWrapper> & resourceWrapper,CalcDimension & result)833 bool ArkTSUtils::ParseJsDimensionFromResourceByName(const EcmaVM* vm, const Local<panda::ObjectRef>& jsObj,
834     DimensionUnit dimensionUnit, const RefPtr<ResourceObject>& resourceObject,
835     const RefPtr<ResourceWrapper>& resourceWrapper, CalcDimension& result)
836 {
837     if (!IsGetResourceByName(vm, jsObj)) {
838         return false;
839     }
840     auto args = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "params"));
841     if (!args->IsArray(vm)) {
842         return false;
843     }
844     Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
845     auto param = panda::ArrayRef::GetValueAt(vm, params, 0);
846     auto resName = param->ToString(vm)->ToString(vm);
847 
848     if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::STRING)) {
849         auto value = resourceWrapper->GetStringByName(resName);
850         result = StringUtils::StringToCalcDimension(value, false, dimensionUnit);
851         return true;
852     }
853     if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::INTEGER)) {
854         auto value = std::to_string(resourceWrapper->GetIntByName(resName));
855         result = StringUtils::StringToDimensionWithUnit(value, dimensionUnit);
856         return true;
857     }
858     result = resourceWrapper->GetDimensionByName(resName);
859     return true;
860 }
861 
ParseJsDimensionFromResourceNG(const EcmaVM * vm,const Local<JSValueRef> & jsObj,DimensionUnit dimensionUnit,CalcDimension & result)862 bool ArkTSUtils::ParseJsDimensionFromResourceNG(const EcmaVM* vm, const Local<JSValueRef>& jsObj,
863     DimensionUnit dimensionUnit, CalcDimension& result)
864 {
865     RefPtr<ResourceObject> resourceObject;
866     return ParseJsDimensionFromResourceNG(vm, jsObj, dimensionUnit, result, resourceObject);
867 }
868 
ParseJsDimensionFromResourceNG(const EcmaVM * vm,const Local<JSValueRef> & jsObj,DimensionUnit dimensionUnit,CalcDimension & result,RefPtr<ResourceObject> & resourceObject)869 bool ArkTSUtils::ParseJsDimensionFromResourceNG(const EcmaVM* vm, const Local<JSValueRef>& jsObj,
870     DimensionUnit dimensionUnit, CalcDimension& result, RefPtr<ResourceObject>& resourceObject)
871 {
872     auto obj = jsObj->ToObject(vm);
873     auto resId = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
874     if (!resId->IsNumber()) {
875         return false;
876     }
877 
878     CompleteResourceObject(vm, obj);
879     resourceObject = GetResourceObject(vm, jsObj);
880 
881     auto resourceWrapper = CreateResourceWrapper(vm, jsObj, resourceObject);
882     if (!resourceWrapper) {
883         return false;
884     }
885     auto resIdNum = resId->Int32Value(vm);
886     if (resIdNum == -1) {
887         return ParseJsDimensionNGFromResourceByName(vm, obj, dimensionUnit, resourceObject, resourceWrapper, result);
888     }
889     auto type = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "type"));
890     if (type->IsNull() || !type->IsNumber()) {
891         return false;
892     }
893     if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::STRING)) {
894         auto value = resourceWrapper->GetString(resId->Int32Value(vm));
895         return StringUtils::StringToCalcDimensionNG(value, result, false, dimensionUnit);
896     }
897     if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::INTEGER)) {
898         auto value = std::to_string(resourceWrapper->GetInt(resId->Int32Value(vm)));
899         StringUtils::StringToDimensionWithUnitNG(value, result, dimensionUnit);
900         return true;
901     }
902     if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::FLOAT)) {
903         result = resourceWrapper->GetDimension(resId->Int32Value(vm));
904         return true;
905     }
906 
907     return false;
908 }
909 
ParseJsDimensionNGFromResourceByName(const EcmaVM * vm,const Local<panda::ObjectRef> & jsObj,DimensionUnit dimensionUnit,const RefPtr<ResourceObject> & resourceObject,const RefPtr<ResourceWrapper> & resourceWrapper,CalcDimension & result)910 bool ArkTSUtils::ParseJsDimensionNGFromResourceByName(const EcmaVM* vm, const Local<panda::ObjectRef>& jsObj,
911     DimensionUnit dimensionUnit, const RefPtr<ResourceObject>& resourceObject,
912     const RefPtr<ResourceWrapper>& resourceWrapper, CalcDimension& result)
913 {
914     if (!IsGetResourceByName(vm, jsObj)) {
915         return false;
916     }
917     auto args = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "params"));
918     if (!args->IsArray(vm)) {
919         return false;
920     }
921     Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
922     auto param = panda::ArrayRef::GetValueAt(vm, params, 0);
923     auto resName = param->ToString(vm)->ToString(vm);
924 
925     if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::STRING)) {
926         auto value = resourceWrapper->GetStringByName(resName);
927         return StringUtils::StringToCalcDimensionNG(value, result, false, dimensionUnit);
928     }
929     if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::INTEGER)) {
930         auto value = std::to_string(resourceWrapper->GetIntByName(resName));
931         StringUtils::StringToDimensionWithUnitNG(value, result, dimensionUnit);
932         return true;
933     }
934     result = resourceWrapper->GetDimensionByName(resName);
935     return true;
936 }
937 
ParseStringArray(const EcmaVM * vm,const Local<JSValueRef> & arg,std::string * array,int32_t defaultLength)938 bool ArkTSUtils::ParseStringArray(const EcmaVM* vm, const Local<JSValueRef>& arg,
939     std::string* array, int32_t defaultLength)
940 {
941     CHECK_NULL_RETURN(vm, false);
942     CHECK_NULL_RETURN(array, false);
943     if (defaultLength <= 0) {
944         return false;
945     }
946     auto handle = panda::CopyableGlobal<panda::ArrayRef>(vm, arg);
947     if (handle.IsEmpty() || handle->IsUndefined() || handle->IsNull()) {
948         return false;
949     }
950     int32_t length = static_cast<int32_t>(handle->Length(vm));
951     if (length != defaultLength) {
952         return false;
953     }
954     for (int32_t i = 0; i < length; i++) {
955         auto value = handle->GetValueAt(vm, arg, i);
956         if (!ParseJsMedia(vm, value, *(array + i))) {
957             *(array + i) = "";
958         }
959     }
960     return true;
961 }
962 
ParseJsDimensionVp(const EcmaVM * vm,const Local<JSValueRef> & value,CalcDimension & result,bool enableCheckInvalidvalue)963 bool ArkTSUtils::ParseJsDimensionVp(
964     const EcmaVM* vm, const Local<JSValueRef>& value, CalcDimension& result, bool enableCheckInvalidvalue)
965 {
966     return ArkTSUtils::ParseJsDimension(vm, value, result, DimensionUnit::VP, true, enableCheckInvalidvalue);
967 }
968 
ParseJsDimensionVp(const EcmaVM * vm,const Local<JSValueRef> & value,CalcDimension & result,RefPtr<ResourceObject> & resourceObject,bool enableCheckInvalidvalue)969 bool ArkTSUtils::ParseJsDimensionVp(const EcmaVM* vm, const Local<JSValueRef>& value,
970     CalcDimension& result, RefPtr<ResourceObject>& resourceObject, bool enableCheckInvalidvalue)
971 {
972     return ArkTSUtils::ParseJsDimension(vm, value, result, DimensionUnit::VP, resourceObject, true,
973         enableCheckInvalidvalue);
974 }
975 
ParseJsInteger(const EcmaVM * vm,const Local<JSValueRef> & value,int32_t & result)976 bool ArkTSUtils::ParseJsInteger(const EcmaVM *vm, const Local<JSValueRef> &value, int32_t &result)
977 {
978     if (value->IsNumber()) {
979         result = value->Int32Value(vm);
980         return true;
981     }
982     return false;
983 }
984 
ParseJsInteger(const EcmaVM * vm,const Local<JSValueRef> & value,uint32_t & result)985 bool ArkTSUtils::ParseJsInteger(const EcmaVM *vm, const Local<JSValueRef> &value, uint32_t &result)
986 {
987     if (value->IsNumber()) {
988         result = value->Uint32Value(vm);
989         return true;
990     }
991     // resource ignore by design
992     return false;
993 }
994 
ParseJsIntegerWithResource(const EcmaVM * vm,const Local<JSValueRef> & jsValue,int32_t & result)995 bool ArkTSUtils::ParseJsIntegerWithResource(const EcmaVM* vm, const Local<JSValueRef>& jsValue, int32_t& result)
996 {
997     RefPtr<ResourceObject> resourceObject;
998     return ParseJsIntegerWithResource(vm, jsValue, result, resourceObject);
999 }
1000 
ParseJsIntegerWithResource(const EcmaVM * vm,const Local<JSValueRef> & jsValue,int32_t & result,RefPtr<ResourceObject> & resourceObject)1001 bool ArkTSUtils::ParseJsIntegerWithResource(const EcmaVM* vm, const Local<JSValueRef>& jsValue, int32_t& result,
1002     RefPtr<ResourceObject>& resourceObject)
1003 {
1004     if (!jsValue->IsNumber() && !jsValue->IsObject(vm)) {
1005         return false;
1006     }
1007 
1008     if (jsValue->IsNumber()) {
1009         result = jsValue->Int32Value(vm);
1010         return true;
1011     }
1012 
1013     auto jsObj = jsValue->ToObject(vm);
1014     auto type = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "type"));
1015     auto id = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
1016     int32_t resourceType = 0;
1017     if (!type->IsNumber() || !id->IsNumber()) {
1018         return false;
1019     }
1020     resourceType = type->Int32Value(vm);
1021     auto resIdNum = id->Int32Value(vm);
1022 
1023     CompleteResourceObject(vm, jsObj);
1024     resourceObject = GetResourceObject(vm, jsValue);
1025     auto resourceWrapper = CreateResourceWrapper(vm, jsValue, resourceObject);
1026     CHECK_NULL_RETURN(resourceWrapper, false);
1027 
1028     if (resIdNum == -1) {
1029         if (!IsGetResourceByName(vm, jsObj)) {
1030             return false;
1031         }
1032         auto args = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "params"));
1033         Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
1034         auto param = panda::ArrayRef::GetValueAt(vm, params, 0);
1035         if (resourceType == static_cast<int32_t>(ResourceType::INTEGER)) {
1036             result = resourceWrapper->GetIntByName(param->ToString(vm)->ToString(vm));
1037             return true;
1038         }
1039         return false;
1040     }
1041 
1042     if (resourceType == static_cast<int32_t>(ResourceType::INTEGER)) {
1043         result = resourceWrapper->GetInt(resIdNum);
1044         return true;
1045     }
1046 
1047     return false;
1048 }
1049 
GetResourceIdAndType(const EcmaVM * vm,const Local<panda::ObjectRef> & jsObj,int32_t & resId,int32_t & resType)1050 bool GetResourceIdAndType(const EcmaVM* vm, const Local<panda::ObjectRef>& jsObj, int32_t& resId, int32_t& resType)
1051 {
1052     auto id = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
1053     auto type = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "type"));
1054     if (!id->IsNumber() || !type->IsNumber()) {
1055         return false;
1056     }
1057 
1058     resId = id->Int32Value(vm);
1059     resType = type->Int32Value(vm);
1060     return true;
1061 }
1062 
ParseResourceToDouble(const EcmaVM * vm,const Local<JSValueRef> & jsValue,double & result,RefPtr<ResourceObject> & resourceObject)1063 bool ArkTSUtils::ParseResourceToDouble(const EcmaVM* vm, const Local<JSValueRef>& jsValue, double& result,
1064     RefPtr<ResourceObject>& resourceObject)
1065 {
1066     auto jsObj = jsValue->ToObject(vm);
1067     int32_t resId;
1068     int32_t resType;
1069     if (jsObj->IsNull() || !GetResourceIdAndType(vm, jsObj, resId, resType)) {
1070         return false;
1071     }
1072     CompleteResourceObject(vm, jsObj);
1073     resourceObject = GetResourceObject(vm, jsObj);
1074     auto resourceWrapper = CreateResourceWrapper(vm, jsObj, resourceObject);
1075     CHECK_NULL_RETURN(resourceWrapper, false);
1076     if (resId == -1) {
1077         if (!IsGetResourceByName(vm, jsObj)) {
1078             return false;
1079         }
1080         auto args = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "params"));
1081         if (!args->IsArray(vm)) {
1082             return false;
1083         }
1084         Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
1085         auto param = panda::ArrayRef::GetValueAt(vm, params, 0);
1086         if (resType == static_cast<int32_t>(ResourceType::STRING)) {
1087             auto numberString = resourceWrapper->GetStringByName(param->ToString(vm)->ToString(vm));
1088             return StringUtils::StringToDouble(numberString, result);
1089         }
1090         if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
1091             result = resourceWrapper->GetIntByName(param->ToString(vm)->ToString(vm));
1092             return true;
1093         }
1094         if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
1095             result = resourceWrapper->GetDoubleByName(param->ToString(vm)->ToString(vm));
1096             return true;
1097         }
1098         return false;
1099     }
1100     if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::STRING)) {
1101         auto numberString = resourceWrapper->GetString(resId);
1102         return StringUtils::StringToDouble(numberString, result);
1103     }
1104     if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::INTEGER)) {
1105         result = resourceWrapper->GetInt(resId);
1106         return true;
1107     }
1108     if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::FLOAT)) {
1109         result = resourceWrapper->GetDouble(resId);
1110         return true;
1111     }
1112     return false;
1113 }
1114 
ParseJsDouble(const EcmaVM * vm,const Local<JSValueRef> & value,double & result)1115 bool ArkTSUtils::ParseJsDouble(const EcmaVM *vm, const Local<JSValueRef> &value, double &result)
1116 {
1117     RefPtr<ResourceObject> resourceObject;
1118     return ParseJsDouble(vm, value, result, resourceObject);
1119 }
1120 
ParseJsDouble(const EcmaVM * vm,const Local<JSValueRef> & value,double & result,RefPtr<ResourceObject> & resourceObject)1121 bool ArkTSUtils::ParseJsDouble(const EcmaVM *vm, const Local<JSValueRef> &value, double &result,
1122     RefPtr<ResourceObject>& resourceObject)
1123 {
1124     if (value->IsNumber()) {
1125         result = value->ToNumber(vm)->Value();
1126         return true;
1127     }
1128     if (value->IsString(vm)) {
1129         return StringUtils::StringToDouble(value->ToString(vm)->ToString(vm), result);
1130     }
1131     if (value->IsObject(vm)) {
1132         return ParseResourceToDouble(vm, value, result, resourceObject);
1133     }
1134     return false;
1135 }
1136 
ParseAllBorder(const EcmaVM * vm,const Local<JSValueRef> & args,CalcDimension & result)1137 bool ArkTSUtils::ParseAllBorder(const EcmaVM* vm, const Local<JSValueRef>& args, CalcDimension& result)
1138 {
1139     RefPtr<ResourceObject> resourceObject;
1140     return ParseAllBorder(vm, args, result, resourceObject);
1141 }
1142 
ParseAllBorder(const EcmaVM * vm,const Local<JSValueRef> & args,CalcDimension & result,RefPtr<ResourceObject> & resourceObject)1143 bool ArkTSUtils::ParseAllBorder(const EcmaVM* vm, const Local<JSValueRef>& args, CalcDimension& result,
1144     RefPtr<ResourceObject>& resourceObject)
1145 {
1146     if (ParseJsDimensionVp(vm, args, result, resourceObject)) {
1147         if (result.IsNegative()) {
1148             result.Reset();
1149         }
1150         return true;
1151     } else {
1152         return false;
1153     }
1154 }
1155 
ParseAllRadius(const EcmaVM * vm,const Local<JSValueRef> & args,CalcDimension & result)1156 bool ArkTSUtils::ParseAllRadius(const EcmaVM* vm, const Local<JSValueRef>& args, CalcDimension& result)
1157 {
1158     RefPtr<ResourceObject> resourceObject;
1159     return ParseAllRadius(vm, args, result, resourceObject);
1160 }
1161 
ParseAllRadius(const EcmaVM * vm,const Local<JSValueRef> & args,CalcDimension & result,RefPtr<ResourceObject> & resourceObject)1162 bool ArkTSUtils::ParseAllRadius(const EcmaVM* vm, const Local<JSValueRef>& args, CalcDimension& result,
1163     RefPtr<ResourceObject>& resourceObject)
1164 {
1165     if (ParseJsDimensionVp(vm, args, result)) {
1166         if (result.IsNegative()) {
1167             result.Reset();
1168         }
1169         return true;
1170     } else {
1171         return false;
1172     }
1173 }
1174 
ParseJsDimensionNG(const EcmaVM * vm,const Local<JSValueRef> & jsValue,CalcDimension & result,DimensionUnit defaultUnit,bool isSupportPercent)1175 bool ArkTSUtils::ParseJsDimensionNG(const EcmaVM *vm, const Local<JSValueRef> &jsValue, CalcDimension &result,
1176     DimensionUnit defaultUnit, bool isSupportPercent)
1177 {
1178     RefPtr<ResourceObject> resourceObject;
1179     return ParseJsDimensionNG(vm, jsValue, result, defaultUnit, resourceObject, isSupportPercent);
1180 }
1181 
ParseJsDimensionNG(const EcmaVM * vm,const Local<JSValueRef> & jsValue,CalcDimension & result,DimensionUnit defaultUnit,RefPtr<ResourceObject> & resourceObject,bool isSupportPercent)1182 bool ArkTSUtils::ParseJsDimensionNG(const EcmaVM *vm, const Local<JSValueRef> &jsValue, CalcDimension &result,
1183     DimensionUnit defaultUnit, RefPtr<ResourceObject>& resourceObject, bool isSupportPercent)
1184 {
1185     if (!jsValue->IsNumber() && !jsValue->IsString(vm) && !jsValue->IsObject(vm)) {
1186         return false;
1187     }
1188     if (jsValue->IsNumber()) {
1189         result = CalcDimension(jsValue->ToNumber(vm)->Value(), defaultUnit);
1190         return true;
1191     }
1192     if (jsValue->IsString(vm)) {
1193         auto value = jsValue->ToString(vm)->ToString(vm);
1194         if (value.back() == '%' && !isSupportPercent) {
1195             return false;
1196         }
1197         return StringUtils::StringToCalcDimensionNG(jsValue->ToString(vm)->ToString(vm), result, false, defaultUnit);
1198     }
1199     if (jsValue->IsObject(vm)) {
1200         return ParseJsDimensionFromResourceNG(vm, jsValue, defaultUnit, result, resourceObject);
1201     }
1202     return false;
1203 }
1204 
ParseJsDimensionVpNG(const EcmaVM * vm,const Local<JSValueRef> & jsValue,CalcDimension & result,bool isSupportPercent)1205 bool ArkTSUtils::ParseJsDimensionVpNG(const EcmaVM *vm, const Local<JSValueRef> &jsValue, CalcDimension &result,
1206     bool isSupportPercent)
1207 {
1208     return ArkTSUtils::ParseJsDimensionNG(vm, jsValue, result, DimensionUnit::VP, isSupportPercent);
1209 }
1210 
ParseJsDimensionVpNG(const EcmaVM * vm,const Local<JSValueRef> & jsValue,CalcDimension & result,RefPtr<ResourceObject> & resourceObject,bool isSupportPercent)1211 bool ArkTSUtils::ParseJsDimensionVpNG(const EcmaVM *vm, const Local<JSValueRef> &jsValue, CalcDimension &result,
1212     RefPtr<ResourceObject>& resourceObject, bool isSupportPercent)
1213 {
1214     return ArkTSUtils::ParseJsDimensionNG(vm, jsValue, result, DimensionUnit::VP, resourceObject, isSupportPercent);
1215 }
1216 
ParseJsDimension(const EcmaVM * vm,const Local<JSValueRef> & jsValue,CalcDimension & result,DimensionUnit defaultUnit,bool isSupportPercent,bool enableCheckInvalidvalue)1217 bool ArkTSUtils::ParseJsDimension(const EcmaVM *vm, const Local<JSValueRef> &jsValue, CalcDimension &result,
1218     DimensionUnit defaultUnit, bool isSupportPercent, bool enableCheckInvalidvalue)
1219 {
1220     RefPtr<ResourceObject> resourceObject;
1221     return ParseJsDimension(vm, jsValue, result, defaultUnit, resourceObject,
1222         isSupportPercent, enableCheckInvalidvalue);
1223 }
1224 
ParseJsDimension(const EcmaVM * vm,const Local<JSValueRef> & jsValue,CalcDimension & result,DimensionUnit defaultUnit,RefPtr<ResourceObject> & resourceObject,bool isSupportPercent,bool enableCheckInvalidvalue)1225 bool ArkTSUtils::ParseJsDimension(const EcmaVM *vm, const Local<JSValueRef> &jsValue, CalcDimension &result,
1226     DimensionUnit defaultUnit, RefPtr<ResourceObject>& resourceObject,
1227     bool isSupportPercent, bool enableCheckInvalidvalue)
1228 {
1229     if (!jsValue->IsNumber() && !jsValue->IsString(vm) && !jsValue->IsObject(vm)) {
1230         return false;
1231     }
1232 
1233     if (jsValue->IsNumber()) {
1234         result = CalcDimension(jsValue->ToNumber(vm)->Value(), defaultUnit);
1235         return true;
1236     }
1237     if (jsValue->IsString(vm)) {
1238         auto stringValue = jsValue->ToString(vm)->ToString(vm);
1239         if (stringValue.back() == '%' && !isSupportPercent) {
1240             return false;
1241         }
1242         if (enableCheckInvalidvalue && stringValue.find("calc") == std::string::npos) {
1243             errno = 0;
1244             char* pEnd = nullptr;
1245             std::string str = jsValue->ToString(vm)->ToString(vm);
1246             std::strtod(str.c_str(), &pEnd);
1247             if (pEnd == str.c_str() || errno == ERANGE) {
1248                 return false;
1249             }
1250         }
1251         result = StringUtils::StringToCalcDimension(jsValue->ToString(vm)->ToString(vm), false, defaultUnit);
1252         return true;
1253     }
1254     if (jsValue->IsObject(vm)) {
1255         return ParseJsDimensionFromResource(vm, jsValue, defaultUnit, result, resourceObject);
1256     }
1257     return false;
1258 }
1259 
ParseJsDimensionFp(const EcmaVM * vm,const Local<JSValueRef> & jsValue,CalcDimension & result,bool isSupportPercent,bool enableCheckInvalidvalue)1260 bool ArkTSUtils::ParseJsDimensionFp(const EcmaVM* vm, const Local<JSValueRef>& jsValue, CalcDimension& result,
1261     bool isSupportPercent, bool enableCheckInvalidvalue)
1262 {
1263     return ArkTSUtils::ParseJsDimension(
1264         vm, jsValue, result, DimensionUnit::FP, isSupportPercent, enableCheckInvalidvalue);
1265 }
1266 
ParseJsDimensionFp(const EcmaVM * vm,const Local<JSValueRef> & jsValue,CalcDimension & result,RefPtr<ResourceObject> & resourceObject,bool isSupportPercent,bool enableCheckInvalidvalue)1267 bool ArkTSUtils::ParseJsDimensionFp(const EcmaVM* vm, const Local<JSValueRef>& jsValue, CalcDimension& result,
1268     RefPtr<ResourceObject>& resourceObject, bool isSupportPercent, bool enableCheckInvalidvalue)
1269 {
1270     return ArkTSUtils::ParseJsDimension(
1271         vm, jsValue, result, DimensionUnit::FP, resourceObject, isSupportPercent, enableCheckInvalidvalue);
1272 }
1273 
ParseJsDimensionFpNG(const EcmaVM * vm,const Local<JSValueRef> & jsValue,CalcDimension & result,bool isSupportPercent)1274 bool ArkTSUtils::ParseJsDimensionFpNG(const EcmaVM *vm, const Local<JSValueRef> &jsValue, CalcDimension &result,
1275     bool isSupportPercent)
1276 {
1277     return ArkTSUtils::ParseJsDimensionNG(vm, jsValue, result, DimensionUnit::FP, isSupportPercent);
1278 }
1279 
ParseJsDimensionFpNG(const EcmaVM * vm,const Local<JSValueRef> & jsValue,CalcDimension & result,RefPtr<ResourceObject> & resourceObject,bool isSupportPercent)1280 bool ArkTSUtils::ParseJsDimensionFpNG(const EcmaVM *vm, const Local<JSValueRef> &jsValue, CalcDimension &result,
1281     RefPtr<ResourceObject>& resourceObject, bool isSupportPercent)
1282 {
1283     return ArkTSUtils::ParseJsDimensionNG(vm, jsValue, result, DimensionUnit::FP, resourceObject, isSupportPercent);
1284 }
1285 
ParseJsFontFamiliesToString(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::string & result)1286 bool ArkTSUtils::ParseJsFontFamiliesToString(const EcmaVM* vm, const Local<JSValueRef>& jsValue, std::string& result)
1287 {
1288     RefPtr<ResourceObject> resourceObject;
1289     return ParseJsFontFamiliesToString(vm, jsValue, result, resourceObject);
1290 }
1291 
ParseJsFontFamiliesToString(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::string & result,RefPtr<ResourceObject> & resourceObject)1292 bool ArkTSUtils::ParseJsFontFamiliesToString(const EcmaVM* vm, const Local<JSValueRef>& jsValue, std::string& result,
1293     RefPtr<ResourceObject>& resourceObject)
1294 {
1295     if (jsValue->IsNull() || jsValue->IsUndefined()) {
1296         return false;
1297     }
1298 
1299     if (jsValue->IsString(vm) && jsValue->ToString(vm)->ToString(vm).empty()) {
1300         return false;
1301     }
1302 
1303     std::vector<std::string> fontFamilies;
1304     if (!ParseJsFontFamilies(vm, jsValue, fontFamilies, resourceObject)) {
1305         return false;
1306     }
1307     if (fontFamilies.size() > 0) {
1308         result = "";
1309         for (uint32_t i = 0; i < fontFamilies.size(); i++) {
1310             result += fontFamilies.at(i);
1311             if (&fontFamilies.at(i) != &fontFamilies.back()) {
1312                 result += ",";
1313             }
1314         }
1315         return true;
1316     }
1317 
1318     return true;
1319 }
1320 
ParseJsFontFamilies(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::vector<std::string> & result)1321 bool ArkTSUtils::ParseJsFontFamilies(
1322     const EcmaVM *vm, const Local<JSValueRef> &jsValue, std::vector<std::string> &result)
1323 {
1324     RefPtr<ResourceObject> resourceObject;
1325     return ParseJsFontFamilies(vm, jsValue, result, resourceObject);
1326 }
1327 
ParseJsFontFamilies(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::vector<std::string> & result,RefPtr<ResourceObject> & resourceObject)1328 bool ArkTSUtils::ParseJsFontFamilies(const EcmaVM *vm, const Local<JSValueRef> &jsValue,
1329     std::vector<std::string> &result, RefPtr<ResourceObject>& resourceObject)
1330 {
1331     result.clear();
1332     if (!jsValue->IsString(vm) && !jsValue->IsObject(vm)) {
1333         return false;
1334     }
1335     if (jsValue->IsString(vm)) {
1336         result = Framework::ConvertStrToFontFamilies(jsValue->ToString(vm)->ToString(vm));
1337         return true;
1338     }
1339     if (jsValue->IsObject(vm)) {
1340         auto obj = jsValue->ToObject(vm);
1341         auto resId = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
1342         if (!resId->IsNumber()) {
1343             return false;
1344         }
1345         return ParseJsFontFamiliesFromResource(vm, jsValue, result, resourceObject);
1346     }
1347     return true;
1348 }
1349 
ParseJsFontFamiliesFromResource(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::vector<std::string> & result,RefPtr<ResourceObject> & resourceObject)1350 bool ArkTSUtils::ParseJsFontFamiliesFromResource(const EcmaVM *vm, const Local<JSValueRef> &jsValue,
1351     std::vector<std::string> &result, RefPtr<ResourceObject>& resourceObject)
1352 {
1353     auto jsObj = jsValue->ToObject(vm);
1354     auto resId = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
1355     if (!resId->IsNumber()) {
1356         return false;
1357     }
1358 
1359     CompleteResourceObject(vm, jsObj);
1360     resourceObject = GetResourceObject(vm, jsValue);
1361     auto resourceWrapper = CreateResourceWrapper(vm, jsValue, resourceObject);
1362     if (!resourceWrapper) {
1363         return false;
1364     }
1365 
1366     auto resIdNum = resId->Int32Value(vm);
1367     if (resIdNum == -1) {
1368         if (!IsGetResourceByName(vm, jsValue)) {
1369             return false;
1370         }
1371         auto args = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "params"));
1372         if (!args->IsArray(vm)) {
1373             return false;
1374         }
1375         Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
1376         auto param = panda::ArrayRef::GetValueAt(vm, params, 0);
1377         result.emplace_back(resourceWrapper->GetStringByName(param->ToString(vm)->ToString(vm)));
1378         return true;
1379     }
1380     result.emplace_back(resourceWrapper->GetString(resId->Uint32Value(vm)));
1381     return true;
1382 }
1383 
ParseJsLengthMetrics(const EcmaVM * vm,const Local<JSValueRef> & jsValue,CalcDimension & result)1384 bool ArkTSUtils::ParseJsLengthMetrics(const EcmaVM* vm, const Local<JSValueRef>& jsValue, CalcDimension& result)
1385 {
1386     RefPtr<ResourceObject> resourceObj;
1387     return ParseJsLengthMetrics(vm, jsValue, result, resourceObj);
1388 }
1389 
ParseJsLengthMetrics(const EcmaVM * vm,const Local<JSValueRef> & jsValue,CalcDimension & result,RefPtr<ResourceObject> & resourceObj)1390 bool ArkTSUtils::ParseJsLengthMetrics(const EcmaVM* vm, const Local<JSValueRef>& jsValue, CalcDimension& result,
1391     RefPtr<ResourceObject>& resourceObj)
1392 {
1393     if (!jsValue->IsObject(vm)) {
1394         return false;
1395     }
1396     auto jsObj = jsValue->ToObject(vm);
1397     auto value = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "value"));
1398     if (!value->IsNumber()) {
1399         return false;
1400     }
1401     auto unit = DimensionUnit::VP;
1402     auto jsUnit = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "unit"));
1403     if (jsUnit->IsNumber()) {
1404         unit = static_cast<DimensionUnit>(jsUnit->ToNumber(vm)->Value());
1405     }
1406     CalcDimension dimension(value->ToNumber(vm)->Value(), unit);
1407     result = dimension;
1408     auto jsRes = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "res"));
1409     if (SystemProperties::ConfigChangePerform() && !jsRes->IsUndefined() &&
1410         !jsRes->IsNull() && jsRes->IsObject(vm)) {
1411         auto jsObjRes = jsRes->ToObject(vm);
1412         CompleteResourceObject(vm, jsObjRes);
1413         resourceObj = GetResourceObject(vm, jsObjRes);
1414     }
1415     return true;
1416 }
1417 
ParseJsMedia(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::string & result)1418 bool ArkTSUtils::ParseJsMedia(const EcmaVM *vm, const Local<JSValueRef> &jsValue, std::string& result)
1419 {
1420     RefPtr<ResourceObject> resourceObject;
1421     return ParseJsMedia(vm, jsValue, result, resourceObject);
1422 }
1423 
ParseJsMedia(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::string & result,RefPtr<ResourceObject> & resourceObject)1424 bool ArkTSUtils::ParseJsMedia(const EcmaVM *vm, const Local<JSValueRef> &jsValue, std::string& result,
1425     RefPtr<ResourceObject>& resourceObject)
1426 {
1427     if (!jsValue->IsObject(vm) && !jsValue->IsString(vm)) {
1428         return false;
1429     }
1430     if (jsValue->IsString(vm)) {
1431         result = jsValue->ToString(vm)->ToString(vm);
1432         return true;
1433     }
1434     if (jsValue->IsObject(vm)) {
1435         auto obj = jsValue->ToObject(vm);
1436         CompleteResourceObject(vm, obj);
1437         auto resId = obj->Get(vm,
1438             panda::ExternalStringCache::GetCachedString(vm, static_cast<int32_t>(Framework::ArkUIIndex::ID)));
1439         if (!resId->IsNumber()) {
1440             return false;
1441         }
1442         return ParseJsMediaFromResource(vm, jsValue, result, resourceObject);
1443     }
1444     return false;
1445 }
1446 
ParseJsMediaFromResource(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::string & result,RefPtr<ResourceObject> & resourceObject)1447 bool ArkTSUtils::ParseJsMediaFromResource(const EcmaVM *vm, const Local<JSValueRef> &jsValue, std::string& result,
1448     RefPtr<ResourceObject>& resourceObject)
1449 {
1450     auto jsObj = jsValue->ToObject(vm);
1451     auto type = jsObj->Get(vm,
1452         panda::ExternalStringCache::GetCachedString(vm, static_cast<int32_t>(Framework::ArkUIIndex::TYPE)));
1453     auto resId = jsObj->Get(vm,
1454         panda::ExternalStringCache::GetCachedString(vm, static_cast<int32_t>(Framework::ArkUIIndex::ID)));
1455     if (!resId->IsNull() && !type->IsNull() && type->IsNumber() && resId->IsNumber()) {
1456         resourceObject = GetResourceObject(vm, jsValue);
1457         auto resourceWrapper = CreateResourceWrapper(vm, jsValue, resourceObject);
1458         CHECK_NULL_RETURN(resourceWrapper, false);
1459 
1460         if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::RAWFILE)) {
1461             auto args = jsObj->Get(vm, panda::ExternalStringCache::GetCachedString(vm,
1462                 static_cast<int32_t>(Framework::ArkUIIndex::PARAMS)));
1463             if (!args->IsArray(vm)) {
1464                 return false;
1465             }
1466             Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
1467             auto fileName = panda::ArrayRef::GetValueAt(vm, params, 0);
1468             if (!fileName->IsString(vm)) {
1469                 return false;
1470             }
1471             result = resourceWrapper->GetRawfile(fileName->ToString(vm)->ToString(vm));
1472             return true;
1473         }
1474         auto resIdNum = resId->Int32Value(vm);
1475         if (resIdNum == -1) {
1476             if (!IsGetResourceByName(vm, jsValue)) {
1477                 return false;
1478             }
1479             auto args = jsObj->Get(vm, panda::ExternalStringCache::GetCachedString(vm,
1480                 static_cast<int32_t>(Framework::ArkUIIndex::PARAMS)));
1481             if (!args->IsArray(vm)) {
1482                 return false;
1483             }
1484             Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
1485             auto param = panda::ArrayRef::GetValueAt(vm, params, 0);
1486             if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::MEDIA)) {
1487                 result = resourceWrapper->GetMediaPathByName(param->ToString(vm)->ToString(vm));
1488                 return true;
1489             }
1490             return false;
1491         }
1492         if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::MEDIA)) {
1493             result = resourceWrapper->GetMediaPath(resId->Uint32Value(vm));
1494             return true;
1495         }
1496         return false;
1497     }
1498     return false;
1499 }
1500 
GetStringFromJS(const EcmaVM * vm,const Local<JSValueRef> & value,std::string & result)1501 void ArkTSUtils::GetStringFromJS(const EcmaVM *vm, const Local<JSValueRef> &value, std::string& result)
1502 {
1503     result = DEFAULT_STR;
1504     if (!value->IsNull() && value->IsString(vm)) {
1505         result = value->ToString(vm)->ToString(vm);
1506     }
1507     if (value->IsObject(vm)) {
1508         ParseJsStringFromResource(vm, value, result);
1509     }
1510 }
1511 
ParseJsIntegerArray(const EcmaVM * vm,Local<JSValueRef> values,std::vector<uint32_t> & result)1512 bool ArkTSUtils::ParseJsIntegerArray(const EcmaVM* vm, Local<JSValueRef> values, std::vector<uint32_t>& result)
1513 {
1514     if (!values->IsArray(vm) && !values->IsObject(vm)) {
1515         return false;
1516     }
1517 
1518     Local<panda::ArrayRef> valueArray = static_cast<Local<panda::ArrayRef>>(values);
1519     for (size_t i = 0; i < valueArray->Length(vm); i++) {
1520         Local<JSValueRef> value = valueArray->GetValueAt(vm, values, i);
1521         if (value->IsNumber()) {
1522             result.emplace_back(value->Uint32Value(vm));
1523         } else if (value->IsObject(vm)) {
1524             uint32_t singleResInt;
1525             if (ParseJsInteger(vm, value, singleResInt)) {
1526                 result.emplace_back(singleResInt);
1527             } else {
1528                 return false;
1529             }
1530         } else {
1531             return false;
1532         }
1533     }
1534     return true;
1535 }
1536 
ParseJsString(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::string & result,RefPtr<ResourceObject> & resourceObject,const NodeInfo & nodeInfo)1537 bool ArkTSUtils::ParseJsString(const EcmaVM* vm, const Local<JSValueRef>& jsValue, std::string& result,
1538     RefPtr<ResourceObject>& resourceObject, const NodeInfo& nodeInfo)
1539 {
1540     if (!jsValue->IsString(vm) && !jsValue->IsObject(vm)) {
1541         return false;
1542     }
1543     Color color;
1544     bool ret = ArkTSUtils::ParseJsColor(vm, jsValue, color, resourceObject, nodeInfo);
1545     result = ret ? color.ToString() : "";
1546     return ret;
1547 }
1548 
ParseJsString(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::string & result)1549 bool ArkTSUtils::ParseJsString(const EcmaVM* vm, const Local<JSValueRef>& jsValue, std::string& result)
1550 {
1551     RefPtr<ResourceObject> resourceObject;
1552     return ParseJsString(vm, jsValue, result, resourceObject);
1553 }
1554 
ParseJsString(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::string & result,RefPtr<ResourceObject> & resourceObject)1555 bool ArkTSUtils::ParseJsString(const EcmaVM* vm, const Local<JSValueRef>& jsValue, std::string& result,
1556     RefPtr<ResourceObject>& resourceObject)
1557 {
1558     if (!jsValue->IsString(vm) && !jsValue->IsObject(vm)) {
1559         return false;
1560     }
1561     if (jsValue->IsString(vm)) {
1562         result = jsValue->ToString(vm)->ToString(vm);
1563         return true;
1564     }
1565     if (jsValue->IsObject(vm)) {
1566         return ArkTSUtils::ParseJsStringFromResource(vm, jsValue, result, resourceObject);
1567     }
1568     return false;
1569 }
1570 
GetReplaceContentStr(const EcmaVM * vm,int32_t pos,const std::string & type,Local<panda::ArrayRef> params,int32_t containCount)1571 std::string GetReplaceContentStr(
1572     const EcmaVM* vm, int32_t pos, const std::string& type, Local<panda::ArrayRef> params, int32_t containCount)
1573 {
1574     int32_t index = pos + containCount;
1575     if (index < 0) {
1576         return std::string();
1577     }
1578     auto item = panda::ArrayRef::GetValueAt(vm, params, static_cast<uint32_t>(index));
1579     if (type == "d") {
1580         if (item->IsNumber()) {
1581             return std::to_string(item->Int32Value(vm));
1582         }
1583     } else if (type == "s") {
1584         if (item->IsString(vm)) {
1585             return item->ToString(vm)->ToString(vm);
1586         }
1587     } else if (type == "f") {
1588         if (item->IsNumber()) {
1589             return std::to_string(item->ToNumber(vm)->Value());
1590         }
1591     }
1592     return std::string();
1593 }
1594 
ReplaceHolder(const EcmaVM * vm,std::string & originStr,const Local<panda::ArrayRef> & params,int32_t containCount)1595 void ReplaceHolder(const EcmaVM* vm, std::string& originStr, const Local<panda::ArrayRef>& params, int32_t containCount)
1596 {
1597     auto size = static_cast<int32_t>(params->Length(vm));
1598     if (containCount == size) {
1599         return;
1600     }
1601     std::string::const_iterator start = originStr.begin();
1602     std::string::const_iterator end = originStr.end();
1603     std::smatch matches;
1604     bool shortHolderType = false;
1605     bool firstMatch = true;
1606     int searchTime = 0;
1607     while (std::regex_search(start, end, matches, RESOURCE_APP_STRING_PLACEHOLDER)) {
1608         std::string pos = matches[2];
1609         std::string type = matches[4];
1610         if (firstMatch) {
1611             firstMatch = false;
1612             shortHolderType = pos.length() == 0;
1613         } else {
1614             if (static_cast<uint32_t>(shortHolderType) ^ static_cast<uint32_t>(pos.length() == 0)) {
1615                 return;
1616             }
1617         }
1618 
1619         std::string replaceContentStr;
1620         if (shortHolderType) {
1621             replaceContentStr = GetReplaceContentStr(vm, searchTime, type, params, containCount);
1622         } else {
1623             replaceContentStr = GetReplaceContentStr(vm, StringUtils::StringToInt(pos) - 1, type, params, containCount);
1624         }
1625 
1626         originStr.replace(matches[0].first - originStr.begin(), matches[0].length(), replaceContentStr);
1627         start = originStr.begin() + matches.prefix().length() + replaceContentStr.length();
1628         end = originStr.end();
1629         searchTime++;
1630     }
1631 }
1632 
FillResultForResIdNumIsNegative(const EcmaVM * vm,const Local<JSValueRef> & type,const Local<JSValueRef> & params,std::string & result,const RefPtr<ResourceWrapper> & resourceWrapper)1633 bool FillResultForResIdNumIsNegative(const EcmaVM* vm, const Local<JSValueRef>& type, const Local<JSValueRef>& params,
1634     std::string& result, const RefPtr<ResourceWrapper>& resourceWrapper)
1635 {
1636     auto param = panda::ArrayRef::GetValueAt(vm, params, 0);
1637     if (type->Uint32Value(vm) == static_cast<uint32_t>(ResourceType::STRING)) {
1638         auto originStr = resourceWrapper->GetStringByName(param->ToString(vm)->ToString(vm));
1639         ReplaceHolder(vm, originStr, params, 1);
1640         result = originStr;
1641     } else if (type->Uint32Value(vm) == static_cast<uint32_t>(ResourceType::PLURAL)) {
1642         auto countJsVal = panda::ArrayRef::GetValueAt(vm, params, 1);
1643         int count = 0;
1644         if (!countJsVal->IsNumber()) {
1645             return false;
1646         }
1647         count = countJsVal->ToNumber(vm)->Value();
1648         auto pluralStr = resourceWrapper->GetPluralStringByName(param->ToString(vm)->ToString(vm), count);
1649         ReplaceHolder(vm, pluralStr, params, REPLACEHOLDER_INDEX);
1650         result = pluralStr;
1651     } else {
1652         return false;
1653     }
1654     return true;
1655 }
1656 
ParseJsStringFromResource(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::string & result)1657 bool ArkTSUtils::ParseJsStringFromResource(const EcmaVM* vm, const Local<JSValueRef>& jsValue, std::string& result)
1658 {
1659     RefPtr<ResourceObject> resourceObject;
1660     return ParseJsStringFromResource(vm, jsValue, result, resourceObject);
1661 }
1662 
ParseJsStringFromResource(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::string & result,RefPtr<ResourceObject> & resourceObject)1663 bool ArkTSUtils::ParseJsStringFromResource(const EcmaVM* vm, const Local<JSValueRef>& jsValue, std::string& result,
1664     RefPtr<ResourceObject>& resourceObject)
1665 {
1666     auto obj = jsValue->ToObject(vm);
1667     CompleteResourceObject(vm, obj);
1668 
1669     auto type = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "type"));
1670     auto resId = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
1671     auto args = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "params"));
1672     if (!type->IsNumber() || !resId->IsNumber() || !args->IsArray(vm)) {
1673         return false;
1674     }
1675 
1676     resourceObject = GetResourceObject(vm, obj);
1677     auto resourceWrapper = CreateResourceWrapper(vm, obj, resourceObject);
1678     if (!resourceWrapper) {
1679         return false;
1680     }
1681 
1682     Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
1683     auto resIdNum = resourceObject->GetId();
1684     if (resIdNum == -1) {
1685         if (!IsGetResourceByName(vm, obj)) {
1686             return false;
1687         }
1688         return FillResultForResIdNumIsNegative(vm, type, params, result, resourceWrapper);
1689     }
1690     if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::STRING)) {
1691         auto originStr = resourceWrapper->GetString(resId->Uint32Value(vm));
1692         ReplaceHolder(vm, originStr, params, 0);
1693         result = originStr;
1694     } else if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::PLURAL)) {
1695         auto countJsVal = panda::ArrayRef::GetValueAt(vm, params, 0);
1696         int count = 0;
1697         if (!countJsVal->IsNumber()) {
1698             return false;
1699         }
1700         count = countJsVal->ToNumber(vm)->Value();
1701         auto pluralStr = resourceWrapper->GetPluralString(resId->ToNumber(vm)->Value(), count);
1702         ReplaceHolder(vm, pluralStr, params, 1);
1703         result = pluralStr;
1704     } else if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::FLOAT)) {
1705         result = std::to_string(resourceWrapper->GetDouble(resId->Uint32Value(vm)));
1706     } else if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::INTEGER)) {
1707         result = std::to_string(resourceWrapper->GetInt(resId->Uint32Value(vm)));
1708     } else {
1709         return false;
1710     }
1711     return true;
1712 }
1713 
ParseJsResource(const EcmaVM * vm,const Local<JSValueRef> & jsValue,CalcDimension & result)1714 bool ArkTSUtils::ParseJsResource(const EcmaVM *vm, const Local<JSValueRef> &jsValue, CalcDimension &result)
1715 {
1716     RefPtr<ResourceObject> resourceObject;
1717     return ParseJsResource(vm, jsValue, result, resourceObject);
1718 }
1719 
ParseJsResource(const EcmaVM * vm,const Local<JSValueRef> & jsValue,CalcDimension & result,RefPtr<ResourceObject> & resourceObject)1720 bool ArkTSUtils::ParseJsResource(const EcmaVM *vm, const Local<JSValueRef> &jsValue, CalcDimension &result,
1721     RefPtr<ResourceObject>& resourceObject)
1722 {
1723     if (!jsValue->IsObject(vm)) {
1724         return false;
1725     }
1726     auto jsObj = jsValue->ToObject(vm);
1727     CompleteResourceObject(vm, jsObj);
1728     resourceObject = GetResourceObject(vm, jsValue);
1729     auto resourceWrapper = CreateResourceWrapper(vm, jsValue, resourceObject);
1730     CHECK_NULL_RETURN(resourceWrapper, false);
1731 
1732     auto type = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "type"));
1733     auto id = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
1734     uint32_t resourceType = 0;
1735     if (type->IsNull() || !type->IsNumber() || id->IsNull() || !id->IsNumber()) {
1736         return false;
1737     } else {
1738         resourceType = type->Uint32Value(vm);
1739     }
1740     if (resourceType == static_cast<uint32_t>(ResourceType::STRING)) {
1741         auto value = resourceWrapper->GetString(id->Uint32Value(vm));
1742         return StringUtils::StringToCalcDimensionNG(value, result, false);
1743     }
1744     if (resourceType == static_cast<uint32_t>(ResourceType::INTEGER)) {
1745         auto value = std::to_string(resourceWrapper->GetInt(id->Uint32Value(vm)));
1746         StringUtils::StringToDimensionWithUnitNG(value, result);
1747         return true;
1748     }
1749 
1750     if (resourceType == static_cast<uint32_t>(ResourceType::FLOAT)) {
1751         result = resourceWrapper->GetDimension(id->Uint32Value(vm));
1752         return true;
1753     }
1754     return false;
1755 }
1756 
GetJsMediaBundleInfo(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::string & bundleName,std::string & moduleName)1757 void ArkTSUtils::GetJsMediaBundleInfo(
1758     const EcmaVM* vm, const Local<JSValueRef>& jsValue, std::string& bundleName, std::string& moduleName)
1759 {
1760     if (!jsValue->IsObject(vm) || jsValue->IsString(vm)) {
1761         return;
1762     }
1763     auto jsObj = jsValue->ToObject(vm);
1764     if (!jsObj->IsUndefined()) {
1765         auto bundle = jsObj->Get(vm, panda::ExternalStringCache::GetCachedString(vm,
1766             static_cast<int32_t>(Framework::ArkUIIndex::BUNDLE_NAME)));
1767         auto module = jsObj->Get(vm, panda::ExternalStringCache::GetCachedString(vm,
1768             static_cast<int32_t>(Framework::ArkUIIndex::MODULE_NAME)));
1769         if (bundle->IsString(vm) && module->IsString(vm)) {
1770             bundleName = bundle->ToString(vm)->ToString(vm);
1771             moduleName = module->ToString(vm)->ToString(vm);
1772         }
1773     }
1774 }
1775 
ParseJsColorStrategy(const EcmaVM * vm,const Local<JSValueRef> & value,ForegroundColorStrategy & strategy)1776 bool ArkTSUtils::ParseJsColorStrategy(
1777     const EcmaVM* vm, const Local<JSValueRef>& value, ForegroundColorStrategy& strategy)
1778 {
1779     if (value->IsString(vm)) {
1780         std::string colorStr = value->ToString(vm)->ToString(vm);
1781         if (colorStr.compare("invert") == 0) {
1782             strategy = ForegroundColorStrategy::INVERT;
1783             return true;
1784         }
1785     }
1786     return false;
1787 }
1788 
GetJsPasswordIcon(const EcmaVM * vm,const Local<JSValueRef> & jsOnIconSrc,const Local<JSValueRef> & jsOffIconSrc,PasswordIcon & result)1789 bool ArkTSUtils::GetJsPasswordIcon(const EcmaVM *vm, const Local<JSValueRef> &jsOnIconSrc,
1790     const Local<JSValueRef> &jsOffIconSrc, PasswordIcon& result)
1791 {
1792     result.showResult = "";
1793     result.hideResult = "";
1794     result.showBundleName = "";
1795     result.hideBundleName = "";
1796     result.showModuleName = "";
1797     result.hideModuleName = "";
1798 
1799     if (!jsOnIconSrc->IsString(vm) && !jsOnIconSrc->IsObject(vm)
1800         && !jsOffIconSrc->IsString(vm) && !jsOffIconSrc->IsObject(vm)) {
1801         return false;
1802     }
1803 
1804     if (jsOnIconSrc->IsString(vm)) {
1805         result.showResult = jsOnIconSrc->ToString(vm)->ToString(vm);
1806     }
1807 
1808     if (jsOnIconSrc->IsObject(vm)) {
1809         auto obj = jsOnIconSrc->ToObject(vm);
1810         std::string bundleName;
1811         std::string moduleName;
1812         auto bundle = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "bundleName"));
1813         auto module = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "moduleName"));
1814         if (bundle->IsString(vm) && module->IsString(vm)) {
1815             result.showBundleName = bundle->ToString(vm)->ToString(vm);
1816             result.showModuleName = module->ToString(vm)->ToString(vm);
1817         }
1818         ParseJsMedia(vm, jsOnIconSrc, result.showResult);
1819     }
1820 
1821     if (jsOffIconSrc->IsString(vm)) {
1822         result.hideResult = jsOffIconSrc->ToString(vm)->ToString(vm);
1823     }
1824 
1825     if (jsOffIconSrc->IsObject(vm)) {
1826         auto obj = jsOffIconSrc->ToObject(vm);
1827         std::string bundleName;
1828         std::string moduleName;
1829         auto bundle = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "bundleName"));
1830         auto module = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "moduleName"));
1831         if (bundle->IsString(vm) && module->IsString(vm)) {
1832             result.hideBundleName = bundle->ToString(vm)->ToString(vm);
1833             result.hideModuleName = module->ToString(vm)->ToString(vm);
1834         }
1835         ParseJsMedia(vm, jsOffIconSrc, result.hideResult);
1836     }
1837     return true;
1838 }
1839 
ParsePadding(const EcmaVM * vm,const Local<JSValueRef> & value,CalcDimension & dimen,ArkUISizeType & result)1840 void ArkTSUtils::ParsePadding(
1841     const EcmaVM* vm, const Local<JSValueRef>& value, CalcDimension& dimen, ArkUISizeType& result)
1842 {
1843     if (ArkTSUtils::ParseJsDimensionVp(vm, value, dimen)) {
1844         if (LessOrEqual(dimen.Value(), 0.0)) {
1845             dimen.SetValue(0.0);
1846             dimen.SetUnit(DimensionUnit::VP);
1847         }
1848         result.unit = static_cast<int8_t>(dimen.Unit());
1849         if (dimen.CalcValue() != "") {
1850             result.string = dimen.CalcValue().c_str();
1851         } else {
1852             result.value = dimen.Value();
1853         }
1854     }
1855 }
1856 
ParsePadding(const EcmaVM * vm,const Local<JSValueRef> & value,CalcDimension & dimen,ArkUISizeType & result,RefPtr<ResourceObject> & resObj)1857 void ArkTSUtils::ParsePadding(const EcmaVM* vm, const Local<JSValueRef>& value, CalcDimension& dimen,
1858                               ArkUISizeType& result, RefPtr<ResourceObject>& resObj)
1859 {
1860     if (ArkTSUtils::ParseJsDimensionVp(vm, value, dimen, resObj)) {
1861         if (LessOrEqual(dimen.Value(), 0.0)) {
1862             dimen.SetValue(0.0);
1863             dimen.SetUnit(DimensionUnit::VP);
1864         }
1865         result.unit = static_cast<int8_t>(dimen.Unit());
1866         if (dimen.CalcValue() != "") {
1867             result.string = dimen.CalcValue().c_str();
1868         } else {
1869             result.value = dimen.Value();
1870         }
1871     }
1872 }
1873 
GetContext(EcmaVM * vm)1874 panda::Local<panda::ObjectRef> ArkTSUtils::GetContext(EcmaVM* vm)
1875 {
1876     auto container = Container::Current();
1877     CHECK_NULL_RETURN(container, panda::JSValueRef::Undefined(vm));
1878     auto frontend = container->GetFrontend();
1879     CHECK_NULL_RETURN(frontend, panda::JSValueRef::Undefined(vm));
1880     return NapiValueToLocalValue(frontend->GetContextValue());
1881 }
1882 
ParseResponseRegion(const EcmaVM * vm,const Local<JSValueRef> & jsValue,ArkUI_Float32 * regionValues,int32_t * regionUnits,uint32_t length)1883 bool ArkTSUtils::ParseResponseRegion(
1884     const EcmaVM* vm, const Local<JSValueRef>& jsValue, ArkUI_Float32* regionValues,
1885     int32_t* regionUnits, uint32_t length)
1886 {
1887     if (jsValue->IsUndefined() || !jsValue->IsArray(vm)) {
1888         return false;
1889     }
1890 
1891     Local<panda::ArrayRef> transArray = static_cast<Local<panda::ArrayRef>>(jsValue);
1892     for (uint32_t i = 0; i < length; i = i + 4) { // 4: dimension length
1893         Local<JSValueRef> x = transArray->GetValueAt(vm, jsValue, i);
1894         Local<JSValueRef> y = transArray->GetValueAt(vm, jsValue, i + 1);
1895         Local<JSValueRef> width = transArray->GetValueAt(vm, jsValue, i + 2); // 2: width value
1896         Local<JSValueRef> height = transArray->GetValueAt(vm, jsValue, i + 3); // 3: height value
1897         CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
1898         CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
1899         CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
1900         CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
1901         auto s1 = width->ToString(vm)->ToString(vm);
1902         auto s2 = height->ToString(vm)->ToString(vm);
1903         if (s1.find('-') != std::string::npos) {
1904             width = OHOS::Ace::Framework::ToJSValue("100%");
1905         }
1906         if (s2.find('-') != std::string::npos) {
1907             height = OHOS::Ace::Framework::ToJSValue("100%");
1908         }
1909         if (!ArkTSUtils::ParseJsDimensionNG(vm, x, xDimen, DimensionUnit::VP)) {
1910             xDimen = CalcDimension(0.0, DimensionUnit::VP);
1911         }
1912         if (!ArkTSUtils::ParseJsDimensionNG(vm, y, yDimen, DimensionUnit::VP)) {
1913             yDimen = CalcDimension(0.0, DimensionUnit::VP);
1914         }
1915         if (!ArkTSUtils::ParseJsDimensionNG(vm, width, widthDimen, DimensionUnit::VP)) {
1916             widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
1917         }
1918         if (!ArkTSUtils::ParseJsDimensionNG(vm, height, heightDimen, DimensionUnit::VP)) {
1919             heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
1920         }
1921         regionValues[i] = static_cast<ArkUI_Float32>(xDimen.Value());
1922         regionUnits[i] = static_cast<int32_t>(xDimen.Unit());
1923         regionValues[i + 1] = static_cast<ArkUI_Float32>(yDimen.Value());
1924         regionUnits[i + 1] = static_cast<int32_t>(yDimen.Unit());
1925         regionValues[i + 2] = static_cast<ArkUI_Float32>(widthDimen.Value()); // 2: width value
1926         regionUnits[i + 2] = static_cast<int32_t>(widthDimen.Unit()); // 2: width Unit
1927         regionValues[i + 3] = static_cast<ArkUI_Float32>(heightDimen.Value()); // 3: height value
1928         regionUnits[i + 3] = static_cast<int32_t>(heightDimen.Unit()); // 3: height Unit
1929     }
1930     return true;
1931 }
1932 
parseShadowColor(const EcmaVM * vm,const Local<JSValueRef> & jsValue)1933 uint32_t ArkTSUtils::parseShadowColor(const EcmaVM* vm, const Local<JSValueRef>& jsValue)
1934 {
1935     RefPtr<ResourceObject> resObj;
1936     return parseShadowColorWithResObj(vm, jsValue, resObj);
1937 }
1938 
parseShadowColorWithResObj(const EcmaVM * vm,const Local<JSValueRef> & jsValue,RefPtr<ResourceObject> & resObj,const std::optional<NodeInfo> & nodeInfo)1939 uint32_t ArkTSUtils::parseShadowColorWithResObj(const EcmaVM* vm, const Local<JSValueRef>& jsValue,
1940     RefPtr<ResourceObject>& resObj, const std::optional<NodeInfo>& nodeInfo)
1941 {
1942     Color color = DEFAULT_TEXT_SHADOW_COLOR;
1943     static const NodeInfo defaultNodeInfo = { "", ColorMode::COLOR_MODE_UNDEFINED };
1944     if (!ParseJsColorAlpha(vm, jsValue, color, resObj,
1945         (nodeInfo.has_value() ? nodeInfo.value() : defaultNodeInfo))) {
1946         color = DEFAULT_TEXT_SHADOW_COLOR;
1947     }
1948     return color.GetValue();
1949 };
1950 
parseShadowFill(const EcmaVM * vm,const Local<JSValueRef> & jsValue)1951 uint32_t ArkTSUtils::parseShadowFill(const EcmaVM* vm, const Local<JSValueRef>& jsValue)
1952 {
1953     if (jsValue->IsBoolean()) {
1954         return static_cast<uint32_t>(jsValue->ToBoolean(vm)->Value());
1955     }
1956     return static_cast<uint32_t>(DEFAULT_TEXT_SHADOW_FILL);
1957 };
1958 
parseShadowType(const EcmaVM * vm,const Local<JSValueRef> & jsValue)1959 uint32_t ArkTSUtils::parseShadowType(const EcmaVM* vm, const Local<JSValueRef>& jsValue)
1960 {
1961     if (jsValue->IsInt()) {
1962         return jsValue->Uint32Value(vm);
1963     }
1964     return static_cast<uint32_t>(DEFAULT_TEXT_SHADOW_TYPE);
1965 };
1966 
parseShadowRadius(const EcmaVM * vm,const Local<JSValueRef> & jsValue)1967 double ArkTSUtils::parseShadowRadius(const EcmaVM* vm, const Local<JSValueRef>& jsValue)
1968 {
1969     RefPtr<ResourceObject> resObj;
1970     return parseShadowRadiusWithResObj(vm, jsValue, resObj);
1971 }
1972 
parseShadowRadiusWithResObj(const EcmaVM * vm,const Local<JSValueRef> & jsValue,RefPtr<ResourceObject> & resObj,const std::optional<NodeInfo> & nodeInfo)1973 double ArkTSUtils::parseShadowRadiusWithResObj(const EcmaVM* vm, const Local<JSValueRef>& jsValue,
1974     RefPtr<ResourceObject>& resObj, const std::optional<NodeInfo>& nodeInfo)
1975 {
1976     double radius = 0.0;
1977     ArkTSUtils::ParseJsDouble(vm, jsValue, radius, resObj);
1978     if (LessNotEqual(radius, 0.0)) {
1979         radius = 0.0;
1980     }
1981     return radius;
1982 };
1983 
parseShadowOffset(const EcmaVM * vm,const Local<JSValueRef> & jsValue)1984 double ArkTSUtils::parseShadowOffset(const EcmaVM* vm, const Local<JSValueRef>& jsValue)
1985 {
1986     RefPtr<ResourceObject> resObj;
1987     return parseShadowOffsetWithResObj(vm, jsValue, resObj);
1988 }
1989 
parseShadowOffsetWithResObj(const EcmaVM * vm,const Local<JSValueRef> & jsValue,RefPtr<ResourceObject> & resObj,const std::optional<NodeInfo> & nodeInfo)1990 double ArkTSUtils::parseShadowOffsetWithResObj(const EcmaVM* vm, const Local<JSValueRef>& jsValue,
1991     RefPtr<ResourceObject>& resObj, const std::optional<NodeInfo>& nodeInfo)
1992 {
1993     CalcDimension offset;
1994     if (ArkTSUtils::ParseJsResource(vm, jsValue, offset, resObj)) {
1995         return offset.Value();
1996     } else if (ArkTSUtils::ParseJsDimensionVp(vm, jsValue, offset, resObj)) {
1997         return offset.Value();
1998     }
1999     return 0.0;
2000 };
2001 
ParseOuterBorder(EcmaVM * vm,const Local<JSValueRef> & args,std::optional<CalcDimension> & optionalDimension)2002 void ArkTSUtils::ParseOuterBorder(
2003     EcmaVM* vm, const Local<JSValueRef>& args, std::optional<CalcDimension>& optionalDimension)
2004 {
2005     RefPtr<ResourceObject> resObj;
2006     ParseOuterBorder(vm, args, optionalDimension, resObj);
2007 }
2008 
ParseOuterBorder(EcmaVM * vm,const Local<JSValueRef> & args,std::optional<CalcDimension> & optionalDimension,RefPtr<ResourceObject> & resObj)2009 void ArkTSUtils::ParseOuterBorder(EcmaVM* vm, const Local<JSValueRef>& args,
2010     std::optional<CalcDimension>& optionalDimension, RefPtr<ResourceObject>& resObj)
2011 {
2012     CalcDimension valueDim;
2013     auto outerBorder = ArkTSUtils::ParseJsDimensionVp(vm, args, valueDim, resObj, false);
2014     if (!args->IsUndefined() && outerBorder) {
2015         if (valueDim.IsNegative() || valueDim.Unit() == DimensionUnit::PERCENT) {
2016             valueDim.Reset();
2017         }
2018         optionalDimension = valueDim;
2019     }
2020 }
2021 
ParseOuterBorderForDashParams(EcmaVM * vm,const Local<JSValueRef> & args,std::optional<CalcDimension> & optionalDimension)2022 void ArkTSUtils::ParseOuterBorderForDashParams(
2023     EcmaVM* vm, const Local<JSValueRef>& args, std::optional<CalcDimension>& optionalDimension)
2024 {
2025     RefPtr<ResourceObject> resObj;
2026     ParseOuterBorderForDashParams(vm, args, optionalDimension, resObj);
2027 }
2028 
ParseOuterBorderForDashParams(EcmaVM * vm,const Local<JSValueRef> & args,std::optional<CalcDimension> & optionalDimension,RefPtr<ResourceObject> & resObj)2029 void ArkTSUtils::ParseOuterBorderForDashParams(EcmaVM* vm, const Local<JSValueRef>& args,
2030     std::optional<CalcDimension>& optionalDimension, RefPtr<ResourceObject>& resObj)
2031 {
2032     CalcDimension valueDim;
2033     if (!args->IsUndefined()) {
2034         if (ArkTSUtils::ParseJsLengthMetrics(vm, args, valueDim)) {
2035             if (valueDim.Unit() == DimensionUnit::PERCENT) {
2036                 valueDim.Reset();
2037             }
2038             optionalDimension = valueDim;
2039         } else if (ArkTSUtils::ParseJsDimensionVpNG(vm, args, valueDim, resObj, false)) {
2040             if (valueDim.IsNegative() || valueDim.Unit() == DimensionUnit::PERCENT) {
2041                 valueDim.Reset();
2042             }
2043             optionalDimension = valueDim;
2044         }
2045     }
2046 }
2047 
PushOuterBorderDimensionVector(const std::optional<CalcDimension> & valueDim,std::vector<ArkUI_Float32> & values,std::vector<ArkUI_Int32> & units)2048 void ArkTSUtils::PushOuterBorderDimensionVector(
2049     const std::optional<CalcDimension>& valueDim, std::vector<ArkUI_Float32>& values, std::vector<ArkUI_Int32>& units)
2050 {
2051     if (valueDim.has_value()) {
2052         values.emplace_back(static_cast<ArkUI_Float32>(valueDim.value().Value()));
2053         units.emplace_back(static_cast<ArkUI_Float32>(valueDim.value().Unit()));
2054     } else {
2055         values.emplace_back(0);
2056         units.emplace_back(0);
2057     }
2058 }
2059 
ParseJsSymbolFontFamilyName(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::string & customFamilyName)2060 void ArkTSUtils::ParseJsSymbolFontFamilyName(const EcmaVM *vm, const Local<JSValueRef> &jsValue,
2061     std::string& customFamilyName)
2062 {
2063     if (jsValue->IsNull() || jsValue->IsUndefined()) {
2064         return;
2065     }
2066     auto jsObj = jsValue->ToObject(vm);
2067     CompleteResourceObject(vm, jsObj);
2068     auto resId = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
2069     if (resId->IsNull() || !resId->IsNumber()) {
2070         return;
2071     }
2072     auto resourceObject = GetResourceObject(vm, jsValue);
2073     if (!resourceObject) {
2074         return;
2075     }
2076     std::string bundleName = resourceObject->GetBundleName();
2077     std::string moduleName = resourceObject->GetModuleName();
2078     customFamilyName = bundleName + "_" + moduleName + CUSTOM_SYMBOL_SUFFIX;
2079     std::replace(customFamilyName.begin(), customFamilyName.end(), '.', '_');
2080 }
2081 
ParseJsSymbolId(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::uint32_t & symbolId)2082 bool ArkTSUtils::ParseJsSymbolId(const EcmaVM *vm, const Local<JSValueRef> &jsValue, std::uint32_t& symbolId)
2083 {
2084     RefPtr<ResourceObject> resourceObject;
2085     return ParseJsSymbolId(vm, jsValue, symbolId, resourceObject);
2086 }
2087 
ParseJsSymbolId(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::uint32_t & symbolId,RefPtr<ResourceObject> & resourceObject)2088 bool ArkTSUtils::ParseJsSymbolId(const EcmaVM *vm, const Local<JSValueRef> &jsValue, std::uint32_t& symbolId,
2089     RefPtr<ResourceObject>& resourceObject)
2090 {
2091     if (jsValue->IsNull() || jsValue->IsUndefined()) {
2092         symbolId = 0;
2093         return false;
2094     }
2095     auto jsObj = jsValue->ToObject(vm);
2096     CompleteResourceObject(vm, jsObj);
2097     auto resId = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
2098     if (resId->IsNull() || !resId->IsNumber()) {
2099         return false;
2100     }
2101     resourceObject = GetResourceObject(vm, jsValue);
2102     if (!resourceObject) {
2103         return false;
2104     }
2105     auto resourceWrapper = CreateResourceWrapper(vm, jsValue, resourceObject);
2106     if (!resourceWrapper) {
2107         return false;
2108     }
2109     if (resourceObject->GetType() == static_cast<int32_t>(ResourceType::STRING)) {
2110         auto strValue = resourceWrapper->GetString(resId->Uint32Value(vm));
2111         if (!strValue.empty()) {
2112             auto customSymbolId = static_cast<uint32_t>(strtol(strValue.c_str(), nullptr, 16));
2113             symbolId = customSymbolId;
2114             return true;
2115         }
2116     }
2117     auto resIdNum = resId->Int32Value(vm);
2118     if (resIdNum == -1) {
2119         if (!IsGetResourceByName(vm, jsObj)) {
2120             return false;
2121         }
2122         auto args = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "params"));
2123         if (!args->IsArray(vm)) {
2124             return false;
2125         }
2126         Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
2127         auto param = panda::ArrayRef::GetValueAt(vm, params, 0);
2128         auto symbol = resourceWrapper->GetSymbolByName(param->ToString(vm)->ToString(vm).c_str());
2129         if (!symbol) {
2130             return false;
2131         }
2132         symbolId = symbol;
2133         return true;
2134     }
2135 
2136     auto symbol = resourceWrapper->GetSymbolById(resId->Uint32Value(vm));
2137     if (!symbol) {
2138         return false;
2139     }
2140     symbolId = symbol;
2141     return true;
2142 }
2143 
ConvertBorderStyle(int32_t value)2144 BorderStyle ArkTSUtils::ConvertBorderStyle(int32_t value)
2145 {
2146     auto style = static_cast<BorderStyle>(value);
2147     if (style < BorderStyle::SOLID || style > BorderStyle::NONE) {
2148         style = BorderStyle::SOLID;
2149     }
2150     return style;
2151 }
2152 
PushOuterBorderDimensionVector(const std::optional<CalcDimension> & valueDim,std::vector<ArkUI_Float32> & options)2153 void ArkTSUtils::PushOuterBorderDimensionVector(const std::optional<CalcDimension>& valueDim,
2154     std::vector<ArkUI_Float32> &options)
2155 {
2156     options.push_back(static_cast<ArkUI_Float32>(valueDim.has_value()));
2157     if (valueDim.has_value()) {
2158         options.push_back(static_cast<ArkUI_Float32>(valueDim.value().Value()));
2159         options.push_back(static_cast<ArkUI_Float32>(valueDim.value().Unit()));
2160     } else {
2161         options.push_back(0);
2162         options.push_back(0);
2163     }
2164 }
2165 
ParseOuterBorderWidth(ArkUIRuntimeCallInfo * runtimeCallInfo,EcmaVM * vm,std::vector<ArkUI_Float32> & values)2166 void ArkTSUtils::ParseOuterBorderWidth(
2167     ArkUIRuntimeCallInfo *runtimeCallInfo, EcmaVM *vm, std::vector<ArkUI_Float32> &values)
2168 {
2169     Local<JSValueRef> leftArgs = runtimeCallInfo->GetCallArgRef(NUM_1);
2170     Local<JSValueRef> rightArgs = runtimeCallInfo->GetCallArgRef(NUM_2);
2171     Local<JSValueRef> topArgs = runtimeCallInfo->GetCallArgRef(NUM_3);
2172     Local<JSValueRef> bottomArgs = runtimeCallInfo->GetCallArgRef(NUM_4);
2173     std::optional<CalcDimension> leftDim;
2174     std::optional<CalcDimension> rightDim;
2175     std::optional<CalcDimension> topDim;
2176     std::optional<CalcDimension> bottomDim;
2177 
2178     ParseOuterBorder(vm, leftArgs, leftDim);
2179     ParseOuterBorder(vm, rightArgs, rightDim);
2180     ParseOuterBorder(vm, topArgs, topDim);
2181     ParseOuterBorder(vm, bottomArgs, bottomDim);
2182 
2183     PushOuterBorderDimensionVector(leftDim, values);
2184     PushOuterBorderDimensionVector(rightDim, values);
2185     PushOuterBorderDimensionVector(topDim, values);
2186     PushOuterBorderDimensionVector(bottomDim, values);
2187 }
2188 
PushOuterBorderColorVector(const std::optional<Color> & valueColor,std::vector<uint32_t> & options)2189 void ArkTSUtils::PushOuterBorderColorVector(const std::optional<Color>& valueColor, std::vector<uint32_t> &options)
2190 {
2191     options.push_back(static_cast<uint32_t>(valueColor.has_value()));
2192     if (valueColor.has_value()) {
2193         options.push_back(static_cast<uint32_t>(valueColor.value().GetValue()));
2194     } else {
2195         options.push_back(0);
2196     }
2197 }
2198 
ParseOuterBorderColor(ArkUIRuntimeCallInfo * runtimeCallInfo,EcmaVM * vm,std::vector<uint32_t> & values,int32_t argsIndex)2199 void ArkTSUtils::ParseOuterBorderColor(
2200     ArkUIRuntimeCallInfo* runtimeCallInfo, EcmaVM* vm, std::vector<uint32_t>& values, int32_t argsIndex)
2201 {
2202     Local<JSValueRef> leftArg = runtimeCallInfo->GetCallArgRef(argsIndex);
2203     Local<JSValueRef> rightArg = runtimeCallInfo->GetCallArgRef(argsIndex + NUM_1);
2204     Local<JSValueRef> topArg = runtimeCallInfo->GetCallArgRef(argsIndex + NUM_2);
2205     Local<JSValueRef> bottomArg = runtimeCallInfo->GetCallArgRef(argsIndex + NUM_3);
2206 
2207     std::optional<Color> leftColor;
2208     std::optional<Color> rightColor;
2209     std::optional<Color> topColor;
2210     std::optional<Color> bottomColor;
2211 
2212     Color left;
2213     if (!leftArg->IsUndefined() && ArkTSUtils::ParseJsColorAlpha(vm, leftArg, left)) {
2214         leftColor = left;
2215     }
2216     Color right;
2217     if (!rightArg->IsUndefined() && ArkTSUtils::ParseJsColorAlpha(vm, rightArg, right)) {
2218         rightColor = right;
2219     }
2220     Color top;
2221     if (!topArg->IsUndefined() && ArkTSUtils::ParseJsColorAlpha(vm, topArg, top)) {
2222         topColor = top;
2223     }
2224     Color bottom;
2225     if (!bottomArg->IsUndefined() && ArkTSUtils::ParseJsColorAlpha(vm, bottomArg, bottom)) {
2226         bottomColor = bottom;
2227     }
2228 
2229     PushOuterBorderColorVector(leftColor, values);
2230     PushOuterBorderColorVector(rightColor, values);
2231     PushOuterBorderColorVector(topColor, values);
2232     PushOuterBorderColorVector(bottomColor, values);
2233 }
2234 
ParseOuterBorderRadius(ArkUIRuntimeCallInfo * runtimeCallInfo,EcmaVM * vm,std::vector<ArkUI_Float32> & values,int32_t argsIndex)2235 void ArkTSUtils::ParseOuterBorderRadius(
2236     ArkUIRuntimeCallInfo* runtimeCallInfo, EcmaVM* vm, std::vector<ArkUI_Float32>& values, int32_t argsIndex)
2237 {
2238     Local<JSValueRef> topLeftArgs = runtimeCallInfo->GetCallArgRef(argsIndex);
2239     Local<JSValueRef> topRightArgs = runtimeCallInfo->GetCallArgRef(argsIndex + NUM_1);
2240     Local<JSValueRef> bottomLeftArgs = runtimeCallInfo->GetCallArgRef(argsIndex + NUM_2);
2241     Local<JSValueRef> bottomRightArgs = runtimeCallInfo->GetCallArgRef(argsIndex + NUM_3);
2242 
2243     std::optional<CalcDimension> topLeftOptional;
2244     std::optional<CalcDimension> topRightOptional;
2245     std::optional<CalcDimension> bottomLeftOptional;
2246     std::optional<CalcDimension> bottomRightOptional;
2247 
2248     ParseOuterBorder(vm, topLeftArgs, topLeftOptional);
2249     ParseOuterBorder(vm, topRightArgs, topRightOptional);
2250     ParseOuterBorder(vm, bottomLeftArgs, bottomLeftOptional);
2251     ParseOuterBorder(vm, bottomRightArgs, bottomRightOptional);
2252 
2253     PushOuterBorderDimensionVector(topLeftOptional, values);
2254     PushOuterBorderDimensionVector(topRightOptional, values);
2255     PushOuterBorderDimensionVector(bottomLeftOptional, values);
2256     PushOuterBorderDimensionVector(bottomRightOptional, values);
2257 }
2258 
SetTextBackgroundStyle(std::shared_ptr<TextBackgroundStyle> style,Color color,RefPtr<ResourceObject> & colorResObj,const ArkUI_Float32 * values,const ArkUI_Int32 * units)2259 void ArkTSUtils::SetTextBackgroundStyle(std::shared_ptr<TextBackgroundStyle> style, Color color,
2260     RefPtr<ResourceObject>& colorResObj, const ArkUI_Float32* values, const ArkUI_Int32* units)
2261 {
2262     CHECK_NULL_VOID(style);
2263     if (SystemProperties::ConfigChangePerform() && colorResObj) {
2264         auto&& updateFunc = [](const RefPtr<ResourceObject>& colorResObj, TextBackgroundStyle& textBackgroundStyle) {
2265             Color color;
2266             ResourceParseUtils::ParseResColor(colorResObj, color);
2267             textBackgroundStyle.backgroundColor = color;
2268         };
2269         style->AddResource("textBackgroundStyle.color", colorResObj, std::move(updateFunc));
2270     }
2271     NG::BorderRadiusProperty borderRadius;
2272     borderRadius.radiusTopLeft = Dimension(values[NUM_0], static_cast<OHOS::Ace::DimensionUnit>(units[NUM_0]));
2273     borderRadius.radiusTopRight = Dimension(values[NUM_1], static_cast<OHOS::Ace::DimensionUnit>(units[NUM_1]));
2274     borderRadius.radiusBottomLeft = Dimension(values[NUM_2], static_cast<OHOS::Ace::DimensionUnit>(units[NUM_2]));
2275     borderRadius.radiusBottomRight = Dimension(values[NUM_3], static_cast<OHOS::Ace::DimensionUnit>(units[NUM_3]));
2276     style->backgroundColor = Color(color);
2277     style->backgroundRadius = borderRadius;
2278     style->backgroundRadius->multiValued = true;
2279 }
2280 
RegisterTextBackgroundStyleResource(std::shared_ptr<TextBackgroundStyle> textBackgroundStyle,RefPtr<ResourceObject> & resObjTopLeft,RefPtr<ResourceObject> & resObjTopRight,RefPtr<ResourceObject> & resObjBottomLeft,RefPtr<ResourceObject> & resObjBottomRight)2281 void ArkTSUtils::RegisterTextBackgroundStyleResource(std::shared_ptr<TextBackgroundStyle> textBackgroundStyle,
2282     RefPtr<ResourceObject>& resObjTopLeft, RefPtr<ResourceObject>& resObjTopRight,
2283     RefPtr<ResourceObject>& resObjBottomLeft, RefPtr<ResourceObject>& resObjBottomRight)
2284 {
2285     if (!SystemProperties::ConfigChangePerform()) {
2286         return;
2287     }
2288     CHECK_NULL_VOID(textBackgroundStyle);
2289     if (resObjTopLeft) {
2290         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObjTopLeft,
2291             TextBackgroundStyle& textBackgroundStyle) {
2292             CalcDimension radius;
2293             ResourceParseUtils::ParseResDimensionVp(resObjTopLeft, radius);
2294             textBackgroundStyle.backgroundRadius->radiusTopLeft = radius;
2295             textBackgroundStyle.backgroundRadius->multiValued = true;
2296         };
2297         textBackgroundStyle->AddResource("textBackgroundStyle.radiusTopLeft", resObjTopLeft,
2298             std::move(updateFunc));
2299     }
2300     if (resObjTopRight) {
2301         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObjTopRight,
2302             TextBackgroundStyle& textBackgroundStyle) {
2303             CalcDimension radius;
2304             ResourceParseUtils::ParseResDimensionVp(resObjTopRight, radius);
2305             textBackgroundStyle.backgroundRadius->radiusTopRight = radius;
2306             textBackgroundStyle.backgroundRadius->multiValued = true;
2307         };
2308         textBackgroundStyle->AddResource("textBackgroundStyle.radiusTopRight", resObjTopRight,
2309             std::move(updateFunc));
2310     }
2311     if (resObjBottomLeft) {
2312         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObjBottomLeft,
2313             TextBackgroundStyle& textBackgroundStyle) {
2314             CalcDimension radius;
2315             ResourceParseUtils::ParseResDimensionVp(resObjBottomLeft, radius);
2316             textBackgroundStyle.backgroundRadius->radiusBottomLeft = radius;
2317             textBackgroundStyle.backgroundRadius->multiValued = true;
2318         };
2319         textBackgroundStyle->AddResource("textBackgroundStyle.radiusBottomLeft", resObjBottomLeft,
2320             std::move(updateFunc));
2321     }
2322     if (resObjBottomRight) {
2323         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObjBottomRight,
2324             TextBackgroundStyle& textBackgroundStyle) {
2325             CalcDimension radius;
2326             ResourceParseUtils::ParseResDimensionVp(resObjBottomRight, radius);
2327             textBackgroundStyle.backgroundRadius->radiusBottomRight = radius;
2328             textBackgroundStyle.backgroundRadius->multiValued = true;
2329         };
2330         textBackgroundStyle->AddResource("textBackgroundStyle.radiusBottomRight", resObjBottomRight,
2331             std::move(updateFunc));
2332     }
2333 }
2334 
ParseOuterBorderRadius(ArkUIRuntimeCallInfo * runtimeCallInfo,EcmaVM * vm,std::vector<ArkUI_Float32> & values,std::vector<ArkUI_Int32> & units,int32_t argsIndex)2335 void ArkTSUtils::ParseOuterBorderRadius(ArkUIRuntimeCallInfo* runtimeCallInfo,
2336     EcmaVM* vm, std::vector<ArkUI_Float32>& values, std::vector<ArkUI_Int32>& units, int32_t argsIndex)
2337 {
2338     std::shared_ptr<TextBackgroundStyle> style = std::make_shared<TextBackgroundStyle>();
2339     ParseOuterBorderRadius(runtimeCallInfo, vm, values, units, argsIndex, style);
2340 }
2341 
ParseOuterBorderRadius(ArkUIRuntimeCallInfo * runtimeCallInfo,EcmaVM * vm,std::vector<ArkUI_Float32> & values,std::vector<ArkUI_Int32> & units,int32_t argsIndex,std::shared_ptr<TextBackgroundStyle> textBackgroundStyle)2342 void ArkTSUtils::ParseOuterBorderRadius(ArkUIRuntimeCallInfo* runtimeCallInfo,
2343     EcmaVM* vm, std::vector<ArkUI_Float32>& values, std::vector<ArkUI_Int32>& units, int32_t argsIndex,
2344     std::shared_ptr<TextBackgroundStyle> textBackgroundStyle)
2345 {
2346     Local<JSValueRef> topLeftArgs = runtimeCallInfo->GetCallArgRef(argsIndex);
2347     Local<JSValueRef> topRightArgs = runtimeCallInfo->GetCallArgRef(argsIndex + NUM_1);
2348     Local<JSValueRef> bottomLeftArgs = runtimeCallInfo->GetCallArgRef(argsIndex + NUM_2);
2349     Local<JSValueRef> bottomRightArgs = runtimeCallInfo->GetCallArgRef(argsIndex + NUM_3);
2350 
2351     std::optional<CalcDimension> topLeftOptional;
2352     std::optional<CalcDimension> topRightOptional;
2353     std::optional<CalcDimension> bottomLeftOptional;
2354     std::optional<CalcDimension> bottomRightOptional;
2355 
2356     RefPtr<ResourceObject> resObjTopLeft;
2357     RefPtr<ResourceObject> resObjTopRight;
2358     RefPtr<ResourceObject> resObjBottomLeft;
2359     RefPtr<ResourceObject> resObjBottomRight;
2360 
2361     ParseOuterBorder(vm, topLeftArgs, topLeftOptional, resObjTopLeft);
2362     ParseOuterBorder(vm, topRightArgs, topRightOptional, resObjTopRight);
2363     ParseOuterBorder(vm, bottomLeftArgs, bottomLeftOptional, resObjBottomLeft);
2364     ParseOuterBorder(vm, bottomRightArgs, bottomRightOptional, resObjBottomRight);
2365 
2366     PushOuterBorderDimensionVector(topLeftOptional, values, units);
2367     PushOuterBorderDimensionVector(topRightOptional, values, units);
2368     PushOuterBorderDimensionVector(bottomLeftOptional, values, units);
2369     PushOuterBorderDimensionVector(bottomRightOptional, values, units);
2370 
2371     RegisterTextBackgroundStyleResource(textBackgroundStyle, resObjTopLeft, resObjTopRight, resObjBottomLeft,
2372         resObjBottomRight);
2373 }
2374 
PushOuterBorderStyleVector(const std::optional<BorderStyle> & value,std::vector<uint32_t> & options)2375 void ArkTSUtils::PushOuterBorderStyleVector(const std::optional<BorderStyle>& value, std::vector<uint32_t> &options)
2376 {
2377     options.push_back(static_cast<uint32_t>(value.has_value()));
2378     if (value.has_value()) {
2379         options.push_back(static_cast<uint32_t>(value.value()));
2380     } else {
2381         options.push_back(NUM_0);
2382     }
2383 }
2384 
ParseOuterBorderStyle(ArkUIRuntimeCallInfo * runtimeCallInfo,EcmaVM * vm,std::vector<uint32_t> & values,int32_t argsIndex)2385 void ArkTSUtils::ParseOuterBorderStyle(
2386     ArkUIRuntimeCallInfo* runtimeCallInfo, EcmaVM* vm, std::vector<uint32_t>& values, int32_t argsIndex)
2387 {
2388     std::optional<BorderStyle> styleLeft;
2389     std::optional<BorderStyle> styleRight;
2390     std::optional<BorderStyle> styleTop;
2391     std::optional<BorderStyle> styleBottom;
2392 
2393     auto topArg = runtimeCallInfo->GetCallArgRef(argsIndex);
2394     auto rightArg = runtimeCallInfo->GetCallArgRef(argsIndex + NUM_1);
2395     auto bottomArg = runtimeCallInfo->GetCallArgRef(argsIndex + NUM_2);
2396     auto leftArg = runtimeCallInfo->GetCallArgRef(argsIndex + NUM_3);
2397 
2398     if (!topArg->IsUndefined() && topArg->IsNumber()) {
2399         styleTop = ConvertBorderStyle(topArg->Int32Value(vm));
2400     }
2401     if (!rightArg->IsUndefined() && rightArg->IsNumber()) {
2402         styleRight = ConvertBorderStyle(rightArg->Int32Value(vm));
2403     }
2404     if (!bottomArg->IsUndefined() && bottomArg->IsNumber()) {
2405         styleBottom = ConvertBorderStyle(bottomArg->Int32Value(vm));
2406     }
2407     if (!leftArg->IsUndefined() && leftArg->IsNumber()) {
2408         styleLeft = ConvertBorderStyle(leftArg->Int32Value(vm));
2409     }
2410 
2411     PushOuterBorderStyleVector(styleLeft, values);
2412     PushOuterBorderStyleVector(styleRight, values);
2413     PushOuterBorderStyleVector(styleTop, values);
2414     PushOuterBorderStyleVector(styleBottom, values);
2415 }
2416 
SetBorderWidthArray(const EcmaVM * vm,const Local<JSValueRef> & args,ArkUI_Float32 values[],int units[],int index)2417 void ArkTSUtils::SetBorderWidthArray(const EcmaVM* vm, const Local<JSValueRef>& args, ArkUI_Float32 values[],
2418     int units[], int index)
2419 {
2420     CalcDimension borderDimension;
2421     if (!args->IsUndefined()) {
2422         if (ArkTSUtils::ParseAllBorder(vm, args, borderDimension)) {
2423             values[index] = borderDimension.Value();
2424             units[index] = static_cast<int>(borderDimension.Unit());
2425         } else {
2426             values[index] = 0;
2427             units[index] = static_cast<int>(DimensionUnit::VP);
2428         }
2429     } else {
2430         values[index] = -1;
2431         units[index] = static_cast<int>(DimensionUnit::INVALID);
2432     }
2433 }
2434 
ParseJsToArkUISize(const EcmaVM * vm,const Local<JSValueRef> & arg,RefPtr<ResourceObject> & resObj)2435 ArkUISizeType ArkTSUtils::ParseJsToArkUISize(const EcmaVM *vm, const Local<JSValueRef> &arg,
2436     RefPtr<ResourceObject>& resObj)
2437 {
2438     ArkUISizeType size = { 0.0, static_cast<int8_t>(DimensionUnit::VP), nullptr };
2439     CalcDimension dimen(0, DimensionUnit::VP);
2440     if (ArkTSUtils::ParseJsDimensionVp(vm, arg, dimen, resObj)) {
2441         size.unit = static_cast<int8_t>(dimen.Unit());
2442         if (dimen.CalcValue() != "") {
2443             size.string = dimen.CalcValue().c_str();
2444         } else {
2445             size.value = dimen.Value();
2446         }
2447     }
2448     return size;
2449 }
2450 
CheckKeysPressed(const EcmaVM * vm,const std::vector<KeyCode> & pressedKeyCodes,std::vector<std::string> & checkKeyCodes)2451 bool ArkTSUtils::CheckKeysPressed(
2452     const EcmaVM* vm, const std::vector<KeyCode>& pressedKeyCodes, std::vector<std::string>& checkKeyCodes)
2453 {
2454     auto hasKeyCode = [pressedKeyCodes](const KeyCode& keyCode) -> bool {
2455         auto it = std::find(pressedKeyCodes.begin(), pressedKeyCodes.end(), keyCode);
2456         return it != pressedKeyCodes.end();
2457     };
2458     for (auto& checkKeyCode : checkKeyCodes) {
2459         if (checkKeyCode == "ctrl") {
2460             if (!hasKeyCode(KeyCode::KEY_CTRL_LEFT) && !hasKeyCode(KeyCode::KEY_CTRL_RIGHT)) {
2461                 return false;
2462             }
2463         } else if (checkKeyCode == "shift") {
2464             if (!hasKeyCode(KeyCode::KEY_SHIFT_LEFT) && !hasKeyCode(KeyCode::KEY_SHIFT_RIGHT)) {
2465                 return false;
2466             }
2467         } else if (checkKeyCode == "alt") {
2468             if (!hasKeyCode(KeyCode::KEY_ALT_LEFT) && !hasKeyCode(KeyCode::KEY_ALT_RIGHT)) {
2469                 return false;
2470             }
2471         } else if (checkKeyCode == "fn") {
2472             if (!hasKeyCode(KeyCode::KEY_FN)) {
2473                 return false;
2474             }
2475         } else {
2476             ThrowError(vm, "indicate the keys are illegal", ERROR_CODE_PARAM_INVALID);
2477             return false;
2478         }
2479     }
2480     return true;
2481 }
2482 
ThrowError(const EcmaVM * vm,const std::string & msg,int32_t code)2483 void ArkTSUtils::ThrowError(const EcmaVM* vm, const std::string& msg, int32_t code)
2484 {
2485     auto errorVal = panda::Exception::Error(vm, panda::StringRef::NewFromUtf8(vm, msg.c_str()));
2486     auto codeVal = panda::Exception::Error(vm, panda::StringRef::NewFromUtf8(vm, std::to_string(code).c_str()));
2487     Local<panda::StringRef> codeKey = panda::StringRef::NewFromUtf8(vm, "code");
2488     Local<panda::ObjectRef> errorObj(errorVal);
2489     errorObj->Set(vm, codeKey, codeVal);
2490     panda::JSNApi::ThrowException(vm, errorObj);
2491 }
2492 
GetModifierKeyState(ArkUIRuntimeCallInfo * info,const std::vector<KeyCode> & pressedKeyCodes)2493 Local<JSValueRef> ArkTSUtils::GetModifierKeyState(
2494     ArkUIRuntimeCallInfo* info, const std::vector<KeyCode>& pressedKeyCodes)
2495 {
2496     auto vm = info->GetVM();
2497     auto param = info->GetCallArgRef(0);
2498     if (!param->IsArray(vm)) {
2499         ThrowError(vm, "indicate the keys are illegal", ERROR_CODE_PARAM_INVALID);
2500         return JSValueRef::Undefined(vm);
2501     }
2502     std::vector<std::string> checkKeyCodes;
2503     std::vector<std::string> validKeyCodes = { "ctrl", "shift", "alt", "fn" };
2504     auto paramArray = panda::Local<panda::ArrayRef>(param);
2505     auto length = paramArray->Length(vm);
2506     for (size_t i = 0; i < length; i++) {
2507         auto value = panda::ArrayRef::GetValueAt(vm, paramArray, i);
2508         auto code = value->ToString(vm)->ToString(vm);
2509         std::transform(code.begin(), code.end(), code.begin(), [](char& c) { return std::tolower(c); });
2510         auto it = std::find(validKeyCodes.begin(), validKeyCodes.end(), code.c_str());
2511         if (it == validKeyCodes.end()) {
2512             ThrowError(vm, "indicate the keys are illegal", ERROR_CODE_PARAM_INVALID);
2513             return JSValueRef::Undefined(info->GetVM());
2514         } else {
2515             checkKeyCodes.emplace_back(code);
2516         }
2517     }
2518     if (checkKeyCodes.empty()) {
2519         ThrowError(vm, "indicate the keys are illegal", ERROR_CODE_PARAM_INVALID);
2520         return JSValueRef::Undefined(vm);
2521     }
2522     if (ArkTSUtils::CheckKeysPressed(vm, pressedKeyCodes, checkKeyCodes)) {
2523         return panda::BooleanRef::New(vm, true);
2524     } else {
2525         return panda::BooleanRef::New(vm, false);
2526     }
2527 }
2528 
JsGetModifierKeyState(ArkUIRuntimeCallInfo * info)2529 Local<JSValueRef> ArkTSUtils::JsGetModifierKeyState(ArkUIRuntimeCallInfo* info)
2530 {
2531     Local<JSValueRef> thisObj = info->GetThisRef();
2532     auto eventInfo = static_cast<BaseEventInfo*>(panda::Local<panda::ObjectRef>(thisObj)->GetNativePointerField(
2533         info->GetVM(), 0));
2534     if (!eventInfo) {
2535         return JSValueRef::Undefined(info->GetVM());
2536     }
2537     auto pressedKeyCodes = eventInfo->GetPressedKeyCodes();
2538     return ArkTSUtils::GetModifierKeyState(info, pressedKeyCodes);
2539 }
2540 
JsGetHorizontalAxisValue(ArkUIRuntimeCallInfo * info)2541 Local<JSValueRef> ArkTSUtils::JsGetHorizontalAxisValue(ArkUIRuntimeCallInfo* info)
2542 {
2543     Local<JSValueRef> thisObj = info->GetThisRef();
2544     auto eventInfo =
2545         static_cast<AxisInfo*>(panda::Local<panda::ObjectRef>(thisObj)->GetNativePointerField(info->GetVM(), 0));
2546     if (!eventInfo) {
2547         return JSValueRef::Undefined(info->GetVM());
2548     }
2549     return panda::NumberRef::New(info->GetVM(), eventInfo->GetHorizontalAxis());
2550 }
2551 
JsGetVerticalAxisValue(ArkUIRuntimeCallInfo * info)2552 Local<JSValueRef> ArkTSUtils::JsGetVerticalAxisValue(ArkUIRuntimeCallInfo* info)
2553 {
2554     Local<JSValueRef> thisObj = info->GetThisRef();
2555     auto eventInfo =
2556         static_cast<AxisInfo*>(panda::Local<panda::ObjectRef>(thisObj)->GetNativePointerField(info->GetVM(), 0));
2557     if (!eventInfo) {
2558         return JSValueRef::Undefined(info->GetVM());
2559     }
2560     return panda::NumberRef::New(info->GetVM(), eventInfo->GetVerticalAxis());
2561 }
2562 
IsDrawable(const EcmaVM * vm,const Local<JSValueRef> & jsValue)2563 bool ArkTSUtils::IsDrawable(const EcmaVM* vm, const Local<JSValueRef>& jsValue)
2564 {
2565     if (!jsValue->IsObject(vm)) {
2566         return false;
2567     }
2568     auto jsObj = jsValue->ToObject(vm);
2569     if (jsObj->IsUndefined()) {
2570         return false;
2571     }
2572 
2573     // if jsObject has function getPixelMap, it's a DrawableDescriptor object
2574     auto func = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "getPixelMap"));
2575     return (!func->IsNull() && func->IsFunction(vm));
2576 }
2577 
GetDrawablePixmap(const EcmaVM * vm,Local<JSValueRef> obj)2578 RefPtr<PixelMap> ArkTSUtils::GetDrawablePixmap(const EcmaVM* vm, Local<JSValueRef> obj)
2579 {
2580     return PixelMap::GetFromDrawable(UnwrapNapiValue(vm, obj));
2581 }
2582 
CreateRSBrightnessBlenderFromNapiValue(const EcmaVM * vm,Local<JSValueRef> obj)2583 Rosen::BrightnessBlender* ArkTSUtils::CreateRSBrightnessBlenderFromNapiValue(const EcmaVM* vm, Local<JSValueRef> obj)
2584 {
2585     auto blenderPtr = static_cast<Rosen::BrightnessBlender*>(UnwrapNapiValue(vm, obj));
2586     return blenderPtr;
2587 }
2588 
UnwrapNapiValue(const EcmaVM * vm,const Local<JSValueRef> & obj)2589 void* ArkTSUtils::UnwrapNapiValue(const EcmaVM* vm, const Local<JSValueRef>& obj)
2590 {
2591     if (!obj->IsObject(vm)) {
2592         LOGE("info is not an object when try CreateFromNapiValue");
2593         return nullptr;
2594     }
2595     auto engine = EngineHelper::GetCurrentEngine();
2596     CHECK_NULL_RETURN(engine, nullptr);
2597     auto nativeEngine = engine->GetNativeEngine();
2598     CHECK_NULL_RETURN(nativeEngine, nullptr);
2599     JSValueWrapper valueWrapper = obj;
2600 
2601     Framework::ScopeRAII scope(reinterpret_cast<napi_env>(nativeEngine));
2602     napi_value napiValue = nativeEngine->ValueToNapiValue(valueWrapper);
2603     auto env = reinterpret_cast<napi_env>(nativeEngine);
2604     napi_valuetype valueType = napi_undefined;
2605     napi_typeof(env, napiValue, &valueType);
2606     if (valueType != napi_object) {
2607         LOGE("napiValue is not napi_object");
2608         return nullptr;
2609     }
2610     void* objectNapi = nullptr;
2611     napi_unwrap(env, napiValue, &objectNapi);
2612     return objectNapi;
2613 }
2614 
2615 #if !defined(PREVIEW)
CreatePixelMapFromNapiValue(const EcmaVM * vm,Local<JSValueRef> obj)2616 RefPtr<PixelMap> ArkTSUtils::CreatePixelMapFromNapiValue(const EcmaVM* vm, Local<JSValueRef> obj)
2617 {
2618     if (!obj->IsObject(vm)) {
2619         return nullptr;
2620     }
2621     auto engine = EngineHelper::GetCurrentEngine();
2622     if (!engine) {
2623         return nullptr;
2624     }
2625     auto* nativeEngine = engine->GetNativeEngine();
2626     if (nativeEngine == nullptr) {
2627         return nullptr;
2628     }
2629     JSValueWrapper valueWrapper = obj;
2630 
2631     Framework::ScopeRAII scope(reinterpret_cast<napi_env>(nativeEngine));
2632     napi_value napiValue = nativeEngine->ValueToNapiValue(valueWrapper);
2633 
2634     Framework::PixelMapNapiEntry pixelMapNapiEntry = Framework::JsEngine::GetPixelMapNapiEntry();
2635     if (!pixelMapNapiEntry) {
2636         return nullptr;
2637     }
2638 
2639     void* pixmapPtrAddr = pixelMapNapiEntry(reinterpret_cast<napi_env>(nativeEngine), napiValue);
2640     if (pixmapPtrAddr == nullptr) {
2641         return nullptr;
2642     }
2643     return PixelMap::CreatePixelMap(pixmapPtrAddr);
2644 }
2645 #endif
2646 
ParseSelectionMenuOptions(ArkUIRuntimeCallInfo * info,const EcmaVM * vm,NG::OnCreateMenuCallback & onCreateMenuCallback,NG::OnMenuItemClickCallback & onMenuItemClickCallback,NG::OnPrepareMenuCallback & onPrepareMenuCallback)2647 bool ArkTSUtils::ParseSelectionMenuOptions(ArkUIRuntimeCallInfo* info, const EcmaVM* vm,
2648     NG::OnCreateMenuCallback& onCreateMenuCallback, NG::OnMenuItemClickCallback& onMenuItemClickCallback,
2649     NG::OnPrepareMenuCallback& onPrepareMenuCallback)
2650 {
2651     Local<JSValueRef> firstArg = info->GetCallArgRef(NUM_0);
2652     Local<JSValueRef> secondArg = info->GetCallArgRef(NUM_1);
2653     if (!secondArg->IsObject(vm) || secondArg->IsUndefined()) {
2654         return false;
2655     }
2656     auto* nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
2657     auto* frameNode = reinterpret_cast<FrameNode*>(nativeNode);
2658     CHECK_NULL_RETURN(frameNode, false);
2659     auto menuOptionsObject = secondArg->ToObject(vm);
2660     auto jsValueOnCreateMenu = menuOptionsObject->Get(vm, panda::StringRef::NewFromUtf8(vm, "onCreateMenu"));
2661     ParseOnCreateMenu(vm, frameNode, jsValueOnCreateMenu, onCreateMenuCallback);
2662     auto jsValueOnMenuItemClick = menuOptionsObject->Get(vm, panda::StringRef::NewFromUtf8(vm, "onMenuItemClick"));
2663     ParseOnMenuItemClick(vm, frameNode, jsValueOnMenuItemClick, onMenuItemClickCallback);
2664     auto jsValueOnPrepareMenu = menuOptionsObject->Get(vm, panda::StringRef::NewFromUtf8(vm, "onPrepareMenu"));
2665     ParseOnPrepareMenu(vm, frameNode, jsValueOnPrepareMenu, onPrepareMenuCallback);
2666     return true;
2667 }
2668 
CreateJsSystemMenuItems(const EcmaVM * vm,const std::vector<NG::MenuItemParam> & systemMenuItems)2669 Local<panda::ArrayRef> ArkTSUtils::CreateJsSystemMenuItems(
2670     const EcmaVM* vm, const std::vector<NG::MenuItemParam>& systemMenuItems)
2671 {
2672     Local<panda::ArrayRef> systemMenuItemsArray = panda::ArrayRef::New(vm);
2673     uint32_t idx = 0;
2674     for (const auto& item : systemMenuItems) {
2675         systemMenuItemsArray->SetValueAt(vm, systemMenuItemsArray, idx++, CreateJsTextMenuItem(vm, item));
2676     }
2677     return systemMenuItemsArray;
2678 }
2679 
CreateJsTextMenuItem(const EcmaVM * vm,const NG::MenuItemParam & menuItemParam)2680 Local<panda::ObjectRef> ArkTSUtils::CreateJsTextMenuItem(const EcmaVM* vm, const NG::MenuItemParam& menuItemParam)
2681 {
2682     Local<panda::ObjectRef> obj = CreateJsTextMenuId(vm, menuItemParam.menuOptionsParam.id);
2683     const char* keys[] = { "content", "id", "labelInfo", "icon" };
2684     auto hasSymbol =
2685         menuItemParam.menuOptionsParam.symbolId.has_value() && menuItemParam.menuOptionsParam.symbolId.value() != 0;
2686     auto contentRef = panda::StringRef::NewFromUtf8(vm, menuItemParam.menuOptionsParam.content.value_or("").c_str());
2687     auto labelRef = panda::StringRef::NewFromUtf8(vm, menuItemParam.menuOptionsParam.labelInfo.value_or("").c_str());
2688     if (hasSymbol) {
2689         Local<JSValueRef> values[] = { contentRef, obj, labelRef,
2690             panda::NumberRef::New(vm, menuItemParam.menuOptionsParam.symbolId.value()) };
2691         return panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
2692     }
2693     Local<JSValueRef> values[] = { contentRef, obj, labelRef,
2694         panda::StringRef::NewFromUtf8(vm, menuItemParam.menuOptionsParam.icon.value_or("").c_str()) };
2695     return panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
2696 }
2697 
CreateJsTextMenuId(const EcmaVM * vm,const std::string & id)2698 Local<panda::ObjectRef> ArkTSUtils::CreateJsTextMenuId(const EcmaVM* vm, const std::string& id)
2699 {
2700     Local<panda::ObjectRef> empty = panda::ObjectRef::New(vm);
2701     auto engine = EngineHelper::GetCurrentEngine();
2702     CHECK_NULL_RETURN(engine, empty);
2703     NativeEngine* nativeEngine = engine->GetNativeEngine();
2704     CHECK_NULL_RETURN(nativeEngine, empty);
2705     auto env = reinterpret_cast<napi_env>(nativeEngine);
2706 
2707     napi_value global = nullptr;
2708     napi_status ret = napi_get_global(env, &global);
2709     if (ret != napi_ok) {
2710         return empty;
2711     }
2712     napi_value constructor = nullptr;
2713     ret = napi_get_named_property(env, global, JS_TEXT_MENU_ID_CLASS_NAME, &constructor);
2714     if (ret != napi_ok) {
2715         return empty;
2716     }
2717 
2718     napi_value obj = nullptr;
2719     napi_value menuId = nullptr;
2720 
2721     ret = napi_create_string_utf8(env, id.c_str(), id.length(), &menuId);
2722     if (ret != napi_ok) {
2723         return empty;
2724     }
2725     ret = napi_new_instance(env, constructor, NUM_1, &menuId, &obj);
2726     if (ret != napi_ok) {
2727         return empty;
2728     }
2729 
2730     auto value = Framework::JsConverter::ConvertNapiValueToJsVal(obj);
2731     if (!value->IsObject()) {
2732         return empty;
2733     }
2734 
2735     return value->GetLocalHandle();
2736 }
2737 
ParseOnCreateMenu(const EcmaVM * vm,FrameNode * frameNode,const Local<JSValueRef> & jsValueOnCreateMenu,NG::OnCreateMenuCallback & onCreateMenuCallback)2738 void ArkTSUtils::ParseOnCreateMenu(const EcmaVM* vm, FrameNode* frameNode, const Local<JSValueRef>& jsValueOnCreateMenu,
2739     NG::OnCreateMenuCallback& onCreateMenuCallback)
2740 {
2741     if (jsValueOnCreateMenu.IsEmpty() || !jsValueOnCreateMenu->IsFunction(vm)) {
2742         return;
2743     }
2744     panda::Local<panda::FunctionRef> func = jsValueOnCreateMenu->ToObject(vm);
2745     auto containerId = Container::CurrentId();
2746     auto jsCallback = [vm, node = AceType::WeakClaim(frameNode), func = panda::CopyableGlobal(vm, func), containerId](
2747                           const std::vector<NG::MenuItemParam>& systemMenuItems) -> std::vector<NG::MenuOptionsParam> {
2748         ContainerScope scope(containerId);
2749         panda::LocalScope pandaScope(vm);
2750         panda::TryCatch trycatch(vm);
2751         PipelineContext::SetCallBackNode(node);
2752         std::vector<NG::MenuOptionsParam> menuParams;
2753         auto textMenuItemArrayObj = CreateJsSystemMenuItems(vm, systemMenuItems);
2754         panda::Local<panda::JSValueRef> params[PARAM_ARR_LENGTH_1] = { textMenuItemArrayObj };
2755         auto menuItems = func->Call(vm, func.ToLocal(), params, PARAM_ARR_LENGTH_1);
2756         if (!menuItems->IsArray(vm)) {
2757             return menuParams;
2758         }
2759         WrapMenuParams(vm, menuParams, menuItems, true);
2760         return menuParams;
2761     };
2762     onCreateMenuCallback = jsCallback;
2763 }
2764 
ParseOnPrepareMenu(const EcmaVM * vm,FrameNode * frameNode,const Local<JSValueRef> & jsValueOnPrepareMenu,NG::OnPrepareMenuCallback & onPrepareMenuCallback)2765 void ArkTSUtils::ParseOnPrepareMenu(const EcmaVM* vm, FrameNode* frameNode,
2766     const Local<JSValueRef>& jsValueOnPrepareMenu, NG::OnPrepareMenuCallback& onPrepareMenuCallback)
2767 {
2768     if (jsValueOnPrepareMenu.IsEmpty() || !jsValueOnPrepareMenu->IsFunction(vm)) {
2769         return;
2770     }
2771     panda::Local<panda::FunctionRef> func = jsValueOnPrepareMenu->ToObject(vm);
2772     auto containerId = Container::CurrentId();
2773     auto jsCallback = [vm, node = AceType::WeakClaim(frameNode), func = panda::CopyableGlobal(vm, func), containerId](
2774                           const std::vector<NG::MenuItemParam>& systemMenuItems) -> std::vector<NG::MenuOptionsParam> {
2775         ContainerScope scope(containerId);
2776         panda::LocalScope pandaScope(vm);
2777         panda::TryCatch trycatch(vm);
2778         PipelineContext::SetCallBackNode(node);
2779         std::vector<NG::MenuOptionsParam> menuParams;
2780         auto textMenuItemArrayObj = CreateJsSystemMenuItems(vm, systemMenuItems);
2781         panda::Local<panda::JSValueRef> params[PARAM_ARR_LENGTH_1] = { textMenuItemArrayObj };
2782         auto menuItems = func->Call(vm, func.ToLocal(), params, PARAM_ARR_LENGTH_1);
2783         if (!menuItems->IsArray(vm)) {
2784             return menuParams;
2785         }
2786         WrapMenuParams(vm, menuParams, menuItems, true);
2787         return menuParams;
2788     };
2789     onPrepareMenuCallback = jsCallback;
2790 }
2791 
ParseMenuItemsSymbolId(const EcmaVM * vm,const Local<JSValueRef> & jsStartIcon,NG::MenuOptionsParam & menuOptionsParam)2792 void ArkTSUtils::ParseMenuItemsSymbolId(
2793     const EcmaVM* vm, const Local<JSValueRef>& jsStartIcon, NG::MenuOptionsParam& menuOptionsParam)
2794 {
2795     if (StringToMenuItemType(menuOptionsParam.id) == MenuItemType::UNKNOWN) {
2796         uint32_t symbolId = 0;
2797         RefPtr<ResourceObject> resourceObject;
2798         if (jsStartIcon->IsNumber()) {
2799             symbolId = jsStartIcon->ToNumber(vm)->Value();
2800             menuOptionsParam.symbolId = symbolId;
2801             return;
2802         }
2803         if (ParseJsSymbolId(vm, jsStartIcon, symbolId, resourceObject)) {
2804             menuOptionsParam.symbolId = symbolId;
2805         }
2806     } else {
2807         UpdateInfoById(menuOptionsParam, menuOptionsParam.id);
2808     }
2809 }
2810 
WrapMenuParams(const EcmaVM * vm,std::vector<NG::MenuOptionsParam> & menuParams,const Local<JSValueRef> & menuItems,bool enableLabelInfo)2811 void ArkTSUtils::WrapMenuParams(const EcmaVM* vm, std::vector<NG::MenuOptionsParam>& menuParams,
2812     const Local<JSValueRef>& menuItems, bool enableLabelInfo)
2813 {
2814     auto menuItemsArray = Local<panda::ArrayRef>(menuItems);
2815     auto length = menuItemsArray->Length(vm);
2816     for (uint32_t index = 0; index < length; index++) {
2817         Local<JSValueRef> menuItem = panda::ArrayRef::GetValueAt(vm, menuItemsArray, index);
2818         if (!menuItem->IsObject(vm)) {
2819             continue;
2820         }
2821         auto menuItemObject = menuItem->ToObject(vm);
2822         NG::MenuOptionsParam menuOptionsParam;
2823         auto jsContent = menuItemObject->Get(vm, panda::StringRef::NewFromUtf8(vm, "content"));
2824         std::string content;
2825         ParseJsString(vm, jsContent, content);
2826         menuOptionsParam.content = content;
2827         auto jsStartIcon = menuItemObject->Get(vm, panda::StringRef::NewFromUtf8(vm, "icon"));
2828         std::string icon;
2829         ParseJsMedia(vm, jsStartIcon, icon);
2830         menuOptionsParam.icon = icon;
2831         ParseMenuItemsSymbolId(vm, jsStartIcon, menuOptionsParam);
2832         auto jsTextMenuId = menuItemObject->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
2833         std::string id;
2834         if (jsTextMenuId->IsObject(vm)) {
2835             auto textMenuIdObject = jsTextMenuId->ToObject(vm);
2836             auto jsId = textMenuIdObject->Get(vm, panda::StringRef::NewFromUtf8(vm, "id_"));
2837             ParseJsString(vm, jsId, id);
2838         }
2839         menuOptionsParam.id = id;
2840         if (enableLabelInfo) {
2841             auto jsLabelInfo = menuItemObject->Get(vm, panda::StringRef::NewFromUtf8(vm, "labelInfo"));
2842             std::string labelInfo;
2843             ParseJsString(vm, jsLabelInfo, labelInfo);
2844             menuOptionsParam.labelInfo = labelInfo;
2845         }
2846         UpdateInfoById(menuOptionsParam, menuOptionsParam.id);
2847         menuParams.emplace_back(menuOptionsParam);
2848     }
2849 }
2850 
ParseOnMenuItemClick(const EcmaVM * vm,FrameNode * frameNode,const Local<JSValueRef> & jsValueOnMenuItemClick,NG::OnMenuItemClickCallback & onMenuItemClickCallback)2851 void ArkTSUtils::ParseOnMenuItemClick(const EcmaVM* vm, FrameNode* frameNode,
2852     const Local<JSValueRef>& jsValueOnMenuItemClick, NG::OnMenuItemClickCallback& onMenuItemClickCallback)
2853 {
2854     if (jsValueOnMenuItemClick.IsEmpty() || !jsValueOnMenuItemClick->IsFunction(vm)) {
2855         return;
2856     }
2857     panda::Local<panda::FunctionRef> func = jsValueOnMenuItemClick->ToObject(vm);
2858     auto containerId = Container::CurrentId();
2859     auto jsCallback = [vm, node = AceType::WeakClaim(frameNode), func = panda::CopyableGlobal(vm, func), containerId](
2860                           const NG::MenuItemParam& menuOptionsParam) -> bool {
2861         ContainerScope scope(containerId);
2862         panda::LocalScope pandaScope(vm);
2863         panda::TryCatch trycatch(vm);
2864         PipelineContext::SetCallBackNode(node);
2865         auto paramArrayObj = CreateJsOnMenuItemClick(vm, menuOptionsParam);
2866         if (paramArrayObj->Length(vm) != PARAM_ARR_LENGTH_2) {
2867             return false;
2868         }
2869         panda::Local<panda::JSValueRef> params[PARAM_ARR_LENGTH_2] = {
2870             panda::ArrayRef::GetValueAt(vm, paramArrayObj, 0), panda::ArrayRef::GetValueAt(vm, paramArrayObj, 1)
2871         };
2872         auto ret = func->Call(vm, func.ToLocal(), params, PARAM_ARR_LENGTH_2);
2873         if (ret->IsBoolean()) {
2874             return ret->ToBoolean(vm)->Value();
2875         }
2876         return false;
2877     };
2878     onMenuItemClickCallback = jsCallback;
2879 }
2880 
CreateJsOnMenuItemClick(const EcmaVM * vm,const NG::MenuItemParam & menuItemParam)2881 Local<panda::ArrayRef> ArkTSUtils::CreateJsOnMenuItemClick(const EcmaVM* vm, const NG::MenuItemParam& menuItemParam)
2882 {
2883     Local<panda::ArrayRef> paramsArray = panda::ArrayRef::New(vm);
2884     paramsArray->SetValueAt(vm, paramsArray, 0, CreateJsTextMenuItem(vm, menuItemParam));
2885     paramsArray->SetValueAt(vm, paramsArray, 1, CreateJsTextRange(vm, menuItemParam));
2886     return paramsArray;
2887 }
2888 
CreateJsTextRange(const EcmaVM * vm,const NG::MenuItemParam & menuItemParam)2889 Local<panda::ObjectRef> ArkTSUtils::CreateJsTextRange(const EcmaVM* vm, const NG::MenuItemParam& menuItemParam)
2890 {
2891     const char* keys[] = { "start", "end" };
2892     Local<JSValueRef> values[] = { panda::NumberRef::New(vm, menuItemParam.start),
2893         panda::NumberRef::New(vm, menuItemParam.end) };
2894     return panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
2895 }
2896 
ChoosePointToJSValue(const EcmaVM * vm,std::vector<int> input)2897 Local<panda::ArrayRef> ArkTSUtils::ChoosePointToJSValue(const EcmaVM* vm, std::vector<int> input)
2898 {
2899     Local<panda::ArrayRef> arr = panda::ArrayRef::New(vm);
2900     for (size_t i = 0; i < input.size(); i++) {
2901         arr->SetValueAt(vm, arr, i, ToJSValueWithVM(vm, input[i]));
2902     }
2903     return arr;
2904 }
2905 
ParseJsAngle(const EcmaVM * vm,const Local<JSValueRef> & value,std::optional<float> & angle)2906 void ArkTSUtils::ParseJsAngle(const EcmaVM *vm, const Local<JSValueRef> &value, std::optional<float> &angle)
2907 {
2908     if (value->IsNumber()) {
2909         angle = static_cast<float>(value->ToNumber(vm)->Value());
2910         return;
2911     }
2912     if (value->IsString(vm)) {
2913         angle = static_cast<float>(StringUtils::StringToDegree(value->ToString(vm)->ToString(vm)));
2914         return;
2915     }
2916     return;
2917 }
2918 
ParseJsInt32(const EcmaVM * vm,const Local<JSValueRef> & value,int32_t & result)2919 bool ArkTSUtils::ParseJsInt32(const EcmaVM *vm, const Local<JSValueRef> &value, int32_t &result)
2920 {
2921     if (value->IsNumber()) {
2922         result = value->Int32Value(vm);
2923         return true;
2924     }
2925     if (value->IsString(vm)) {
2926         result = StringUtils::StringToInt(value->ToString(vm)->ToString(vm));
2927         return true;
2928     }
2929 
2930     return false;
2931 }
2932 
ParseJsIgnoresLayoutSafeAreaEdges(const EcmaVM * vm,const Local<JSValueRef> & value,std::vector<ArkUI_Int32> & edges)2933 bool ArkTSUtils::ParseJsIgnoresLayoutSafeAreaEdges(
2934     const EcmaVM* vm, const Local<JSValueRef>& value, std::vector<ArkUI_Int32>& edges)
2935 {
2936     if (!value->IsArray(vm)) {
2937         return false;
2938     }
2939     auto array = panda::Local<panda::ArrayRef>(value);
2940     auto length = array->Length(vm);
2941     for (uint32_t index = 0; index < length; index++) {
2942         auto item = panda::ArrayRef::GetValueAt(vm, array, index);
2943         ArkUI_Int32 edge;
2944         if (!ArkTSUtils::ParseJsInt32(vm, item, edge)) {
2945             return false;
2946         }
2947         edges.push_back(edge);
2948     }
2949     return true;
2950 }
2951 
ParseGradientCenter(const EcmaVM * vm,const Local<JSValueRef> & value,std::vector<ArkUIInt32orFloat32> & values)2952 void ArkTSUtils::ParseGradientCenter(
2953     const EcmaVM* vm, const Local<JSValueRef>& value, std::vector<ArkUIInt32orFloat32>& values)
2954 {
2955     std::vector<RefPtr<ResourceObject>> vectorResObj;
2956     ArkTSUtils::ParseGradientCenter(vm, value, values, vectorResObj);
2957 }
2958 
ParseGradientCenter(const EcmaVM * vm,const Local<JSValueRef> & value,std::vector<ArkUIInt32orFloat32> & values,std::vector<RefPtr<ResourceObject>> & vectorResObj)2959 void ArkTSUtils::ParseGradientCenter(const EcmaVM* vm, const Local<JSValueRef>& value,
2960     std::vector<ArkUIInt32orFloat32>& values, std::vector<RefPtr<ResourceObject>>& vectorResObj)
2961 {
2962     bool hasValueX = false;
2963     bool hasValueY = false;
2964     CalcDimension valueX;
2965     CalcDimension valueY;
2966     if (value->IsArray(vm)) {
2967         auto array = panda::Local<panda::ArrayRef>(value);
2968         auto length = array->Length(vm);
2969         if (length == NUM_2) {
2970             RefPtr<ResourceObject> xResObj;
2971             RefPtr<ResourceObject> yResObj;
2972             hasValueX =
2973                 ArkTSUtils::ParseJsDimensionVp(vm, panda::ArrayRef::GetValueAt(vm, array, NUM_0), valueX,
2974                 xResObj, false);
2975             hasValueY =
2976                 ArkTSUtils::ParseJsDimensionVp(vm, panda::ArrayRef::GetValueAt(vm, array, NUM_1), valueY,
2977                 yResObj, false);
2978             if (xResObj) {
2979                 vectorResObj.push_back(xResObj);
2980             } else {
2981                 vectorResObj.push_back(nullptr);
2982             }
2983             if (yResObj) {
2984                 vectorResObj.push_back(yResObj);
2985             } else {
2986                 vectorResObj.push_back(nullptr);
2987             }
2988         }
2989     }
2990     values.push_back({.i32 = static_cast<ArkUI_Int32>(hasValueX)});
2991     values.push_back({.f32 = static_cast<ArkUI_Float32>(valueX.Value())});
2992     values.push_back({.i32 = static_cast<ArkUI_Int32>(valueX.Unit())});
2993     values.push_back({.i32 = static_cast<ArkUI_Int32>(hasValueY)});
2994     values.push_back({.f32 = static_cast<ArkUI_Float32>(valueY.Value())});
2995     values.push_back({.i32 = static_cast<ArkUI_Int32>(valueY.Unit())});
2996 }
2997 
ParseGradientColorStops(const EcmaVM * vm,const Local<JSValueRef> & value,std::vector<ArkUIInt32orFloat32> & colors,std::vector<RefPtr<ResourceObject>> & vectorResObj,const NodeInfo & nodeInfo)2998 void ArkTSUtils::ParseGradientColorStops(const EcmaVM *vm, const Local<JSValueRef>& value,
2999     std::vector<ArkUIInt32orFloat32>& colors, std::vector<RefPtr<ResourceObject>>& vectorResObj,
3000     const NodeInfo& nodeInfo)
3001 {
3002     if (!value->IsArray(vm)) {
3003         return;
3004     }
3005     auto array = panda::Local<panda::ArrayRef>(value);
3006     auto length = array->Length(vm);
3007     for (uint32_t index = 0; index < length; index++) {
3008         auto item = panda::ArrayRef::GetValueAt(vm, array, index);
3009         if (!item->IsArray(vm)) {
3010             continue;
3011         }
3012         auto itemArray = panda::Local<panda::ArrayRef>(item);
3013         auto itemLength = itemArray->Length(vm);
3014         if (itemLength < NUM_1) {
3015             continue;
3016         }
3017         Color color;
3018         auto colorParams = panda::ArrayRef::GetValueAt(vm, itemArray, NUM_0);
3019         RefPtr<ResourceObject> resObj;
3020         if (!ArkTSUtils::ParseJsColorAlpha(vm, colorParams, color, resObj, nodeInfo)) {
3021             continue;
3022         }
3023         if (SystemProperties::ConfigChangePerform()) {
3024             if (resObj) {
3025                 vectorResObj.push_back(resObj);
3026             } else {
3027                 vectorResObj.push_back(nullptr);
3028             }
3029         }
3030         bool hasDimension = false;
3031         double dimension = 0.0;
3032         if (itemLength > NUM_1) {
3033             auto stopDimension = panda::ArrayRef::GetValueAt(vm, itemArray, NUM_1);
3034             if (ArkTSUtils::ParseJsDouble(vm, stopDimension, dimension)) {
3035                 hasDimension = true;
3036             }
3037         }
3038         colors.push_back({.u32 = static_cast<ArkUI_Uint32>(color.GetValue())});
3039         colors.push_back({.i32 = static_cast<ArkUI_Int32>(hasDimension)});
3040         colors.push_back({.f32 = static_cast<ArkUI_Float32>(dimension)});
3041     }
3042 }
3043 
ParseGradientColorStops(const EcmaVM * vm,const Local<JSValueRef> & value,std::vector<ArkUIInt32orFloat32> & colors)3044 void ArkTSUtils::ParseGradientColorStops(
3045     const EcmaVM* vm, const Local<JSValueRef>& value, std::vector<ArkUIInt32orFloat32>& colors)
3046 {
3047     std::vector<RefPtr<ResourceObject>> vectorResObj;
3048     NodeInfo nodeInfo = { "", ColorMode::COLOR_MODE_UNDEFINED };
3049     ArkTSUtils::ParseGradientColorStops(vm, value, colors, vectorResObj, nodeInfo);
3050 }
3051 
ParseGradientAngle(const EcmaVM * vm,const Local<JSValueRef> & value,std::vector<ArkUIInt32orFloat32> & values)3052 void ArkTSUtils::ParseGradientAngle(
3053     const EcmaVM* vm, const Local<JSValueRef>& value, std::vector<ArkUIInt32orFloat32>& values)
3054 {
3055     std::optional<float> degree;
3056     ParseJsAngle(vm, value, degree);
3057     auto angleHasValue = degree.has_value();
3058     auto angleValue = angleHasValue ? degree.value() : 0.0f;
3059     degree.reset();
3060     values.push_back({ .i32 = static_cast<ArkUI_Int32>(angleHasValue) });
3061     values.push_back({ .f32 = static_cast<ArkUI_Float32>(angleValue) });
3062 }
3063 } // namespace OHOS::Ace::NG
3064