• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "bridge/declarative_frontend/jsview/js_select.h"
17 
18 #include <cstdint>
19 #include <string>
20 #include <vector>
21 
22 #include "base/log/ace_scoring_log.h"
23 #include "base/utils/utils.h"
24 #include "bridge/common/utils/utils.h"
25 #include "bridge/declarative_frontend/engine/functions/js_function.h"
26 #include "bridge/declarative_frontend/jsview/js_interactable_view.h"
27 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
28 #include "bridge/declarative_frontend/jsview/models/select_model_impl.h"
29 #include "core/components_ng/base/view_abstract_model.h"
30 #include "core/components_ng/pattern/select/select_model.h"
31 #include "core/components_ng/pattern/select/select_model_ng.h"
32 #include "core/components_v2/inspector/inspector_constants.h"
33 #include "core/pipeline/pipeline_base.h"
34 
35 namespace OHOS::Ace {
36 std::unique_ptr<SelectModel> SelectModel::instance_ = nullptr;
37 std::mutex SelectModel::mutex_;
38 
GetInstance()39 SelectModel* SelectModel::GetInstance()
40 {
41     if (!instance_) {
42         std::lock_guard<std::mutex> lock(mutex_);
43         if (!instance_) {
44 #ifdef NG_BUILD
45             instance_.reset(new NG::SelectModelNG());
46 #else
47             if (Container::IsCurrentUseNewPipeline()) {
48                 instance_.reset(new NG::SelectModelNG());
49             } else {
50                 instance_.reset(new Framework::SelectModelImpl());
51             }
52 #endif
53         }
54     }
55     return instance_.get();
56 }
57 } // namespace OHOS::Ace
58 
59 namespace OHOS::Ace::Framework {
Create(const JSCallbackInfo & info)60 void JSSelect::Create(const JSCallbackInfo& info)
61 {
62     if (info.Length() < 0) {
63         return;
64     }
65     if (info[0]->IsArray()) {
66         auto paramArray = JSRef<JSArray>::Cast(info[0]);
67         size_t size = paramArray->Length();
68         std::vector<SelectParam> params(size);
69         for (size_t i = 0; i < size; i++) {
70             std::string value;
71             std::string icon;
72                 JSRef<JSVal> indexVal = paramArray->GetValueAt(i);
73                 if (!indexVal->IsObject()) {
74                     LOGE("element of paramArray is not an object.");
75                     return;
76                 }
77                 auto indexObject = JSRef<JSObject>::Cast(indexVal);
78                 auto selectValue = indexObject->GetProperty("value");
79                 auto selectIcon = indexObject->GetProperty("icon");
80                 if (!ParseJsString(selectValue, value)) {
81                     LOGW("selectValue is null");
82                 }
83                 if (!ParseJsMedia(selectIcon, icon)) {
84                     LOGI("selectIcon is null");
85                 }
86 
87             params[i] = { value, icon };
88         }
89         SelectModel::GetInstance()->Create(params);
90     }
91 }
92 
JSBind(BindingTarget globalObj)93 void JSSelect::JSBind(BindingTarget globalObj)
94 {
95     JSClass<JSSelect>::Declare("Select");
96     MethodOptions opt = MethodOptions::NONE;
97     JSClass<JSSelect>::StaticMethod("create", &JSSelect::Create, opt);
98 
99     JSClass<JSSelect>::StaticMethod("selected", &JSSelect::Selected, opt);
100     JSClass<JSSelect>::StaticMethod("value", &JSSelect::Value, opt);
101     JSClass<JSSelect>::StaticMethod("font", &JSSelect::Font, opt);
102     JSClass<JSSelect>::StaticMethod("fontColor", &JSSelect::FontColor, opt);
103     JSClass<JSSelect>::StaticMethod("selectedOptionBgColor", &JSSelect::SelectedOptionBgColor, opt);
104     JSClass<JSSelect>::StaticMethod("selectedOptionFont", &JSSelect::SelectedOptionFont, opt);
105     JSClass<JSSelect>::StaticMethod("selectedOptionFontColor", &JSSelect::SelectedOptionFontColor, opt);
106     JSClass<JSSelect>::StaticMethod("optionBgColor", &JSSelect::OptionBgColor, opt);
107     JSClass<JSSelect>::StaticMethod("optionFont", &JSSelect::OptionFont, opt);
108     JSClass<JSSelect>::StaticMethod("optionFontColor", &JSSelect::OptionFontColor, opt);
109     JSClass<JSSelect>::StaticMethod("onSelect", &JSSelect::OnSelected, opt);
110     JSClass<JSSelect>::StaticMethod("space", &JSSelect::SetSpace, opt);
111     JSClass<JSSelect>::StaticMethod("arrowPosition", &JSSelect::SetArrowPosition, opt);
112     JSClass<JSSelect>::StaticMethod("menuAlign", &JSSelect::SetMenuAlign, opt);
113 
114     // API7 onSelected deprecated
115     JSClass<JSSelect>::StaticMethod("onSelected", &JSSelect::OnSelected, opt);
116     JSClass<JSSelect>::StaticMethod("width", &JSSelect::JsWidth);
117     JSClass<JSSelect>::StaticMethod("height", &JSSelect::JsHeight);
118     JSClass<JSSelect>::StaticMethod("size", &JSSelect::JsSize);
119     JSClass<JSSelect>::StaticMethod("padding", &JSSelect::JsPadding);
120     JSClass<JSSelect>::StaticMethod("paddingTop", &JSSelect::SetPaddingTop, opt);
121     JSClass<JSSelect>::StaticMethod("paddingBottom", &JSSelect::SetPaddingBottom, opt);
122     JSClass<JSSelect>::StaticMethod("paddingLeft", &JSSelect::SetPaddingLeft, opt);
123     JSClass<JSSelect>::StaticMethod("paddingRight", &JSSelect::SetPaddingRight, opt);
124 
125     JSClass<JSSelect>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
126     JSClass<JSSelect>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
127     JSClass<JSSelect>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
128     JSClass<JSSelect>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
129     JSClass<JSSelect>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
130     JSClass<JSSelect>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
131     JSClass<JSSelect>::InheritAndBind<JSViewAbstract>(globalObj);
132 }
133 
ParseSelectedObject(const JSCallbackInfo & info,const JSRef<JSVal> & changeEventVal)134 void ParseSelectedObject(const JSCallbackInfo& info, const JSRef<JSVal>& changeEventVal)
135 {
136     CHECK_NULL_VOID(changeEventVal->IsFunction());
137 
138     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
139     auto onSelect = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](int32_t index) {
140         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
141         ACE_SCORING_EVENT("Select.SelectChangeEvent");
142         auto newJSVal = JSRef<JSVal>::Make(ToJSValue(index));
143         func->ExecuteJS(1, &newJSVal);
144     };
145     SelectModel::GetInstance()->SetSelectChangeEvent(onSelect);
146 }
147 
Selected(const JSCallbackInfo & info)148 void JSSelect::Selected(const JSCallbackInfo& info)
149 {
150     if (info.Length() < 1 || info.Length() > 2) {
151         LOGE("The arg is wrong, it is supposed to have 1 or 2 arguments");
152         return;
153     }
154 
155     int32_t value = 0;
156     if (info.Length() > 0 && info[0]->IsNumber()) {
157         value = info[0]->ToNumber<int32_t>();
158     }
159 
160     if (value < -1) {
161         value = -1;
162     }
163     if (info.Length() > 1 && info[1]->IsFunction()) {
164         ParseSelectedObject(info, info[1]);
165     }
166     SelectModel::GetInstance()->SetSelected(value);
167 }
168 
ParseValueObject(const JSCallbackInfo & info,const JSRef<JSVal> & changeEventVal)169 void ParseValueObject(const JSCallbackInfo& info, const JSRef<JSVal>& changeEventVal)
170 {
171     CHECK_NULL_VOID(changeEventVal->IsFunction());
172 
173     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
174     auto onSelect = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& value) {
175         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
176         ACE_SCORING_EVENT("Select.ValueChangeEvent");
177         auto newJSVal = JSRef<JSVal>::Make(ToJSValue(value));
178         func->ExecuteJS(1, &newJSVal);
179     };
180     SelectModel::GetInstance()->SetValueChangeEvent(onSelect);
181 }
182 
Value(const JSCallbackInfo & info)183 void JSSelect::Value(const JSCallbackInfo& info)
184 {
185     if (info.Length() < 1 || info.Length() > 2) {
186         LOGE("The arg is wrong, it is supposed to have 1 or 2 arguments");
187         return;
188     }
189 
190     std::string value;
191     if (info.Length() > 0 && info[0]->IsString()) {
192         value = info[0]->ToString();
193     }
194 
195     if (info.Length() > 1 && info[1]->IsFunction()) {
196         ParseValueObject(info, info[1]);
197     }
198     SelectModel::GetInstance()->SetValue(value);
199 }
200 
Font(const JSCallbackInfo & info)201 void JSSelect::Font(const JSCallbackInfo& info)
202 {
203     if (!info[0]->IsObject()) {
204         return;
205     }
206 
207     auto param = JSRef<JSObject>::Cast(info[0]);
208     auto size = param->GetProperty("size");
209     if (!size->IsNull()) {
210         CalcDimension fontSize;
211         if (ParseJsDimensionFp(size, fontSize)) {
212             SelectModel::GetInstance()->SetFontSize(fontSize);
213         }
214     }
215     std::string weight;
216     auto fontWeight = param->GetProperty("weight");
217     if (!fontWeight->IsNull()) {
218         if (fontWeight->IsNumber()) {
219             weight = std::to_string(fontWeight->ToNumber<int32_t>());
220         } else {
221             ParseJsString(fontWeight, weight);
222         }
223         SelectModel::GetInstance()->SetFontWeight(ConvertStrToFontWeight(weight));
224     }
225 
226     auto family = param->GetProperty("family");
227     if (!family->IsNull() && family->IsString()) {
228         auto familyVal = family->ToString();
229         SelectModel::GetInstance()->SetFontFamily(ConvertStrToFontFamilies(familyVal));
230     }
231 
232     auto style = param->GetProperty("style");
233     if (!style->IsNull() && style->IsNumber()) {
234         auto styleVal = static_cast<FontStyle>(style->ToNumber<int32_t>());
235         SelectModel::GetInstance()->SetItalicFontStyle(styleVal);
236     }
237 }
238 
FontColor(const JSCallbackInfo & info)239 void JSSelect::FontColor(const JSCallbackInfo& info)
240 {
241     if (info.Length() < 1) {
242         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
243         return;
244     }
245 
246     Color textColor;
247     if (!ParseJsColor(info[0], textColor)) {
248         if (info[0]->IsNull() || info[0]->IsUndefined()) {
249             auto pipeline = PipelineBase::GetCurrentContext();
250             CHECK_NULL_VOID_NOLOG(pipeline);
251             auto theme = pipeline->GetTheme<SelectTheme>();
252             CHECK_NULL_VOID_NOLOG(theme);
253             textColor = theme->GetFontColor();
254         } else {
255             return;
256         }
257     }
258 
259     SelectModel::GetInstance()->SetFontColor(textColor);
260 }
261 
SelectedOptionBgColor(const JSCallbackInfo & info)262 void JSSelect::SelectedOptionBgColor(const JSCallbackInfo& info)
263 {
264     if (info.Length() < 1) {
265         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
266         return;
267     }
268     Color bgColor;
269     if (!ParseJsColor(info[0], bgColor)) {
270         if (info[0]->IsUndefined() || info[0]->IsNull()) {
271             auto pipeline = PipelineBase::GetCurrentContext();
272             CHECK_NULL_VOID_NOLOG(pipeline);
273             auto theme = pipeline->GetTheme<SelectTheme>();
274             CHECK_NULL_VOID_NOLOG(theme);
275             bgColor = theme->GetSelectedColor();
276         } else {
277             return;
278         }
279     }
280     SelectModel::GetInstance()->SetSelectedOptionBgColor(bgColor);
281 }
282 
SelectedOptionFont(const JSCallbackInfo & info)283 void JSSelect::SelectedOptionFont(const JSCallbackInfo& info)
284 {
285     if (!info[0]->IsObject()) {
286         return;
287     }
288     auto param = JSRef<JSObject>::Cast(info[0]);
289 
290     if (info.Length() < 1) {
291         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
292         return;
293     }
294 
295     auto size = param->GetProperty("size");
296     if (!size->IsNull()) {
297         CalcDimension fontSize;
298         if (ParseJsDimensionFp(size, fontSize)) {
299             SelectModel::GetInstance()->SetSelectedOptionFontSize(fontSize);
300         } else if (size->IsUndefined()) {
301             auto pipeline = PipelineBase::GetCurrentContext();
302             CHECK_NULL_VOID_NOLOG(pipeline);
303             auto theme = pipeline->GetTheme<SelectTheme>();
304             CHECK_NULL_VOID_NOLOG(theme);
305             SelectModel::GetInstance()->SetSelectedOptionFontSize(theme->GetFontSize());
306         }
307     }
308     std::string weight;
309     auto fontWeight = param->GetProperty("weight");
310     if (!fontWeight->IsNull()) {
311         if (fontWeight->IsNumber()) {
312             weight = std::to_string(fontWeight->ToNumber<int32_t>());
313         } else {
314             ParseJsString(fontWeight, weight);
315         }
316         SelectModel::GetInstance()->SetSelectedOptionFontWeight(ConvertStrToFontWeight(weight));
317     }
318 
319     auto family = param->GetProperty("family");
320     if (!family->IsNull() && family->IsString()) {
321         auto familyVal = family->ToString();
322         SelectModel::GetInstance()->SetSelectedOptionFontFamily(ConvertStrToFontFamilies(familyVal));
323     }
324 
325     auto style = param->GetProperty("style");
326     if (!style->IsNull() && style->IsNumber()) {
327         auto styleVal = static_cast<FontStyle>(style->ToNumber<int32_t>());
328         SelectModel::GetInstance()->SetSelectedOptionItalicFontStyle(styleVal);
329     }
330 }
331 
SelectedOptionFontColor(const JSCallbackInfo & info)332 void JSSelect::SelectedOptionFontColor(const JSCallbackInfo& info)
333 {
334     if (info.Length() < 1) {
335         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
336         return;
337     }
338     Color textColor;
339     if (!ParseJsColor(info[0], textColor)) {
340         if (info[0]->IsNull() || info[0]->IsUndefined()) {
341             auto pipeline = PipelineBase::GetCurrentContext();
342             CHECK_NULL_VOID_NOLOG(pipeline);
343             auto theme = pipeline->GetTheme<SelectTheme>();
344             CHECK_NULL_VOID_NOLOG(theme);
345             textColor = theme->GetSelectedColorText();
346         } else {
347             return;
348         }
349     }
350     SelectModel::GetInstance()->SetSelectedOptionFontColor(textColor);
351 }
352 
OptionBgColor(const JSCallbackInfo & info)353 void JSSelect::OptionBgColor(const JSCallbackInfo& info)
354 {
355     if (info.Length() < 1) {
356         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
357         return;
358     }
359     Color bgColor;
360     if (!ParseJsColor(info[0], bgColor)) {
361         return;
362     }
363 
364     SelectModel::GetInstance()->SetOptionBgColor(bgColor);
365 }
366 
OptionFont(const JSCallbackInfo & info)367 void JSSelect::OptionFont(const JSCallbackInfo& info)
368 {
369     if (!info[0]->IsObject()) {
370         return;
371     }
372     auto param = JSRef<JSObject>::Cast(info[0]);
373 
374     auto size = param->GetProperty("size");
375     if (!size->IsNull()) {
376         CalcDimension fontSize;
377         if (ParseJsDimensionFp(size, fontSize)) {
378             SelectModel::GetInstance()->SetOptionFontSize(fontSize);
379         }
380         if (size->IsUndefined()) {
381             auto pipeline = PipelineBase::GetCurrentContext();
382             CHECK_NULL_VOID_NOLOG(pipeline);
383             auto theme = pipeline->GetTheme<SelectTheme>();
384             CHECK_NULL_VOID_NOLOG(theme);
385             SelectModel::GetInstance()->SetOptionFontSize(theme->GetFontSize());
386         }
387     }
388     std::string weight;
389     auto fontWeight = param->GetProperty("weight");
390     if (!fontWeight->IsNull()) {
391         if (fontWeight->IsNumber()) {
392             weight = std::to_string(fontWeight->ToNumber<int32_t>());
393         } else {
394             ParseJsString(fontWeight, weight);
395         }
396         SelectModel::GetInstance()->SetOptionFontWeight(ConvertStrToFontWeight(weight));
397     }
398 
399     auto family = param->GetProperty("family");
400     if (!family->IsNull() && family->IsString()) {
401         auto familyVal = family->ToString();
402         SelectModel::GetInstance()->SetOptionFontFamily(ConvertStrToFontFamilies(familyVal));
403     }
404 
405     auto style = param->GetProperty("style");
406     if (!style->IsNull() && style->IsNumber()) {
407         auto styleVal = static_cast<FontStyle>(style->ToNumber<int32_t>());
408         SelectModel::GetInstance()->SetOptionItalicFontStyle(styleVal);
409     }
410 }
411 
OptionFontColor(const JSCallbackInfo & info)412 void JSSelect::OptionFontColor(const JSCallbackInfo& info)
413 {
414     if (info.Length() < 1) {
415         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
416         return;
417     }
418     Color textColor;
419     if (!ParseJsColor(info[0], textColor)) {
420         return;
421     }
422 
423     SelectModel::GetInstance()->SetOptionFontColor(textColor);
424 }
425 
OnSelected(const JSCallbackInfo & info)426 void JSSelect::OnSelected(const JSCallbackInfo& info)
427 {
428     if (!info[0]->IsFunction()) {
429         LOGE("info[0] is not a function.");
430         return;
431     }
432     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
433     auto onSelect = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](
434                         int32_t index, const std::string& value) {
435         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
436         ACE_SCORING_EVENT("Select.onSelect");
437         JSRef<JSVal> params[2];
438         params[0] = JSRef<JSVal>::Make(ToJSValue(index));
439         params[1] = JSRef<JSVal>::Make(ToJSValue(value));
440         func->ExecuteJS(2, params);
441     };
442     SelectModel::GetInstance()->SetOnSelect(std::move(onSelect));
443     info.ReturnSelf();
444 }
445 
JsWidth(const JSCallbackInfo & info)446 void JSSelect::JsWidth(const JSCallbackInfo& info)
447 {
448     if (info.Length() < 1) {
449         LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
450         return;
451     }
452     CalcDimension value;
453     if (!ParseJsDimensionVp(info[0], value)) {
454         return;
455     }
456 
457     SelectModel::GetInstance()->SetWidth(value);
458 }
459 
JsHeight(const JSCallbackInfo & info)460 void JSSelect::JsHeight(const JSCallbackInfo& info)
461 {
462     if (info.Length() < 1) {
463         LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
464         return;
465     }
466 
467     CalcDimension value;
468     if (!ParseJsDimensionVp(info[0], value)) {
469         return;
470     }
471 
472     SelectModel::GetInstance()->SetHeight(value);
473 }
474 
CheckJSCallbackInfo(const std::string & callerName,const JSCallbackInfo & info,std::vector<JSCallbackInfoType> & infoTypes)475 bool CheckJSCallbackInfo(
476     const std::string& callerName, const JSCallbackInfo& info, std::vector<JSCallbackInfoType>& infoTypes)
477 {
478     if (info.Length() < 1) {
479         LOGE("%{public}s: The arg is supposed to have at least one argument", callerName.c_str());
480         return false;
481     }
482     bool typeVerified = false;
483     std::string unrecognizedType;
484     for (const auto& infoType : infoTypes) {
485         switch (infoType) {
486             case JSCallbackInfoType::STRING:
487                 if (info[0]->IsString()) {
488                     typeVerified = true;
489                 } else {
490                     unrecognizedType += "string|";
491                 }
492                 break;
493             case JSCallbackInfoType::NUMBER:
494                 if (info[0]->IsNumber()) {
495                     typeVerified = true;
496                 } else {
497                     unrecognizedType += "number|";
498                 }
499                 break;
500             case JSCallbackInfoType::OBJECT:
501                 if (info[0]->IsObject()) {
502                     typeVerified = true;
503                 } else {
504                     unrecognizedType += "object|";
505                 }
506                 break;
507             case JSCallbackInfoType::FUNCTION:
508                 if (info[0]->IsFunction()) {
509                     typeVerified = true;
510                 } else {
511                     unrecognizedType += "Function|";
512                 }
513                 break;
514             default:
515                 break;
516         }
517     }
518     if (!typeVerified) {
519         LOGE("%{public}s: info[0] is not a [%{public}s]", callerName.c_str(),
520             unrecognizedType.substr(0, unrecognizedType.size() - 1).c_str());
521     }
522     return typeVerified || infoTypes.size() == 0;
523 }
524 
JsSize(const JSCallbackInfo & info)525 void JSSelect::JsSize(const JSCallbackInfo& info)
526 {
527     std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
528     if (!CheckJSCallbackInfo("JsSize", info, checkList)) {
529         return;
530     }
531 
532     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
533 
534     CalcDimension width;
535     if (!ParseJsDimensionVp(sizeObj->GetProperty("width"), width)) {
536         return;
537     }
538 
539     CalcDimension height;
540     if (!ParseJsDimensionVp(sizeObj->GetProperty("height"), height)) {
541         return;
542     }
543 
544     SelectModel::GetInstance()->SetSize(width, height);
545 }
546 
JsPadding(const JSCallbackInfo & info)547 void JSSelect::JsPadding(const JSCallbackInfo& info)
548 {
549     if (!info[0]->IsString() && !info[0]->IsNumber() && !info[0]->IsObject()) {
550         LOGE("arg is not a string, number or object.");
551         return;
552     }
553 
554     if (info[0]->IsObject()) {
555         std::optional<CalcDimension> left;
556         std::optional<CalcDimension> right;
557         std::optional<CalcDimension> top;
558         std::optional<CalcDimension> bottom;
559         JSRef<JSObject> paddingObj = JSRef<JSObject>::Cast(info[0]);
560 
561         CalcDimension leftDimen;
562         if (ParseJsDimensionVp(paddingObj->GetProperty("left"), leftDimen)) {
563             left = leftDimen;
564         }
565         CalcDimension rightDimen;
566         if (ParseJsDimensionVp(paddingObj->GetProperty("right"), rightDimen)) {
567             right = rightDimen;
568         }
569         CalcDimension topDimen;
570         if (ParseJsDimensionVp(paddingObj->GetProperty("top"), topDimen)) {
571             top = topDimen;
572         }
573         CalcDimension bottomDimen;
574         if (ParseJsDimensionVp(paddingObj->GetProperty("bottom"), bottomDimen)) {
575             bottom = bottomDimen;
576         }
577         if (left.has_value() || right.has_value() || top.has_value() || bottom.has_value()) {
578             ViewAbstractModel::GetInstance()->SetPaddings(top, bottom, left, right);
579             return;
580         }
581     }
582 
583     CalcDimension value;
584     if (!ParseJsDimensionVp(info[0], value)) {
585         value.Reset();
586     }
587     SelectModel::GetInstance()->SetPadding(value);
588 }
589 
SetPaddingLeft(const JSCallbackInfo & info)590 void JSSelect::SetPaddingLeft(const JSCallbackInfo& info)
591 {
592     if (info.Length() < 1) {
593         LOGE("The arg is wrong, it is supposed to have at least 1 argument");
594         return;
595     }
596     CalcDimension value;
597     if (!ParseJsDimensionVp(info[0], value)) {
598         return;
599     }
600     SelectModel::GetInstance()->SetPaddingLeft(value);
601 }
602 
SetPaddingTop(const JSCallbackInfo & info)603 void JSSelect::SetPaddingTop(const JSCallbackInfo& info)
604 {
605     if (info.Length() < 1) {
606         LOGE("The arg is wrong, it is supposed to have at least 1 argument");
607         return;
608     }
609     CalcDimension value;
610     if (!ParseJsDimensionVp(info[0], value)) {
611         return;
612     }
613     SelectModel::GetInstance()->SetPaddingTop(value);
614 }
615 
SetPaddingRight(const JSCallbackInfo & info)616 void JSSelect::SetPaddingRight(const JSCallbackInfo& info)
617 {
618     if (info.Length() < 1) {
619         LOGE("The arg is wrong, it is supposed to have at least 1 argument");
620         return;
621     }
622     CalcDimension value;
623     if (!ParseJsDimensionVp(info[0], value)) {
624         return;
625     }
626     SelectModel::GetInstance()->SetPaddingRight(value);
627 }
628 
SetPaddingBottom(const JSCallbackInfo & info)629 void JSSelect::SetPaddingBottom(const JSCallbackInfo& info)
630 {
631     if (info.Length() < 1) {
632         LOGE("The arg is wrong, it is supposed to have at least 1 argument");
633         return;
634     }
635     CalcDimension value;
636     if (!ParseJsDimensionVp(info[0], value)) {
637         return;
638     }
639     SelectModel::GetInstance()->SetPaddingBottom(value);
640 }
641 
SetSpace(const JSCallbackInfo & info)642 void JSSelect::SetSpace(const JSCallbackInfo& info)
643 {
644     if (info.Length() < 1) {
645         LOGI("The arg is wrong, it is supposed to have at least 1 argument");
646         return;
647     }
648 
649     auto selectTheme = GetTheme<SelectTheme>();
650 
651     CalcDimension value;
652     if (!ParseJsDimensionVp(info[0], value)) {
653         LOGI("JSSelect set space value is mull");
654         value = selectTheme->GetContentSpinnerPadding();
655     }
656     if (LessNotEqual(value.Value(), 0.0) || value.Unit() == DimensionUnit::PERCENT) {
657         LOGI("JSSelect set space value is to small");
658         value = selectTheme->GetContentSpinnerPadding();
659     }
660 
661     SelectModel::GetInstance()->SetSpace(value);
662 }
663 
SetArrowPosition(const JSCallbackInfo & info)664 void JSSelect::SetArrowPosition(const JSCallbackInfo& info)
665 {
666     if (info.Length() < 1) {
667         return;
668     }
669 
670     int32_t direction = 0;
671     if (!ParseJsInt32(info[0], direction)) {
672         direction = 0;
673     }
674 
675     if (static_cast<ArrowPosition>(direction) != ArrowPosition::START &&
676         static_cast<ArrowPosition>(direction) != ArrowPosition::END) {
677         direction = 0;
678     }
679 
680     SelectModel::GetInstance()->SetArrowPosition(static_cast<ArrowPosition>(direction));
681 }
682 
SetMenuAlign(const JSCallbackInfo & info)683 void JSSelect::SetMenuAlign(const JSCallbackInfo& info)
684 {
685     if (info.Length() < 1) {
686         return;
687     }
688 
689     if (!info[0]->IsNumber()) {
690         return;
691     }
692 
693     MenuAlign menuAlignObj;
694     menuAlignObj.alignType = static_cast<MenuAlignType>(info[0]->ToNumber<int32_t>());
695 
696     if (info.Length() > 1) {
697         if (!info[1]->IsObject()) {
698             return;
699         }
700         auto offsetObj = JSRef<JSObject>::Cast(info[1]);
701         CalcDimension dx;
702         auto dxValue = offsetObj->GetProperty("dx");
703         ParseJsDimensionVp(dxValue, dx);
704         CalcDimension dy;
705         auto dyValue = offsetObj->GetProperty("dy");
706         ParseJsDimensionVp(dyValue, dy);
707         menuAlignObj.offset = DimensionOffset(dx, dy);
708     }
709 
710     SelectModel::GetInstance()->SetMenuAlign(menuAlignObj);
711 }
712 } // namespace OHOS::Ace::Framework
713