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