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