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 "frameworks/core/components/declaration/common/declaration.h"
19 #include "frameworks/core/common/resource/resource_manager.h"
20 #include "frameworks/base/utils/system_properties.h"
21 #include "frameworks/core/common/resource/resource_wrapper.h"
22 #include "frameworks/core/common/resource/resource_object.h"
23 #include "frameworks/core/components/theme/theme_constants.h"
24 #include "ecmascript/napi/include/jsnapi.h"
25 #include "frameworks/core/common/card_scope.h"
26
27 namespace OHOS::Ace::NG {
28 const std::regex RESOURCE_APP_STRING_PLACEHOLDER(R"(\%((\d+)(\$)){0,1}([dsf]))", std::regex::icase);
29 const std::regex FLOAT_PATTERN(R"(-?(0|[1-9]\d*)(\.\d+))", std::regex::icase);
30 constexpr uint32_t COLOR_ALPHA_OFFSET = 24;
31 constexpr uint32_t COLOR_ALPHA_VALUE = 0xFF000000;
32 const std::string DEFAULT_STR = "-1";
33 constexpr int32_t REPLACEHOLDER_INDEX = 2;
34 enum class ResourceType : uint32_t {
35 COLOR = 10001,
36 FLOAT,
37 STRING,
38 PLURAL,
39 BOOLEAN,
40 INTARRAY,
41 INTEGER,
42 PATTERN,
43 STRARRAY,
44 MEDIA = 20000,
45 RAWFILE = 30000
46 };
47
ColorAlphaAdapt(uint32_t origin)48 uint32_t ArkTSUtils::ColorAlphaAdapt(uint32_t origin)
49 {
50 uint32_t result = origin;
51 if ((origin >> COLOR_ALPHA_OFFSET) == 0) {
52 result = origin | COLOR_ALPHA_VALUE;
53 }
54 return result;
55 }
56
ParseJsColor(const EcmaVM * vm,const Local<JSValueRef> & value,Color & result)57 bool ArkTSUtils::ParseJsColor(const EcmaVM* vm, const Local<JSValueRef>& value, Color& result)
58 {
59 if (value->IsNumber()) {
60 result = Color(value->Uint32Value(vm));
61 return true;
62 }
63 if (value->IsString()) {
64 return Color::ParseColorString(value->ToString(vm)->ToString(), result);
65 }
66 if (value->IsObject()) {
67 auto obj = value->ToObject(vm);
68 auto resId = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
69 if (!resId->IsNumber()) {
70 return false;
71 }
72 return ParseJsColorFromResource(vm, value, result);
73 }
74 return false;
75 }
76
ParseJsColorAlpha(const EcmaVM * vm,const Local<JSValueRef> & value,Color & result)77 bool ArkTSUtils::ParseJsColorAlpha(const EcmaVM* vm, const Local<JSValueRef>& value, Color& result)
78 {
79 if (value->IsNumber()) {
80 result = Color(ColorAlphaAdapt(value->Uint32Value(vm)));
81 return true;
82 }
83 if (value->IsString()) {
84 return Color::ParseColorString(value->ToString(vm)->ToString(), result);
85 }
86 if (value->IsObject()) {
87 return ParseJsColorFromResource(vm, value, result);
88 }
89 return false;
90 }
91
ToString(const EcmaVM * vm,Local<JSValueRef> & jsVal)92 std::string ToString(const EcmaVM* vm, Local<JSValueRef>& jsVal)
93 {
94 panda::LocalScope scope(vm);
95 if (jsVal->IsObject()) {
96 return panda::JSON::Stringify(vm, jsVal)->ToString(vm)->ToString();
97 }
98 return jsVal->ToString(vm)->ToString();
99 }
100
GetResourceObject(const EcmaVM * vm,const Local<JSValueRef> & jsObj)101 RefPtr<ResourceObject> GetResourceObject(const EcmaVM* vm, const Local<JSValueRef>& jsObj)
102 {
103 auto obj = jsObj->ToObject(vm);
104 auto id = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"))->Int32Value(vm);
105 auto type = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "type"))->Int32Value(vm);
106 auto args = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "params"));
107
108 std::string bundleName;
109 std::string moduleName;
110 auto bundle = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "bundleName"));
111 auto module = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "moduleName"));
112 if (bundle->IsString() && module->IsString()) {
113 bundleName = bundle->ToString(vm)->ToString();
114 moduleName = module->ToString(vm)->ToString();
115 }
116
117 Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
118 std::vector<ResourceObjectParams> resObjParamsList;
119 auto size = static_cast<int32_t>(params->Length(vm));
120 for (int32_t i = 0; i < size; i++) {
121 auto item = panda::ArrayRef::GetValueAt(vm, params, i);
122
123 std::string valueString = ToString(vm, item).c_str();
124
125 ResourceObjectParams resObjParams { .value = valueString };
126 if (item->IsString()) {
127 resObjParams.type = ResourceObjectParamType::STRING;
128 } else if (item->IsNumber()) {
129 if (std::regex_match(item->ToString(vm)->ToString(), FLOAT_PATTERN)) {
130 resObjParams.type = OHOS::Ace::ResourceObjectParamType::FLOAT;
131 } else {
132 resObjParams.type = OHOS::Ace::ResourceObjectParamType::INT;
133 }
134 }
135 resObjParamsList.push_back(resObjParams);
136 }
137 auto resourceObject = AceType::MakeRefPtr<ResourceObject>(id, type, resObjParamsList, bundleName, moduleName);
138 return resourceObject;
139 }
140
GetThemeConstants(const EcmaVM * vm,const Local<JSValueRef> & jsObj)141 RefPtr<OHOS::Ace::ThemeConstants> GetThemeConstants(const EcmaVM* vm, const Local<JSValueRef>& jsObj)
142 {
143 std::string bundleName;
144 std::string moduleName;
145 if (!jsObj->IsUndefined()) {
146 auto obj = jsObj->ToObject(vm);
147 auto bundle = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "bundleName"));
148 auto module = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "moduleName"));
149 if (bundle->IsString() && module->IsString()) {
150 bundleName = bundle->ToString(vm)->ToString();
151 moduleName = module->ToString(vm)->ToString();
152 }
153 }
154
155 auto cardId = CardScope::CurrentId();
156 if (cardId != OHOS::Ace::INVALID_CARD_ID) {
157 auto container = Container::Current();
158 auto weak = container->GetCardPipeline(cardId);
159 auto cardPipelineContext = weak.Upgrade();
160 CHECK_NULL_RETURN(cardPipelineContext, nullptr);
161 auto cardThemeManager = cardPipelineContext->GetThemeManager();
162 CHECK_NULL_RETURN(cardThemeManager, nullptr);
163 return cardThemeManager->GetThemeConstants(bundleName, moduleName);
164 }
165
166 auto container = Container::Current();
167 CHECK_NULL_RETURN(container, nullptr);
168 auto pipelineContext = container->GetPipelineContext();
169 CHECK_NULL_RETURN(pipelineContext, nullptr);
170 auto themeManager = pipelineContext->GetThemeManager();
171 CHECK_NULL_RETURN(themeManager, nullptr);
172 return themeManager->GetThemeConstants(bundleName, moduleName);
173 }
174
CreateResourceWrapper(const EcmaVM * vm,const Local<JSValueRef> & jsObj,RefPtr<ResourceObject> & resourceObject)175 RefPtr<ResourceWrapper> CreateResourceWrapper(const EcmaVM* vm, const Local<JSValueRef>& jsObj,
176 RefPtr<ResourceObject>& resourceObject)
177 {
178 RefPtr<ResourceAdapter> resourceAdapter = nullptr;
179 RefPtr<ThemeConstants> themeConstants = nullptr;
180 if (SystemProperties::GetResourceDecoupling()) {
181 resourceAdapter = ResourceManager::GetInstance().GetOrCreateResourceAdapter(resourceObject);
182 if (!resourceAdapter) {
183 return nullptr;
184 }
185 } else {
186 themeConstants = GetThemeConstants(vm, jsObj);
187 if (!themeConstants) {
188 return nullptr;
189 }
190 }
191 auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
192 return resourceWrapper;
193 }
194
IsGetResourceByName(const EcmaVM * vm,const Local<JSValueRef> & jsObj)195 bool IsGetResourceByName(const EcmaVM* vm, const Local<JSValueRef>& jsObj)
196 {
197 auto obj = jsObj->ToObject(vm);
198 auto args = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "params"));
199 if (!args->IsArray(vm)) {
200 return false;
201 }
202 auto bundleName = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "bundleName"));
203 auto moduleName = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "moduleName"));
204 if (!bundleName->IsString() || !moduleName->IsString()) {
205 return false;
206 }
207 if (!bundleName->ToString(vm)->ToString().empty() || !moduleName->ToString(vm)->ToString().empty()) {
208 return false;
209 }
210 Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
211 if (params->Length(vm) == 0) {
212 return false;
213 }
214 return true;
215 }
216
217
ParseJsColorFromResource(const EcmaVM * vm,const Local<JSValueRef> & jsObj,Color & result)218 bool ArkTSUtils::ParseJsColorFromResource(const EcmaVM* vm, const Local<JSValueRef>& jsObj, Color& result)
219 {
220 auto obj = jsObj ->ToObject(vm);
221 auto resId = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
222 if (!resId->IsNumber()) {
223 return false;
224 }
225
226 auto resourceObject = GetResourceObject(vm, jsObj);
227 auto resourceWrapper = CreateResourceWrapper(vm, jsObj, resourceObject);
228 if (!resourceWrapper) {
229 return false;
230 }
231
232 auto resIdNum = resId->Int32Value(vm);
233 if (resIdNum == -1) {
234 if (!IsGetResourceByName(vm, jsObj)) {
235 return false;
236 }
237 auto args = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "params"));
238 if (!args->IsArray(vm)) {
239 return false;
240 }
241 Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
242 auto param = panda::ArrayRef::GetValueAt(vm, params, 0);
243 result = resourceWrapper->GetColorByName(param->ToString(vm)->ToString());
244 return true;
245 }
246 auto type = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "type"));
247 if (type->IsNull() || !type->IsNumber()) {
248 return false;
249 }
250 if (resourceObject->GetType() == static_cast<uint32_t>(ResourceType::STRING)) {
251 auto value = resourceWrapper->GetString(resId->Int32Value(vm));
252 return Color::ParseColorString(value, result);
253 }
254 if (resourceObject->GetType() == static_cast<uint32_t>(ResourceType::INTEGER)) {
255 auto value = resourceWrapper->GetInt(resId->Int32Value(vm));
256 result = Color(ColorAlphaAdapt(value));
257 return true;
258 }
259 if (resourceObject->GetType() == static_cast<uint32_t>(ResourceType::COLOR)) {
260 result = resourceWrapper->GetColor(resId->ToNumber(vm)->Value());
261 return true;
262 }
263 return false;
264 }
265
ParseJsDimensionFromResource(const EcmaVM * vm,const Local<JSValueRef> & jsObj,DimensionUnit dimensionUnit,CalcDimension & result)266 bool ArkTSUtils::ParseJsDimensionFromResource(const EcmaVM* vm, const Local<JSValueRef>& jsObj,
267 DimensionUnit dimensionUnit, CalcDimension& result)
268 {
269 auto obj = jsObj->ToObject(vm);
270 auto resId = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
271 if (!resId->IsNumber()) {
272 return false;
273 }
274
275 auto resourceObject = GetResourceObject(vm, jsObj);
276
277 auto resourceWrapper = CreateResourceWrapper(vm, jsObj, resourceObject);
278 if (!resourceWrapper) {
279 return false;
280 }
281 auto resIdNum = resId->Int32Value(vm);
282 if (resIdNum == -1) {
283 if (!IsGetResourceByName(vm, jsObj)) {
284 return false;
285 }
286 auto args = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "params"));
287 if (!args->IsArray(vm)) {
288 return false;
289 }
290 Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
291 auto param = panda::ArrayRef::GetValueAt(vm, params, 0);
292 result = resourceWrapper->GetDimensionByName(param->ToString(vm)->ToString());
293 return true;
294 }
295 auto type = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "type"));
296 if (type->IsNull() || !type->IsNumber()) {
297 return false;
298 }
299 if (resourceObject->GetType() == static_cast<uint32_t>(ResourceType::STRING)) {
300 auto value = resourceWrapper->GetString(resId->Int32Value(vm));
301 result = StringUtils::StringToCalcDimension(value, false, dimensionUnit);
302 return true;
303 }
304 if (resourceObject->GetType() == static_cast<uint32_t>(ResourceType::INTEGER)) {
305 auto value = std::to_string(resourceWrapper->GetInt(resId->Int32Value(vm)));
306 result = StringUtils::StringToDimensionWithUnit(value, dimensionUnit);
307 return true;
308 }
309 result = resourceWrapper->GetDimension(resId->Int32Value(vm));
310 return true;
311 }
312
ParseJsDimensionFromResourceNG(const EcmaVM * vm,const Local<JSValueRef> & jsObj,DimensionUnit dimensionUnit,CalcDimension & result)313 bool ArkTSUtils::ParseJsDimensionFromResourceNG(const EcmaVM* vm, const Local<JSValueRef>& jsObj,
314 DimensionUnit dimensionUnit, CalcDimension& result)
315 {
316 auto obj = jsObj->ToObject(vm);
317 auto resId = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
318 if (!resId->IsNumber()) {
319 return false;
320 }
321
322 auto resourceObject = GetResourceObject(vm, jsObj);
323
324 auto resourceWrapper = CreateResourceWrapper(vm, jsObj, resourceObject);
325 if (!resourceWrapper) {
326 return false;
327 }
328 auto resIdNum = resId->Int32Value(vm);
329 if (resIdNum == -1) {
330 if (!IsGetResourceByName(vm, jsObj)) {
331 return false;
332 }
333 auto args = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "params"));
334 if (!args->IsArray(vm)) {
335 return false;
336 }
337 Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
338 auto param = panda::ArrayRef::GetValueAt(vm, params, 0);
339 result = resourceWrapper->GetDimensionByName(param->ToString(vm)->ToString());
340 return true;
341 }
342 auto type = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "type"));
343 if (type->IsNull() || !type->IsNumber()) {
344 return false;
345 }
346 if (resourceObject->GetType() == static_cast<uint32_t>(ResourceType::STRING)) {
347 auto value = resourceWrapper->GetString(resId->Int32Value(vm));
348 return StringUtils::StringToCalcDimensionNG(value, result, false, dimensionUnit);
349 }
350 if (resourceObject->GetType() == static_cast<uint32_t>(ResourceType::INTEGER)) {
351 auto value = std::to_string(resourceWrapper->GetInt(resId->Int32Value(vm)));
352 StringUtils::StringToDimensionWithUnitNG(value, result, dimensionUnit);
353 return true;
354 }
355 if (resourceObject->GetType() == static_cast<uint32_t>(ResourceType::FLOAT)) {
356 result = resourceWrapper->GetDimension(resId->Int32Value(vm));
357 return true;
358 }
359
360 return false;
361 }
362
ParseStringArray(const EcmaVM * vm,const Local<JSValueRef> & arg,std::string * array,int32_t defaultLength)363 bool ArkTSUtils::ParseStringArray(const EcmaVM* vm, const Local<JSValueRef>& arg,
364 std::string* array, int32_t defaultLength)
365 {
366 CHECK_NULL_RETURN(vm, false);
367 CHECK_NULL_RETURN(array, false);
368 if (defaultLength <= 0) {
369 return false;
370 }
371 auto handle = panda::CopyableGlobal<panda::ArrayRef>(vm, arg);
372 int32_t length = static_cast<int32_t>(handle->Length(vm));
373 if (length != defaultLength) {
374 return false;
375 }
376 for (int32_t i = 0; i < length; i++) {
377 auto value = handle->GetValueAt(vm, arg, i);
378 if (!ParseJsMedia(vm, value, *(array + i))) {
379 *(array + i) = "";
380 }
381 }
382 return true;
383 }
384
ParseJsDimensionVp(const EcmaVM * vm,const Local<JSValueRef> & value,CalcDimension & result,bool enableCheckInvalidvalue)385 bool ArkTSUtils::ParseJsDimensionVp(
386 const EcmaVM* vm, const Local<JSValueRef>& value, CalcDimension& result, bool enableCheckInvalidvalue)
387 {
388 return ArkTSUtils::ParseJsDimension(vm, value, result, DimensionUnit::VP, true, enableCheckInvalidvalue);
389 }
390
ParseJsInteger(const EcmaVM * vm,const Local<JSValueRef> & value,int32_t & result)391 bool ArkTSUtils::ParseJsInteger(const EcmaVM *vm, const Local<JSValueRef> &value, int32_t &result)
392 {
393 if (value->IsNumber()) {
394 result = value->Int32Value(vm);
395 return true;
396 }
397 return false;
398 }
399
ParseJsInteger(const EcmaVM * vm,const Local<JSValueRef> & value,uint32_t & result)400 bool ArkTSUtils::ParseJsInteger(const EcmaVM *vm, const Local<JSValueRef> &value, uint32_t &result)
401 {
402 if (value->IsNumber()) {
403 result = value->Uint32Value(vm);
404 return true;
405 }
406 // resource ignore by design
407 return false;
408 }
409
GetResourceIdAndType(const EcmaVM * vm,const Local<panda::ObjectRef> & jsObj,int32_t & resId,int32_t & resType)410 bool GetResourceIdAndType(const EcmaVM* vm, const Local<panda::ObjectRef>& jsObj, int32_t& resId, int32_t& resType)
411 {
412 auto id = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
413 auto type = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "type"));
414 if (!id->IsNumber() || !type->IsNumber()) {
415 return false;
416 }
417
418 resId = id->Int32Value(vm);
419 resType = type->Int32Value(vm);
420 return true;
421 }
422
ParseResourceToDouble(const EcmaVM * vm,const Local<JSValueRef> & jsValue,double & result)423 bool ArkTSUtils::ParseResourceToDouble(const EcmaVM* vm, const Local<JSValueRef>& jsValue, double& result)
424 {
425 auto jsObj = jsValue->ToObject(vm);
426 int32_t resId;
427 int32_t resType;
428 if (jsObj->IsNull() || !GetResourceIdAndType(vm, jsObj, resId, resType)) {
429 return false;
430 }
431 auto resourceObject = GetResourceObject(vm, jsObj);
432 auto resourceWrapper = CreateResourceWrapper(vm, jsObj, resourceObject);
433 if (!resourceWrapper) {
434 return false;
435 }
436 if (resId == -1) {
437 if (!IsGetResourceByName(vm, jsObj)) {
438 return false;
439 }
440 auto args = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "params"));
441 if (!args->IsArray(vm)) {
442 return false;
443 }
444 Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
445 auto param = panda::ArrayRef::GetValueAt(vm, params, 0);
446 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
447 auto numberString = resourceWrapper->GetStringByName(param->ToString(vm)->ToString());
448 return StringUtils::StringToDouble(numberString, result);
449 }
450 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
451 result = resourceWrapper->GetIntByName(param->ToString(vm)->ToString());
452 return true;
453 }
454 if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
455 result = resourceWrapper->GetDoubleByName(param->ToString(vm)->ToString());
456 return true;
457 }
458 return false;
459 }
460 if (resourceObject->GetType() == static_cast<uint32_t>(ResourceType::STRING)) {
461 auto numberString = resourceWrapper->GetString(resId);
462 return StringUtils::StringToDouble(numberString, result);
463 }
464 if (resourceObject->GetType() == static_cast<uint32_t>(ResourceType::INTEGER)) {
465 result = resourceWrapper->GetInt(resId);
466 return true;
467 }
468 if (resourceObject->GetType() == static_cast<uint32_t>(ResourceType::FLOAT)) {
469 result = resourceWrapper->GetDouble(resId);
470 return true;
471 }
472 return false;
473 }
474
ParseJsDouble(const EcmaVM * vm,const Local<JSValueRef> & value,double & result)475 bool ArkTSUtils::ParseJsDouble(const EcmaVM *vm, const Local<JSValueRef> &value, double &result)
476 {
477 if (value->IsNumber()) {
478 result = value->ToNumber(vm)->Value();
479 return true;
480 }
481 if (value->IsString()) {
482 return StringUtils::StringToDouble(value->ToString(vm)->ToString(), result);
483 }
484 if (value->IsObject()) {
485 return ParseResourceToDouble(vm, value, result);
486 }
487 return false;
488 }
489
ParseAllBorder(const EcmaVM * vm,const Local<JSValueRef> & args,CalcDimension & result)490 bool ArkTSUtils::ParseAllBorder(const EcmaVM* vm, const Local<JSValueRef>& args, CalcDimension& result)
491 {
492 if (ParseJsDimensionVp(vm, args, result)) {
493 if (result.IsNegative()) {
494 result.Reset();
495 }
496
497 if (result.Unit() == DimensionUnit::PERCENT) {
498 result.Reset();
499 }
500 return true;
501 } else {
502 return false;
503 }
504 }
505
ParseAllRadius(const EcmaVM * vm,const Local<JSValueRef> & args,CalcDimension & result)506 bool ArkTSUtils::ParseAllRadius(const EcmaVM* vm, const Local<JSValueRef>& args, CalcDimension& result)
507 {
508 if (ParseJsDimensionVp(vm, args, result)) {
509 if (result.IsNegative()) {
510 result.Reset();
511 }
512 return true;
513 } else {
514 return false;
515 }
516 }
517
ParseJsDimensionNG(const EcmaVM * vm,const Local<JSValueRef> & jsValue,CalcDimension & result,DimensionUnit defaultUnit,bool isSupportPercent)518 bool ArkTSUtils::ParseJsDimensionNG(const EcmaVM *vm, const Local<JSValueRef> &jsValue, CalcDimension &result,
519 DimensionUnit defaultUnit, bool isSupportPercent)
520 {
521 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
522 return false;
523 }
524 if (jsValue->IsNumber()) {
525 result = CalcDimension(jsValue->ToNumber(vm)->Value(), defaultUnit);
526 return true;
527 }
528 if (jsValue->IsString()) {
529 auto value = jsValue->ToString(vm)->ToString();
530 if (value.back() == '%' && !isSupportPercent) {
531 return false;
532 }
533 return StringUtils::StringToCalcDimensionNG(jsValue->ToString(vm)->ToString(), result, false, defaultUnit);
534 }
535 if (jsValue->IsObject()) {
536 return ParseJsDimensionFromResourceNG(vm, jsValue, defaultUnit, result);
537 }
538 return false;
539 }
540
ParseJsDimensionVpNG(const EcmaVM * vm,const Local<JSValueRef> & jsValue,CalcDimension & result,bool isSupportPercent)541 bool ArkTSUtils::ParseJsDimensionVpNG(const EcmaVM *vm, const Local<JSValueRef> &jsValue, CalcDimension &result,
542 bool isSupportPercent)
543 {
544 return ArkTSUtils::ParseJsDimensionNG(vm, jsValue, result, DimensionUnit::VP, isSupportPercent);
545 }
546
ParseJsDimension(const EcmaVM * vm,const Local<JSValueRef> & jsValue,CalcDimension & result,DimensionUnit defaultUnit,bool isSupportPercent,bool enableCheckInvalidvalue)547 bool ArkTSUtils::ParseJsDimension(const EcmaVM *vm, const Local<JSValueRef> &jsValue, CalcDimension &result,
548 DimensionUnit defaultUnit, bool isSupportPercent, bool enableCheckInvalidvalue)
549 {
550 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
551 return false;
552 }
553
554 if (jsValue->IsNumber()) {
555 result = CalcDimension(jsValue->ToNumber(vm)->Value(), defaultUnit);
556 return true;
557 }
558 if (jsValue->IsString()) {
559 auto stringValue = jsValue->ToString(vm)->ToString();
560 if (stringValue.back() == '%' && !isSupportPercent) {
561 return false;
562 }
563 if (enableCheckInvalidvalue && stringValue.find("calc") == std::string::npos) {
564 errno = 0;
565 char* pEnd = nullptr;
566 std::string str = jsValue->ToString(vm)->ToString();
567 std::strtod(str.c_str(), &pEnd);
568 if (pEnd == str.c_str() || errno == ERANGE) {
569 return false;
570 }
571 }
572 result = StringUtils::StringToCalcDimension(jsValue->ToString(vm)->ToString(), false, defaultUnit);
573 return true;
574 }
575 if (jsValue->IsObject()) {
576 return ParseJsDimensionFromResource(vm, jsValue, defaultUnit, result);
577 }
578 return false;
579 }
580
ParseJsDimensionFp(const EcmaVM * vm,const Local<JSValueRef> & jsValue,CalcDimension & result,bool isSupportPercent,bool enableCheckInvalidvalue)581 bool ArkTSUtils::ParseJsDimensionFp(const EcmaVM* vm, const Local<JSValueRef>& jsValue, CalcDimension& result,
582 bool isSupportPercent, bool enableCheckInvalidvalue)
583 {
584 return ArkTSUtils::ParseJsDimension(
585 vm, jsValue, result, DimensionUnit::FP, isSupportPercent, enableCheckInvalidvalue);
586 }
587
ParseJsFontFamiliesToString(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::string & result)588 bool ArkTSUtils::ParseJsFontFamiliesToString(const EcmaVM* vm, const Local<JSValueRef>& jsValue, std::string& result)
589 {
590 if (jsValue->IsNull() || jsValue->IsUndefined()) {
591 return false;
592 }
593
594 if (jsValue->IsString() && jsValue->ToString(vm)->ToString().empty()) {
595 return false;
596 }
597
598 std::vector<std::string> fontFamilies;
599 if (!ParseJsFontFamilies(vm, jsValue, fontFamilies)) {
600 return false;
601 }
602 if (fontFamilies.size() > 0) {
603 result = "";
604 for (uint32_t i = 0; i < fontFamilies.size(); i++) {
605 result += fontFamilies.at(i);
606 if (&fontFamilies.at(i) != &fontFamilies.back()) {
607 result += ",";
608 }
609 }
610 return true;
611 }
612
613 return true;
614 }
615
ParseJsFontFamilies(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::vector<std::string> & result)616 bool ArkTSUtils::ParseJsFontFamilies(
617 const EcmaVM *vm, const Local<JSValueRef> &jsValue, std::vector<std::string> &result)
618 {
619 result.clear();
620 if (!jsValue->IsString() && !jsValue->IsObject()) {
621 return false;
622 }
623 if (jsValue->IsString()) {
624 result = Framework::ConvertStrToFontFamilies(jsValue->ToString(vm)->ToString());
625 return true;
626 }
627 if (jsValue->IsObject()) {
628 auto obj = jsValue->ToObject(vm);
629 auto resId = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
630 if (!resId->IsNumber()) {
631 return false;
632 }
633 return ParseJsFontFamiliesFromResource(vm, jsValue, result);
634 }
635 return true;
636 }
637
ParseJsFontFamiliesFromResource(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::vector<std::string> & result)638 bool ArkTSUtils::ParseJsFontFamiliesFromResource(
639 const EcmaVM *vm, const Local<JSValueRef> &jsValue, std::vector<std::string> &result)
640 {
641 auto jsObj = jsValue->ToObject(vm);
642 auto resId = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
643 if (!resId->IsNumber()) {
644 return false;
645 }
646
647 auto resourceObject = GetResourceObject(vm, jsValue);
648 auto resourceWrapper = CreateResourceWrapper(vm, jsValue, resourceObject);
649 if (!resourceWrapper) {
650 return false;
651 }
652
653 auto resIdNum = resId->Int32Value(vm);
654 if (resIdNum == -1) {
655 if (!IsGetResourceByName(vm, jsValue)) {
656 return false;
657 }
658 auto args = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "params"));
659 if (!args->IsArray(vm)) {
660 return false;
661 }
662 Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
663 auto param = panda::ArrayRef::GetValueAt(vm, params, 0);
664 result.emplace_back(resourceWrapper->GetStringByName(param->ToString(vm)->ToString()));
665 return true;
666 }
667 result.emplace_back(resourceWrapper->GetString(resId->Uint32Value(vm)));
668 return true;
669 }
670
ParseJsMedia(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::string & result)671 bool ArkTSUtils::ParseJsMedia(const EcmaVM *vm, const Local<JSValueRef> &jsValue, std::string& result)
672 {
673 if (!jsValue->IsObject() && !jsValue->IsString()) {
674 return false;
675 }
676 if (jsValue->IsString()) {
677 result = jsValue->ToString(vm)->ToString();
678 return true;
679 }
680 if (jsValue->IsObject()) {
681 auto obj = jsValue->ToObject(vm);
682 auto resId = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
683 if (!resId->IsNumber()) {
684 return false;
685 }
686 return ParseJsMediaFromResource(vm, jsValue, result);
687 }
688 return false;
689 }
690
ParseJsMediaFromResource(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::string & result)691 bool ArkTSUtils::ParseJsMediaFromResource(const EcmaVM *vm, const Local<JSValueRef> &jsValue, std::string& result)
692 {
693 auto jsObj = jsValue->ToObject(vm);
694 auto type = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "type"));
695 auto resId = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
696 if (!resId->IsNull() && !type->IsNull() && type->IsNumber() && resId->IsNumber()) {
697 auto resourceObject = GetResourceObject(vm, jsValue);
698 auto resourceWrapper = CreateResourceWrapper(vm, jsValue, resourceObject);
699 if (!resourceWrapper) {
700 return false;
701 }
702
703 if (resourceObject->GetType() == static_cast<uint32_t>(ResourceType::RAWFILE)) {
704 auto args = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "params"));
705 if (!args->IsArray(vm)) {
706 return false;
707 }
708 Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
709 auto fileName = panda::ArrayRef::GetValueAt(vm, params, 0);
710 if (!fileName->IsString()) {
711 return false;
712 }
713 result = resourceWrapper->GetRawfile(fileName->ToString(vm)->ToString());
714 return true;
715 }
716 auto resIdNum = resId->Int32Value(vm);
717 if (resIdNum == -1) {
718 if (!IsGetResourceByName(vm, jsValue)) {
719 return false;
720 }
721 auto args = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "params"));
722 if (!args->IsArray(vm)) {
723 return false;
724 }
725 Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
726 auto param = panda::ArrayRef::GetValueAt(vm, params, 0);
727 if (resourceObject->GetType() == static_cast<uint32_t>(ResourceType::MEDIA)) {
728 result = resourceWrapper->GetMediaPathByName(param->ToString(vm)->ToString());
729 return true;
730 }
731 return false;
732 }
733 if (resourceObject->GetType() == static_cast<uint32_t>(ResourceType::MEDIA)) {
734 result = resourceWrapper->GetMediaPath(resId->Uint32Value(vm));
735 return true;
736 }
737 return false;
738 }
739 return false;
740 }
741
GetStringFromJS(const EcmaVM * vm,const Local<JSValueRef> & value,std::string & result)742 void ArkTSUtils::GetStringFromJS(const EcmaVM *vm, const Local<JSValueRef> &value, std::string& result)
743 {
744 result = DEFAULT_STR;
745 if (!value->IsNull() && value->IsString()) {
746 result = value->ToString(vm)->ToString();
747 }
748 if (value->IsObject()) {
749 ParseJsStringFromResource(vm, value, result);
750 }
751 }
752
ParseJsIntegerArray(const EcmaVM * vm,Local<JSValueRef> values,std::vector<uint32_t> & result)753 bool ArkTSUtils::ParseJsIntegerArray(const EcmaVM* vm, Local<JSValueRef> values, std::vector<uint32_t>& result)
754 {
755 if (!values->IsArray(vm) && !values->IsObject()) {
756 return false;
757 }
758
759 Local<panda::ArrayRef> valueArray = static_cast<Local<panda::ArrayRef>>(values);
760 for (size_t i = 0; i < valueArray->Length(vm); i++) {
761 Local<JSValueRef> value = valueArray->GetValueAt(vm, values, i);
762 if (value->IsNumber()) {
763 result.emplace_back(value->Uint32Value(vm));
764 } else if (value->IsObject()) {
765 uint32_t singleResInt;
766 if (ParseJsInteger(vm, value, singleResInt)) {
767 result.emplace_back(singleResInt);
768 } else {
769 return false;
770 }
771 } else {
772 return false;
773 }
774 }
775 return true;
776 }
777
ParseJsString(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::string & result)778 bool ArkTSUtils::ParseJsString(const EcmaVM* vm, const Local<JSValueRef>& jsValue, std::string& result)
779 {
780 if (!jsValue->IsString() && !jsValue->IsObject()) {
781 return false;
782 }
783 if (jsValue->IsString()) {
784 result = jsValue->ToString(vm)->ToString();
785 return true;
786 }
787 if (jsValue->IsObject()) {
788 return ArkTSUtils::ParseJsStringFromResource(vm, jsValue, result);
789 }
790 return false;
791 }
792
GetReplaceContentStr(const EcmaVM * vm,int32_t pos,const std::string & type,Local<panda::ArrayRef> params,int32_t containCount)793 std::string GetReplaceContentStr(
794 const EcmaVM* vm, int32_t pos, const std::string& type, Local<panda::ArrayRef> params, int32_t containCount)
795 {
796 int32_t index = pos + containCount;
797 if (index < 0) {
798 return std::string();
799 }
800 auto item = panda::ArrayRef::GetValueAt(vm, params, static_cast<uint32_t>(index));
801 if (type == "d") {
802 if (item->IsNumber()) {
803 return std::to_string(item->ToNumber(vm)->Value());
804 }
805 } else if (type == "s") {
806 if (item->IsString()) {
807 return item->ToString(vm)->ToString();
808 }
809 } else if (type == "f") {
810 if (item->IsNumber()) {
811 return std::to_string(item->ToNumber(vm)->Value());
812 }
813 }
814 return std::string();
815 }
816
ReplaceHolder(const EcmaVM * vm,std::string & originStr,const Local<panda::ArrayRef> & params,int32_t containCount)817 void ReplaceHolder(const EcmaVM* vm, std::string& originStr, const Local<panda::ArrayRef>& params, int32_t containCount)
818 {
819 auto size = static_cast<int32_t>(params->Length(vm));
820 if (containCount == size) {
821 return;
822 }
823 std::string::const_iterator start = originStr.begin();
824 std::string::const_iterator end = originStr.end();
825 std::smatch matches;
826 bool shortHolderType = false;
827 bool firstMatch = true;
828 int searchTime = 0;
829 while (std::regex_search(start, end, matches, RESOURCE_APP_STRING_PLACEHOLDER)) {
830 std::string pos = matches[2];
831 std::string type = matches[4];
832 if (firstMatch) {
833 firstMatch = false;
834 shortHolderType = pos.length() == 0;
835 } else {
836 if (static_cast<uint32_t>(shortHolderType) ^ static_cast<uint32_t>(pos.length() == 0)) {
837 return;
838 }
839 }
840
841 std::string replaceContentStr;
842 if (shortHolderType) {
843 replaceContentStr = GetReplaceContentStr(vm, searchTime, type, params, containCount);
844 } else {
845 replaceContentStr = GetReplaceContentStr(vm, StringUtils::StringToInt(pos) - 1, type, params, containCount);
846 }
847
848 originStr.replace(matches[0].first - originStr.begin(), matches[0].length(), replaceContentStr);
849 start = originStr.begin() + matches.prefix().length() + replaceContentStr.length();
850 end = originStr.end();
851 searchTime++;
852 }
853 }
854
FillResultForResIdNumIsNegative(const EcmaVM * vm,const Local<JSValueRef> & type,const Local<JSValueRef> & params,std::string & result,const RefPtr<ResourceWrapper> & resourceWrapper)855 bool FillResultForResIdNumIsNegative(const EcmaVM* vm, const Local<JSValueRef>& type, const Local<JSValueRef>& params,
856 std::string& result, const RefPtr<ResourceWrapper>& resourceWrapper)
857 {
858 auto param = panda::ArrayRef::GetValueAt(vm, params, 0);
859 if (type->Uint32Value(vm) == static_cast<uint32_t>(ResourceType::STRING)) {
860 auto originStr = resourceWrapper->GetStringByName(param->ToString(vm)->ToString());
861 ReplaceHolder(vm, originStr, params, 0);
862 result = originStr;
863 } else if (type->Uint32Value(vm) == static_cast<uint32_t>(ResourceType::PLURAL)) {
864 auto countJsVal = panda::ArrayRef::GetValueAt(vm, params, 1);
865 int count = 0;
866 if (!countJsVal->IsNumber()) {
867 return false;
868 }
869 count = countJsVal->ToNumber(vm)->Value();
870 auto pluralStr = resourceWrapper->GetPluralStringByName(param->ToString(vm)->ToString(), count);
871 ReplaceHolder(vm, pluralStr, params, REPLACEHOLDER_INDEX);
872 result = pluralStr;
873 } else {
874 return false;
875 }
876 return true;
877 }
878
ParseJsStringFromResource(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::string & result)879 bool ArkTSUtils::ParseJsStringFromResource(const EcmaVM* vm, const Local<JSValueRef>& jsValue, std::string& result)
880 {
881 auto obj = jsValue->ToObject(vm);
882 auto type = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "type"));
883 auto resId = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
884 auto args = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "params"));
885 if (!type->IsNumber() || !resId->IsNumber() || !args->IsArray(vm)) {
886 return false;
887 }
888
889 auto resourceObject = GetResourceObject(vm, obj);
890 auto resourceWrapper = CreateResourceWrapper(vm, obj, resourceObject);
891 if (!resourceWrapper) {
892 return false;
893 }
894
895 Local<panda::ArrayRef> params = static_cast<Local<panda::ArrayRef>>(args);
896 auto resIdNum = resourceObject->GetId();
897 if (resIdNum == -1) {
898 if (!IsGetResourceByName(vm, obj)) {
899 return false;
900 }
901 return FillResultForResIdNumIsNegative(vm, type, params, result, resourceWrapper);
902 }
903 if (resourceObject->GetType() == static_cast<uint32_t>(ResourceType::STRING)) {
904 auto originStr = resourceWrapper->GetString(resId->Uint32Value(vm));
905 ReplaceHolder(vm, originStr, params, 0);
906 result = originStr;
907 } else if (resourceObject->GetType() == static_cast<uint32_t>(ResourceType::PLURAL)) {
908 auto countJsVal = panda::ArrayRef::GetValueAt(vm, params, 0);
909 int count = 0;
910 if (!countJsVal->IsNumber()) {
911 return false;
912 }
913 count = countJsVal->ToNumber(vm)->Value();
914 auto pluralStr = resourceWrapper->GetPluralString(resId->ToNumber(vm)->Value(), count);
915 ReplaceHolder(vm, pluralStr, params, 1);
916 result = pluralStr;
917 } else if (resourceObject->GetType() == static_cast<uint32_t>(ResourceType::FLOAT)) {
918 result = std::to_string(resourceWrapper->GetDouble(resId->Uint32Value(vm)));
919 } else if (resourceObject->GetType() == static_cast<uint32_t>(ResourceType::INTEGER)) {
920 result = std::to_string(resourceWrapper->GetInt(resId->Uint32Value(vm)));
921 } else {
922 return false;
923 }
924 return true;
925 }
926
ParseJsResource(const EcmaVM * vm,const Local<JSValueRef> & jsValue,CalcDimension & result)927 bool ArkTSUtils::ParseJsResource(const EcmaVM *vm, const Local<JSValueRef> &jsValue, CalcDimension &result)
928 {
929 if (!jsValue->IsObject()) {
930 return false;
931 }
932 auto jsObj = jsValue->ToObject(vm);
933 auto resourceObject = GetResourceObject(vm, jsValue);
934 auto resourceWrapper = CreateResourceWrapper(vm, jsValue, resourceObject);
935 CHECK_NULL_RETURN(resourceWrapper, false);
936
937 auto type = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "type"));
938 auto id = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "id"));
939 uint32_t resourceType = 0;
940 if (type->IsNull() || !type->IsNumber() || id->IsNull() || !id->IsNumber()) {
941 return false;
942 } else {
943 resourceType = type->Uint32Value(vm);
944 }
945 if (resourceType == static_cast<uint32_t>(ResourceType::STRING)) {
946 auto value = resourceWrapper->GetString(id->Uint32Value(vm));
947 return StringUtils::StringToCalcDimensionNG(value, result, false);
948 }
949 if (resourceType == static_cast<uint32_t>(ResourceType::INTEGER)) {
950 auto value = std::to_string(resourceWrapper->GetInt(id->Uint32Value(vm)));
951 StringUtils::StringToDimensionWithUnitNG(value, result);
952 return true;
953 }
954
955 if (resourceType == static_cast<uint32_t>(ResourceType::FLOAT)) {
956 result = resourceWrapper->GetDimension(id->Uint32Value(vm));
957 return true;
958 }
959 return false;
960 }
961
GetJsMediaBundleInfo(const EcmaVM * vm,const Local<JSValueRef> & jsValue,std::string & bundleName,std::string & moduleName)962 void ArkTSUtils::GetJsMediaBundleInfo(
963 const EcmaVM* vm, const Local<JSValueRef>& jsValue, std::string& bundleName, std::string& moduleName)
964 {
965 if (!jsValue->IsObject() || jsValue->IsString()) {
966 return;
967 }
968 auto jsObj = jsValue->ToObject(vm);
969 if (!jsObj->IsUndefined()) {
970 auto bundle = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "bundleName"));
971 auto module = jsObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "moduleName"));
972 if (bundle->IsString() && module->IsString()) {
973 bundleName = bundle->ToString(vm)->ToString();
974 moduleName = module->ToString(vm)->ToString();
975 }
976 }
977 }
978
ParseJsColorStrategy(const EcmaVM * vm,const Local<JSValueRef> & value,ForegroundColorStrategy & strategy)979 bool ArkTSUtils::ParseJsColorStrategy(
980 const EcmaVM* vm, const Local<JSValueRef>& value, ForegroundColorStrategy& strategy)
981 {
982 if (value->IsString()) {
983 std::string colorStr = value->ToString(vm)->ToString();
984 if (colorStr.compare("invert") == 0) {
985 strategy = ForegroundColorStrategy::INVERT;
986 return true;
987 }
988 }
989 return false;
990 }
991
GetJsPasswordIcon(const EcmaVM * vm,const Local<JSValueRef> & jsOnIconSrc,const Local<JSValueRef> & jsOffIconSrc,PasswordIcon & result)992 bool ArkTSUtils::GetJsPasswordIcon(const EcmaVM *vm, const Local<JSValueRef> &jsOnIconSrc,
993 const Local<JSValueRef> &jsOffIconSrc, PasswordIcon& result)
994 {
995 result.showResult = "";
996 result.hideResult = "";
997 result.showBundleName = "";
998 result.hideBundleName = "";
999 result.showModuleName = "";
1000 result.hideModuleName = "";
1001
1002 if (!jsOnIconSrc->IsString() && !jsOnIconSrc->IsObject()
1003 && !jsOffIconSrc->IsString() && !jsOffIconSrc->IsObject()) {
1004 return false;
1005 }
1006
1007 if (jsOnIconSrc->IsString()) {
1008 result.showResult = jsOnIconSrc->ToString(vm)->ToString();
1009 }
1010
1011 if (jsOnIconSrc->IsObject()) {
1012 auto obj = jsOnIconSrc->ToObject(vm);
1013 std::string bundleName;
1014 std::string moduleName;
1015 auto bundle = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "bundleName"));
1016 auto module = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "moduleName"));
1017 if (bundle->IsString() && module->IsString()) {
1018 result.showBundleName = bundle->ToString(vm)->ToString();
1019 result.showModuleName = module->ToString(vm)->ToString();
1020 }
1021 ParseJsMedia(vm, jsOnIconSrc, result.showResult);
1022 }
1023
1024 if (jsOffIconSrc->IsString()) {
1025 result.hideResult = jsOffIconSrc->ToString(vm)->ToString();
1026 }
1027
1028 if (jsOffIconSrc->IsObject()) {
1029 auto obj = jsOffIconSrc->ToObject(vm);
1030 std::string bundleName;
1031 std::string moduleName;
1032 auto bundle = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "bundleName"));
1033 auto module = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "moduleName"));
1034 if (bundle->IsString() && module->IsString()) {
1035 result.hideBundleName = bundle->ToString(vm)->ToString();
1036 result.hideModuleName = module->ToString(vm)->ToString();
1037 }
1038 ParseJsMedia(vm, jsOffIconSrc, result.hideResult);
1039 }
1040 return true;
1041 }
1042
ParsePadding(const EcmaVM * vm,const Local<JSValueRef> & value,CalcDimension & dimen,ArkUISizeType & result)1043 void ArkTSUtils::ParsePadding(
1044 const EcmaVM* vm, const Local<JSValueRef>& value, CalcDimension& dimen, ArkUISizeType& result)
1045 {
1046 if (ArkTSUtils::ParseJsDimensionVp(vm, value, dimen)) {
1047 if (LessOrEqual(dimen.Value(), 0.0)) {
1048 dimen.SetValue(0.0);
1049 dimen.SetUnit(DimensionUnit::VP);
1050 }
1051 result.unit = static_cast<int8_t>(dimen.Unit());
1052 if (dimen.CalcValue() != "") {
1053 result.string = dimen.CalcValue().c_str();
1054 } else {
1055 result.value = dimen.Value();
1056 }
1057 }
1058 }
1059
ParseResponseRegion(const EcmaVM * vm,const Local<JSValueRef> & jsValue,double * regionValues,int32_t * regionUnits,uint32_t length)1060 bool ArkTSUtils::ParseResponseRegion(
1061 const EcmaVM* vm, const Local<JSValueRef>& jsValue, double* regionValues, int32_t* regionUnits, uint32_t length)
1062 {
1063 if (jsValue->IsUndefined() || !jsValue->IsArray(vm)) {
1064 return false;
1065 }
1066
1067 Local<panda::ArrayRef> transArray = static_cast<Local<panda::ArrayRef>>(jsValue);
1068 for (uint32_t i = 0; i < length; i = i + 4) { // 4: dimension length
1069 Local<JSValueRef> x = transArray->GetValueAt(vm, jsValue, i);
1070 Local<JSValueRef> y = transArray->GetValueAt(vm, jsValue, i + 1);
1071 Local<JSValueRef> width = transArray->GetValueAt(vm, jsValue, i + 2); // 2: width value
1072 Local<JSValueRef> height = transArray->GetValueAt(vm, jsValue, i + 3); // 3: height value
1073 CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
1074 CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
1075 CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
1076 CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
1077 auto s1 = width->ToString(vm)->ToString();
1078 auto s2 = height->ToString(vm)->ToString();
1079 if (s1.find('-') != std::string::npos) {
1080 width = OHOS::Ace::Framework::ToJSValue("100%");
1081 }
1082 if (s2.find('-') != std::string::npos) {
1083 height = OHOS::Ace::Framework::ToJSValue("100%");
1084 }
1085 if (!ArkTSUtils::ParseJsDimensionNG(vm, x, xDimen, DimensionUnit::VP)) {
1086 xDimen = CalcDimension(0.0, DimensionUnit::VP);
1087 }
1088 if (!ArkTSUtils::ParseJsDimensionNG(vm, y, yDimen, DimensionUnit::VP)) {
1089 yDimen = CalcDimension(0.0, DimensionUnit::VP);
1090 }
1091 if (!ArkTSUtils::ParseJsDimensionNG(vm, width, widthDimen, DimensionUnit::VP)) {
1092 widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
1093 }
1094 if (!ArkTSUtils::ParseJsDimensionNG(vm, height, heightDimen, DimensionUnit::VP)) {
1095 heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
1096 }
1097 regionValues[i] = xDimen.Value();
1098 regionUnits[i] = static_cast<int32_t>(xDimen.Unit());
1099 regionValues[i + 1] = yDimen.Value();
1100 regionUnits[i + 1] = static_cast<int32_t>(yDimen.Unit());
1101 regionValues[i + 2] = widthDimen.Value(); // 2: width value
1102 regionUnits[i + 2] = static_cast<int32_t>(widthDimen.Unit()); // 2: width Unit
1103 regionValues[i + 3] = heightDimen.Value(); // 3: height value
1104 regionUnits[i + 3] = static_cast<int32_t>(heightDimen.Unit()); // 3: height Unit
1105 }
1106 return true;
1107 }
1108 } // namespace OHOS::Ace::NG
1109