• 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 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
22 
23 #include "base/log/ace_scoring_log.h"
24 #include "base/utils/utils.h"
25 #include "bridge/common/utils/utils.h"
26 #include "bridge/declarative_frontend/engine/functions/js_function.h"
27 #include "bridge/declarative_frontend/jsview/js_interactable_view.h"
28 #include "bridge/declarative_frontend/jsview/js_popups.h"
29 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
30 #include "bridge/declarative_frontend/jsview/js_symbol_modifier.h"
31 #include "bridge/declarative_frontend/jsview/models/select_model_impl.h"
32 #include "core/components_ng/base/view_abstract_model.h"
33 #include "core/components_ng/base/view_stack_processor.h"
34 #include "core/components_ng/pattern/menu/menu_theme.h"
35 #include "core/components_ng/pattern/select/select_model.h"
36 #include "core/components_ng/pattern/select/select_model_ng.h"
37 #include "core/components_ng/pattern/select/select_properties.h"
38 #include "core/components_v2/inspector/inspector_constants.h"
39 #include "core/pipeline/pipeline_base.h"
40 
41 namespace OHOS::Ace {
42 std::unique_ptr<SelectModel> SelectModel::instance_ = nullptr;
43 std::mutex SelectModel::mutex_;
44 
GetInstance()45 SelectModel* SelectModel::GetInstance()
46 {
47     if (!instance_) {
48         std::lock_guard<std::mutex> lock(mutex_);
49         if (!instance_) {
50 #ifdef NG_BUILD
51             instance_.reset(new NG::SelectModelNG());
52 #else
53             if (Container::IsCurrentUseNewPipeline()) {
54                 instance_.reset(new NG::SelectModelNG());
55             } else {
56                 instance_.reset(new Framework::SelectModelImpl());
57             }
58 #endif
59         }
60     }
61     return instance_.get();
62 }
63 } // namespace OHOS::Ace
64 
65 namespace OHOS::Ace::Framework {
Create(const JSCallbackInfo & info)66 void JSSelect::Create(const JSCallbackInfo& info)
67 {
68     if (info.Length() < 0) {
69         return;
70     }
71     if (info[0]->IsArray()) {
72         auto paramArray = JSRef<JSArray>::Cast(info[0]);
73         size_t size = paramArray->Length();
74         std::vector<SelectParam> params(size);
75         std::vector<SelectResObjParam> resObjVec(size);
76         for (size_t i = 0; i < size; i++) {
77             std::string value;
78             std::string icon;
79             RefPtr<ResourceObject> valueResObj;
80             RefPtr<ResourceObject> iconResObj;
81             JSRef<JSVal> indexVal = paramArray->GetValueAt(i);
82             if (!indexVal->IsObject()) {
83                 return;
84             }
85             auto indexObject = JSRef<JSObject>::Cast(indexVal);
86             auto selectValue = indexObject->GetProperty("value");
87             auto selectIcon = indexObject->GetProperty("icon");
88             auto selectSymbolIcon = indexObject->GetProperty("symbolIcon");
89             RefPtr<JSSymbolGlyphModifier> selectSymbol = AceType::MakeRefPtr<JSSymbolGlyphModifier>();
90             selectSymbol->symbol_ = selectSymbolIcon;
91             params[i].symbolModifier = selectSymbol;
92             ParseJsString(selectValue, value, valueResObj);
93             params[i].text = value;
94             if (valueResObj) {
95                 resObjVec[i].valueResObj = valueResObj;
96             }
97             if (selectSymbolIcon->IsObject()) {
98                 std::function<void(WeakPtr<NG::FrameNode>)> symbolApply = nullptr;
99                 JSViewAbstract::SetSymbolOptionApply(info, symbolApply, selectSymbolIcon);
100                 params[i].symbolIcon = symbolApply;
101             } else {
102                 ParseJsMedia(selectIcon, icon, iconResObj);
103                 params[i].icon = icon;
104                 resObjVec[i].iconResObj = iconResObj;
105             }
106         }
107         SelectModel::GetInstance()->Create(params);
108         if (SystemProperties::ConfigChangePerform()) {
109             if (resObjVec.size() > 0) {
110                 SelectModel::GetInstance()->CreateWithValueIconResourceObj(resObjVec);
111             }
112         }
113     }
114 }
115 
JSBind(BindingTarget globalObj)116 void JSSelect::JSBind(BindingTarget globalObj)
117 {
118     JSClass<JSSelect>::Declare("Select");
119     MethodOptions opt = MethodOptions::NONE;
120     JSClass<JSSelect>::StaticMethod("create", &JSSelect::Create, opt);
121 
122     JSClass<JSSelect>::StaticMethod("selected", &JSSelect::Selected, opt);
123     JSClass<JSSelect>::StaticMethod("value", &JSSelect::Value, opt);
124     JSClass<JSSelect>::StaticMethod("font", &JSSelect::Font, opt);
125     JSClass<JSSelect>::StaticMethod("fontColor", &JSSelect::FontColor, opt);
126     JSClass<JSSelect>::StaticMethod("backgroundColor", &JSSelect::BackgroundColor, opt);
127     JSClass<JSSelect>::StaticMethod("selectedOptionBgColor", &JSSelect::SelectedOptionBgColor, opt);
128     JSClass<JSSelect>::StaticMethod("selectedOptionFont", &JSSelect::SelectedOptionFont, opt);
129     JSClass<JSSelect>::StaticMethod("selectedOptionFontColor", &JSSelect::SelectedOptionFontColor, opt);
130     JSClass<JSSelect>::StaticMethod("optionBgColor", &JSSelect::OptionBgColor, opt);
131     JSClass<JSSelect>::StaticMethod("optionFont", &JSSelect::OptionFont, opt);
132     JSClass<JSSelect>::StaticMethod("optionFontColor", &JSSelect::OptionFontColor, opt);
133     JSClass<JSSelect>::StaticMethod("onSelect", &JSSelect::OnSelected, opt);
134     JSClass<JSSelect>::StaticMethod("space", &JSSelect::SetSpace, opt);
135     JSClass<JSSelect>::StaticMethod("arrowPosition", &JSSelect::SetArrowPosition, opt);
136     JSClass<JSSelect>::StaticMethod("menuAlign", &JSSelect::SetMenuAlign, opt);
137     JSClass<JSSelect>::StaticMethod("avoidance", &JSSelect::SetAvoidance, opt);
138 
139     // API7 onSelected deprecated
140     JSClass<JSSelect>::StaticMethod("onSelected", &JSSelect::OnSelected, opt);
141     JSClass<JSSelect>::StaticMethod("size", &JSSelect::JsSize);
142     JSClass<JSSelect>::StaticMethod("padding", &JSSelect::JsPadding);
143     JSClass<JSSelect>::StaticMethod("paddingTop", &JSSelect::SetPaddingTop, opt);
144     JSClass<JSSelect>::StaticMethod("paddingBottom", &JSSelect::SetPaddingBottom, opt);
145     JSClass<JSSelect>::StaticMethod("paddingLeft", &JSSelect::SetPaddingLeft, opt);
146     JSClass<JSSelect>::StaticMethod("paddingRight", &JSSelect::SetPaddingRight, opt);
147     JSClass<JSSelect>::StaticMethod("optionWidth", &JSSelect::SetOptionWidth, opt);
148     JSClass<JSSelect>::StaticMethod("optionHeight", &JSSelect::SetOptionHeight, opt);
149     JSClass<JSSelect>::StaticMethod("optionWidthFitTrigger", &JSSelect::SetOptionWidthFitTrigger, opt);
150     JSClass<JSSelect>::StaticMethod("menuBackgroundColor", &JSSelect::SetMenuBackgroundColor, opt);
151     JSClass<JSSelect>::StaticMethod("menuBackgroundBlurStyle", &JSSelect::SetMenuBackgroundBlurStyle, opt);
152     JSClass<JSSelect>::StaticMethod("divider", &JSSelect::SetDivider);
153     JSClass<JSSelect>::StaticMethod("controlSize", &JSSelect::SetControlSize);
154     JSClass<JSSelect>::StaticMethod("direction", &JSSelect::SetDirection, opt);
155     JSClass<JSSelect>::StaticMethod("dividerStyle", &JSSelect::SetDividerStyle);
156     JSClass<JSSelect>::StaticMethod("menuOutline", &JSSelect::SetMenuOutline, opt);
157     JSClass<JSSelect>::StaticMethod("arrowModifier", &JSSelect::SetArrowModifier, opt);
158     JSClass<JSSelect>::StaticMethod("textModifier", &JSSelect::SetTextModifier, opt);
159     JSClass<JSSelect>::StaticMethod("optionTextModifier", &JSSelect::SetOptionTextModifier, opt);
160     JSClass<JSSelect>::StaticMethod("selectedOptionTextModifier", &JSSelect::SetSelectedOptionTextModifier, opt);
161     JSClass<JSSelect>::StaticMethod("showInSubWindow", &JSSelect::SetShowInSubWindow);
162     JSClass<JSSelect>::StaticMethod("showDefaultSelectedIcon", &JSSelect::SetShowDefaultSelectedIcon);
163 
164     JSClass<JSSelect>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
165     JSClass<JSSelect>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
166     JSClass<JSSelect>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
167     JSClass<JSSelect>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
168     JSClass<JSSelect>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
169     JSClass<JSSelect>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
170     JSClass<JSSelect>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
171     JSClass<JSSelect>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
172     JSClass<JSSelect>::InheritAndBind<JSViewAbstract>(globalObj);
173 }
174 
ParseSelectedObject(const JSCallbackInfo & info,const JSRef<JSVal> & changeEventVal)175 void ParseSelectedObject(const JSCallbackInfo& info, const JSRef<JSVal>& changeEventVal)
176 {
177     CHECK_NULL_VOID(changeEventVal->IsFunction());
178 
179     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
180     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
181     auto onSelect = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](int32_t index) {
182         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
183         ACE_SCORING_EVENT("Select.SelectChangeEvent");
184         PipelineContext::SetCallBackNode(node);
185         auto newJSVal = JSRef<JSVal>::Make(ToJSValue(index));
186         func->ExecuteJS(1, &newJSVal);
187     };
188     SelectModel::GetInstance()->SetSelectChangeEvent(onSelect);
189 }
190 
Selected(const JSCallbackInfo & info)191 void JSSelect::Selected(const JSCallbackInfo& info)
192 {
193     if (info.Length() < 1 || info.Length() > 2) {
194         return;
195     }
196 
197     int32_t value = 0;
198     RefPtr<ResourceObject> resObj;
199     bool result = ParseJsInteger<int32_t>(info[0], value, resObj);
200 
201     if (value < -1) {
202         value = -1;
203     }
204     JSRef<JSVal> changeEventVal;
205     auto selectedVal = info[0];
206     if (!result && selectedVal->IsObject()) {
207         JSRef<JSObject> obj = JSRef<JSObject>::Cast(selectedVal);
208         selectedVal = obj->GetProperty("value");
209         changeEventVal = obj->GetProperty("$value");
210         ParseJsInteger<int32_t>(selectedVal, value, resObj);
211     } else if (info.Length() > 1) {
212         changeEventVal = info[1];
213     }
214 
215     if (changeEventVal->IsFunction()) {
216         ParseSelectedObject(info, changeEventVal);
217     }
218     if (SystemProperties::ConfigChangePerform()) {
219         SelectModel::GetInstance()->CreateWithIntegerResourceObj(resObj);
220     }
221     TAG_LOGD(AceLogTag::ACE_SELECT_COMPONENT, "set selected index %{public}d", value);
222     SelectModel::GetInstance()->SetSelected(value);
223 }
224 
ParseValueObject(const JSCallbackInfo & info,const JSRef<JSVal> & changeEventVal)225 void ParseValueObject(const JSCallbackInfo& info, const JSRef<JSVal>& changeEventVal)
226 {
227     CHECK_NULL_VOID(changeEventVal->IsFunction());
228 
229     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
230     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
231     auto onSelect = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
232                         const std::string& value) {
233         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
234         ACE_SCORING_EVENT("Select.ValueChangeEvent");
235         PipelineContext::SetCallBackNode(node);
236         auto newJSVal = JSRef<JSVal>::Make(ToJSValue(value));
237         func->ExecuteJS(1, &newJSVal);
238     };
239     SelectModel::GetInstance()->SetValueChangeEvent(onSelect);
240 }
241 
Value(const JSCallbackInfo & info)242 void JSSelect::Value(const JSCallbackInfo& info)
243 {
244     if (info.Length() < 1 || info.Length() > 2) {
245         return;
246     }
247 
248     std::string value;
249     RefPtr<ResourceObject> resObj;
250     bool result = ParseJsString(info[0], value, resObj);
251 
252     JSRef<JSVal> changeEventVal;
253     auto selectedVal = info[0];
254     if (!result && selectedVal->IsObject()) {
255         JSRef<JSObject> obj = JSRef<JSObject>::Cast(selectedVal);
256         selectedVal = obj->GetProperty("value");
257         changeEventVal = obj->GetProperty("$value");
258         ParseJsString(selectedVal, value, resObj);
259     } else if (info.Length() > 1) {
260         changeEventVal = info[1];
261     }
262 
263     if (changeEventVal->IsFunction()) {
264         ParseValueObject(info, changeEventVal);
265     }
266     if (SystemProperties::ConfigChangePerform()) {
267         SelectModel::GetInstance()->CreateWithStringResourceObj(resObj);
268     }
269     TAG_LOGD(AceLogTag::ACE_SELECT_COMPONENT, "value set by user");
270     SelectModel::GetInstance()->SetValue(value);
271 }
272 
Font(const JSCallbackInfo & info)273 void JSSelect::Font(const JSCallbackInfo& info)
274 {
275     if (info[0]->IsNull() || info[0]->IsUndefined()) {
276         ResetFont(SelectFontType::SELECT);
277         return;
278     }
279     if (!info[0]->IsObject()) {
280         return;
281     }
282     auto param = JSRef<JSObject>::Cast(info[0]);
283     ParseFontSize(param->GetProperty("size"), SelectFontType::SELECT);
284     ParseFontWeight(param->GetProperty("weight"), SelectFontType::SELECT);
285     ParseFontFamily(param->GetProperty("family"), SelectFontType::SELECT);
286     ParseFontStyle(param->GetProperty("style"), SelectFontType::SELECT);
287 }
288 
ParseFontSize(const JSRef<JSVal> & jsValue,SelectFontType type)289 void JSSelect::ParseFontSize(const JSRef<JSVal>& jsValue, SelectFontType type)
290 {
291     CalcDimension fontSize;
292     if (!ParseJsDimensionFp(jsValue, fontSize)) {
293         ResetFontSize(type);
294         return;
295     }
296     if (type == SelectFontType::SELECT) {
297         SelectModel::GetInstance()->SetFontSize(fontSize);
298     } else if (type == SelectFontType::OPTION) {
299         SelectModel::GetInstance()->SetOptionFontSize(fontSize);
300     } else if (type == SelectFontType::SELECTED_OPTION) {
301         SelectModel::GetInstance()->SetSelectedOptionFontSize(fontSize);
302     }
303 }
304 
ParseFontWeight(const JSRef<JSVal> & jsValue,SelectFontType type)305 void JSSelect::ParseFontWeight(const JSRef<JSVal>& jsValue, SelectFontType type)
306 {
307     std::string weight;
308     if (jsValue->IsNumber()) {
309         weight = std::to_string(jsValue->ToNumber<int32_t>());
310     } else {
311         ParseJsString(jsValue, weight);
312     }
313     if (type == SelectFontType::SELECT) {
314         SelectModel::GetInstance()->SetFontWeight(ConvertStrToFontWeight(weight, FontWeight::MEDIUM));
315     } else if (type == SelectFontType::OPTION) {
316         SelectModel::GetInstance()->SetOptionFontWeight(ConvertStrToFontWeight(weight, FontWeight::REGULAR));
317     } else if (type == SelectFontType::SELECTED_OPTION) {
318         SelectModel::GetInstance()->SetSelectedOptionFontWeight(ConvertStrToFontWeight(weight, FontWeight::REGULAR));
319     }
320 }
321 
ParseFontFamily(const JSRef<JSVal> & jsValue,SelectFontType type)322 void JSSelect::ParseFontFamily(const JSRef<JSVal>& jsValue, SelectFontType type)
323 {
324     if (!jsValue->IsString()) {
325         ResetFontFamily(type);
326         return;
327     }
328     auto family = ConvertStrToFontFamilies(jsValue->ToString());
329     if (type == SelectFontType::SELECT) {
330         SelectModel::GetInstance()->SetFontFamily(family);
331     } else if (type == SelectFontType::OPTION) {
332         SelectModel::GetInstance()->SetOptionFontFamily(family);
333     } else if (type == SelectFontType::SELECTED_OPTION) {
334         SelectModel::GetInstance()->SetSelectedOptionFontFamily(family);
335     }
336 }
337 
ParseFontStyle(const JSRef<JSVal> & jsValue,SelectFontType type)338 void JSSelect::ParseFontStyle(const JSRef<JSVal>& jsValue, SelectFontType type)
339 {
340     if (!jsValue->IsNumber()) {
341         ResetFontStyle(type);
342         return;
343     }
344     auto styleVal = static_cast<FontStyle>(jsValue->ToNumber<int32_t>());
345     if (type == SelectFontType::SELECT) {
346         SelectModel::GetInstance()->SetItalicFontStyle(styleVal);
347     } else if (type == SelectFontType::OPTION) {
348         SelectModel::GetInstance()->SetOptionItalicFontStyle(styleVal);
349     } else if (type == SelectFontType::SELECTED_OPTION) {
350         SelectModel::GetInstance()->SetSelectedOptionItalicFontStyle(styleVal);
351     }
352 }
353 
ResetFontSize(SelectFontType type)354 void JSSelect::ResetFontSize(SelectFontType type)
355 {
356     auto selectTheme = GetTheme<SelectTheme>();
357     CHECK_NULL_VOID(selectTheme);
358     if (type == SelectFontType::OPTION) {
359         SelectModel::GetInstance()->SetOptionFontSize(selectTheme->GetMenuFontSize());
360         return;
361     } else if (type == SelectFontType::SELECTED_OPTION) {
362         SelectModel::GetInstance()->SetSelectedOptionFontSize(selectTheme->GetMenuFontSize());
363         return;
364     }
365     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
366         SelectModel::GetInstance()->SetFontSize(selectTheme->GetFontSize());
367     } else {
368         auto controlSize = SelectModel::GetInstance()->GetControlSize();
369         SelectModel::GetInstance()->SetFontSize(selectTheme->GetFontSize(controlSize));
370     }
371 }
372 
ResetFontWeight(SelectFontType type)373 void JSSelect::ResetFontWeight(SelectFontType type)
374 {
375     if (type == SelectFontType::SELECT) {
376         SelectModel::GetInstance()->SetFontWeight(FontWeight::MEDIUM);
377     } else if (type == SelectFontType::OPTION) {
378         SelectModel::GetInstance()->SetOptionFontWeight(FontWeight::REGULAR);
379     } else if (type == SelectFontType::SELECTED_OPTION) {
380         SelectModel::GetInstance()->SetSelectedOptionFontWeight(FontWeight::REGULAR);
381     }
382 }
383 
ResetFontFamily(SelectFontType type)384 void JSSelect::ResetFontFamily(SelectFontType type)
385 {
386     auto textTheme = GetTheme<TextTheme>();
387     CHECK_NULL_VOID(textTheme);
388     if (type == SelectFontType::SELECT) {
389         SelectModel::GetInstance()->SetFontFamily(textTheme->GetTextStyle().GetFontFamilies());
390     } else if (type == SelectFontType::OPTION) {
391         SelectModel::GetInstance()->SetOptionFontFamily(textTheme->GetTextStyle().GetFontFamilies());
392     } else if (type == SelectFontType::SELECTED_OPTION) {
393         SelectModel::GetInstance()->SetSelectedOptionFontFamily(textTheme->GetTextStyle().GetFontFamilies());
394     }
395 }
396 
ResetFontStyle(SelectFontType type)397 void JSSelect::ResetFontStyle(SelectFontType type)
398 {
399     auto textTheme = GetTheme<TextTheme>();
400     CHECK_NULL_VOID(textTheme);
401     if (type == SelectFontType::SELECT) {
402         SelectModel::GetInstance()->SetItalicFontStyle(textTheme->GetTextStyle().GetFontStyle());
403     } else if (type == SelectFontType::OPTION) {
404         SelectModel::GetInstance()->SetOptionItalicFontStyle(textTheme->GetTextStyle().GetFontStyle());
405     } else if (type == SelectFontType::SELECTED_OPTION) {
406         SelectModel::GetInstance()->SetSelectedOptionItalicFontStyle(textTheme->GetTextStyle().GetFontStyle());
407     }
408 }
409 
ResetFont(SelectFontType type)410 void JSSelect::ResetFont(SelectFontType type)
411 {
412     ResetFontSize(type);
413     ResetFontWeight(type);
414     ResetFontFamily(type);
415     ResetFontStyle(type);
416 }
417 
FontColor(const JSCallbackInfo & info)418 void JSSelect::FontColor(const JSCallbackInfo& info)
419 {
420     if (info.Length() < 1) {
421         return;
422     }
423 
424     Color textColor;
425     RefPtr<ResourceObject> resObj;
426     bool isNormal = false;
427     if (!ParseJsColor(info[0], textColor, resObj)) {
428         SelectModel::GetInstance()->ResetFontColor();
429     } else {
430         SelectModel::GetInstance()->SetFontColor(textColor);
431         isNormal = true;
432     }
433     if (SystemProperties::ConfigChangePerform()) {
434         SelectModel::GetInstance()->SetFontColorByUser(isNormal);
435         SelectModel::GetInstance()->CreateWithColorResourceObj(resObj, SelectColorType::FONT_COLOR);
436     }
437 }
438 
BackgroundColor(const JSCallbackInfo & info)439 void JSSelect::BackgroundColor(const JSCallbackInfo& info)
440 {
441     if (info.Length() < 1) {
442         return;
443     }
444     Color backgroundColor;
445     RefPtr<ResourceObject> resObj;
446     if (!ParseJsColor(info[0], backgroundColor, resObj)) {
447         backgroundColor = Color::TRANSPARENT;
448     }
449     if (SystemProperties::ConfigChangePerform()) {
450         SelectModel::GetInstance()->CreateWithColorResourceObj(resObj, SelectColorType::BACKGROUND_COLOR);
451     }
452     SelectModel::GetInstance()->BackgroundColor(backgroundColor);
453 }
454 
SelectedOptionBgColor(const JSCallbackInfo & info)455 void JSSelect::SelectedOptionBgColor(const JSCallbackInfo& info)
456 {
457     if (info.Length() < 1) {
458         return;
459     }
460     Color bgColor;
461     RefPtr<ResourceObject> resObj;
462     bool isValidValue = true;
463     if (!ParseJsColor(info[0], bgColor, resObj)) {
464         if (info[0]->IsUndefined() || info[0]->IsNull()) {
465             auto pipeline = PipelineBase::GetCurrentContext();
466             CHECK_NULL_VOID(pipeline);
467             auto theme = pipeline->GetTheme<SelectTheme>();
468             CHECK_NULL_VOID(theme);
469             bgColor = theme->GetSelectedColor();
470             isValidValue = false;
471         } else {
472             return;
473         }
474     }
475     if (SystemProperties::ConfigChangePerform()) {
476         SelectModel::GetInstance()->SetSelectedOptionBgColorByUser(isValidValue);
477         SelectModel::GetInstance()->CreateWithColorResourceObj(resObj, SelectColorType::SELECTED_OPTION_BG_COLOR);
478     }
479     SelectModel::GetInstance()->SetSelectedOptionBgColor(bgColor);
480 }
481 
SelectedOptionFont(const JSCallbackInfo & info)482 void JSSelect::SelectedOptionFont(const JSCallbackInfo& info)
483 {
484     if (info[0]->IsNull() || info[0]->IsUndefined()) {
485         ResetFont(SelectFontType::SELECTED_OPTION);
486         return;
487     }
488     if (!info[0]->IsObject()) {
489         return;
490     }
491     auto param = JSRef<JSObject>::Cast(info[0]);
492     ParseFontSize(param->GetProperty("size"), SelectFontType::SELECTED_OPTION);
493     ParseFontWeight(param->GetProperty("weight"), SelectFontType::SELECTED_OPTION);
494     ParseFontFamily(param->GetProperty("family"), SelectFontType::SELECTED_OPTION);
495     ParseFontStyle(param->GetProperty("style"), SelectFontType::SELECTED_OPTION);
496 }
497 
SelectedOptionFontColor(const JSCallbackInfo & info)498 void JSSelect::SelectedOptionFontColor(const JSCallbackInfo& info)
499 {
500     if (info.Length() < 1) {
501         return;
502     }
503     Color textColor;
504     RefPtr<ResourceObject> resObj;
505     bool isValidValue = true;
506     if (!ParseJsColor(info[0], textColor, resObj)) {
507         if (info[0]->IsNull() || info[0]->IsUndefined()) {
508             auto pipeline = PipelineBase::GetCurrentContext();
509             CHECK_NULL_VOID(pipeline);
510             auto theme = pipeline->GetTheme<SelectTheme>();
511             CHECK_NULL_VOID(theme);
512             textColor = theme->GetSelectedColorText();
513             isValidValue = false;
514         } else {
515             return;
516         }
517     }
518     if (SystemProperties::ConfigChangePerform()) {
519         SelectModel::GetInstance()->SetSelectedOptionFontColorByUser(isValidValue);
520         SelectModel::GetInstance()->CreateWithColorResourceObj(resObj, SelectColorType::SELECTED_OPTION_FONT_COLOR);
521     }
522     SelectModel::GetInstance()->SetSelectedOptionFontColor(textColor);
523 }
524 
OptionBgColor(const JSCallbackInfo & info)525 void JSSelect::OptionBgColor(const JSCallbackInfo& info)
526 {
527     if (info.Length() < 1) {
528         return;
529     }
530     Color bgColor;
531     RefPtr<ResourceObject> resObj;
532     bool isValidValue = true;
533     if (!ParseJsColor(info[0], bgColor, resObj)) {
534         if (!(info[0]->IsUndefined() || info[0]->IsNull())) {
535             return;
536         }
537         auto pipeline = PipelineBase::GetCurrentContextSafelyWithCheck();
538         CHECK_NULL_VOID(pipeline);
539         auto theme = pipeline->GetTheme<SelectTheme>();
540         CHECK_NULL_VOID(theme);
541         bgColor = theme->GetBackgroundColor();
542         isValidValue = false;
543     }
544     SelectModel::GetInstance()->SetOptionBgColor(bgColor);
545     if (SystemProperties::ConfigChangePerform()) {
546         SelectModel::GetInstance()->SetOptionBgColorByUser(isValidValue);
547         SelectModel::GetInstance()->CreateWithColorResourceObj(resObj, SelectColorType::OPTION_BG_COLOR);
548     }
549 }
550 
OptionFont(const JSCallbackInfo & info)551 void JSSelect::OptionFont(const JSCallbackInfo& info)
552 {
553     if (info[0]->IsNull() || info[0]->IsUndefined()) {
554         ResetFont(SelectFontType::OPTION);
555         return;
556     }
557     if (!info[0]->IsObject()) {
558         return;
559     }
560     auto param = JSRef<JSObject>::Cast(info[0]);
561     ParseFontSize(param->GetProperty("size"), SelectFontType::OPTION);
562     ParseFontWeight(param->GetProperty("weight"), SelectFontType::OPTION);
563     ParseFontFamily(param->GetProperty("family"), SelectFontType::OPTION);
564     ParseFontStyle(param->GetProperty("style"), SelectFontType::OPTION);
565 }
566 
OptionFontColor(const JSCallbackInfo & info)567 void JSSelect::OptionFontColor(const JSCallbackInfo& info)
568 {
569     if (info.Length() < 1) {
570         return;
571     }
572     Color textColor;
573     RefPtr<ResourceObject> resObj;
574     bool isValidValue = true;
575     if (!ParseJsColor(info[0], textColor, resObj)) {
576         if (info[0]->IsUndefined() || info[0]->IsNull()) {
577             auto pipeline = PipelineBase::GetCurrentContext();
578             CHECK_NULL_VOID(pipeline);
579             auto theme = pipeline->GetTheme<SelectTheme>();
580             CHECK_NULL_VOID(theme);
581             textColor = theme->GetMenuFontColor();
582             isValidValue = false;
583         } else {
584             return;
585         }
586     }
587     if (SystemProperties::ConfigChangePerform()) {
588         SelectModel::GetInstance()->SetOptionFontColorByUser(isValidValue);
589         SelectModel::GetInstance()->CreateWithColorResourceObj(resObj, SelectColorType::OPTION_FONT_COLOR);
590     }
591     TAG_LOGD(AceLogTag::ACE_SELECT_COMPONENT, "set option font color %{public}s", textColor.ColorToString().c_str());
592     SelectModel::GetInstance()->SetOptionFontColor(textColor);
593 }
594 
OnSelected(const JSCallbackInfo & info)595 void JSSelect::OnSelected(const JSCallbackInfo& info)
596 {
597     if (!info[0]->IsFunction()) {
598         return;
599     }
600     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
601     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
602     auto onSelect = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
603                         int32_t index, const std::string& value) {
604         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
605         ACE_SCORING_EVENT("Select.onSelect");
606         TAG_LOGD(AceLogTag::ACE_SELECT_COMPONENT, "fire change event %{public}d %{public}s", index, value.c_str());
607         PipelineContext::SetCallBackNode(node);
608         JSRef<JSVal> params[2];
609         params[0] = JSRef<JSVal>::Make(ToJSValue(index));
610         params[1] = JSRef<JSVal>::Make(ToJSValue(value));
611         func->ExecuteJS(2, params);
612         UiSessionManager::GetInstance()->ReportComponentChangeEvent("event", "Select.onSelect");
613     };
614     SelectModel::GetInstance()->SetOnSelect(std::move(onSelect));
615     info.ReturnSelf();
616 }
617 
JsSize(const JSCallbackInfo & info)618 void JSSelect::JsSize(const JSCallbackInfo& info)
619 {
620     if (!info[0]->IsObject()) {
621         JSViewAbstract::JsWidth(JSVal::Undefined());
622         JSViewAbstract::JsHeight(JSVal::Undefined());
623         return;
624     }
625     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
626     JSViewAbstract::JsWidth(sizeObj->GetProperty("width"));
627     JSViewAbstract::JsHeight(sizeObj->GetProperty("height"));
628 }
629 
JsPadding(const JSCallbackInfo & info)630 void JSSelect::JsPadding(const JSCallbackInfo& info)
631 {
632     if (!info[0]->IsString() && !info[0]->IsNumber() && !info[0]->IsObject()) {
633         return;
634     }
635 
636     if (info[0]->IsObject()) {
637         JSRef<JSObject> paddingObj = JSRef<JSObject>::Cast(info[0]);
638         CommonCalcDimension commonCalcDimension;
639         JSViewAbstract::ParseCommonMarginOrPaddingCorner(paddingObj, commonCalcDimension);
640         if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() ||
641             commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) {
642             ViewAbstractModel::GetInstance()->SetPaddings(commonCalcDimension.top, commonCalcDimension.bottom,
643                 commonCalcDimension.left, commonCalcDimension.right);
644             return;
645         }
646     }
647 
648     CalcDimension value;
649     if (!ParseJsDimensionVp(info[0], value)) {
650         value.Reset();
651     }
652     SelectModel::GetInstance()->SetPadding(value);
653 }
654 
SetPaddingLeft(const JSCallbackInfo & info)655 void JSSelect::SetPaddingLeft(const JSCallbackInfo& info)
656 {
657     if (info.Length() < 1) {
658         return;
659     }
660     CalcDimension value;
661     if (!ParseJsDimensionVp(info[0], value)) {
662         return;
663     }
664     SelectModel::GetInstance()->SetPaddingLeft(value);
665 }
666 
SetPaddingTop(const JSCallbackInfo & info)667 void JSSelect::SetPaddingTop(const JSCallbackInfo& info)
668 {
669     if (info.Length() < 1) {
670         return;
671     }
672     CalcDimension value;
673     if (!ParseJsDimensionVp(info[0], value)) {
674         return;
675     }
676     SelectModel::GetInstance()->SetPaddingTop(value);
677 }
678 
SetPaddingRight(const JSCallbackInfo & info)679 void JSSelect::SetPaddingRight(const JSCallbackInfo& info)
680 {
681     if (info.Length() < 1) {
682         return;
683     }
684     CalcDimension value;
685     if (!ParseJsDimensionVp(info[0], value)) {
686         return;
687     }
688     SelectModel::GetInstance()->SetPaddingRight(value);
689 }
690 
SetPaddingBottom(const JSCallbackInfo & info)691 void JSSelect::SetPaddingBottom(const JSCallbackInfo& info)
692 {
693     if (info.Length() < 1) {
694         return;
695     }
696     CalcDimension value;
697     if (!ParseJsDimensionVp(info[0], value)) {
698         return;
699     }
700     SelectModel::GetInstance()->SetPaddingBottom(value);
701 }
702 
SetSpace(const JSCallbackInfo & info)703 void JSSelect::SetSpace(const JSCallbackInfo& info)
704 {
705     if (info.Length() < 1) {
706         return;
707     }
708 
709     auto selectTheme = GetTheme<SelectTheme>();
710 
711     CalcDimension value;
712     if (!ParseJsDimensionVp(info[0], value)) {
713         value = selectTheme->GetContentSpinnerPadding();
714     }
715     if (LessNotEqual(value.Value(), 0.0) || value.Unit() == DimensionUnit::PERCENT) {
716         value = selectTheme->GetContentSpinnerPadding();
717     }
718 
719     SelectModel::GetInstance()->SetSpace(value);
720 }
721 
SetArrowPosition(const JSCallbackInfo & info)722 void JSSelect::SetArrowPosition(const JSCallbackInfo& info)
723 {
724     if (info.Length() < 1) {
725         return;
726     }
727 
728     int32_t direction = 0;
729     if (!ParseJsInt32(info[0], direction)) {
730         direction = 0;
731     }
732 
733     if (static_cast<ArrowPosition>(direction) != ArrowPosition::START &&
734         static_cast<ArrowPosition>(direction) != ArrowPosition::END) {
735         direction = 0;
736     }
737 
738     SelectModel::GetInstance()->SetArrowPosition(static_cast<ArrowPosition>(direction));
739 }
740 
SetMenuAlign(const JSCallbackInfo & info)741 void JSSelect::SetMenuAlign(const JSCallbackInfo& info)
742 {
743     if (info.Length() < 1) {
744         return;
745     }
746 
747     MenuAlign menuAlignObj;
748 
749     if (!info[0]->IsNumber()) {
750         if (!(info[0]->IsUndefined() || info[0]->IsNull())) {
751             return;
752         }
753     } else {
754         menuAlignObj.alignType = static_cast<MenuAlignType>(info[0]->ToNumber<int32_t>());
755         TAG_LOGD(AceLogTag::ACE_SELECT_COMPONENT, "set alignType %{public}d", menuAlignObj.alignType);
756     }
757 
758     if (info.Length() > 1) {
759         if (info[1]->IsUndefined() || info[1]->IsNull()) {
760             SelectModel::GetInstance()->SetMenuAlign(menuAlignObj);
761             return;
762         }
763         if (!info[1]->IsObject()) {
764             return;
765         }
766         auto offsetObj = JSRef<JSObject>::Cast(info[1]);
767         CalcDimension dx;
768         auto dxValue = offsetObj->GetProperty("dx");
769         ParseJsDimensionVp(dxValue, dx);
770         CalcDimension dy;
771         auto dyValue = offsetObj->GetProperty("dy");
772         ParseJsDimensionVp(dyValue, dy);
773         TAG_LOGD(AceLogTag::ACE_SELECT_COMPONENT, "set offset dx %{public}f dy %{public}f", dx.Value(), dy.Value());
774         menuAlignObj.offset = DimensionOffset(dx, dy);
775     }
776 
777     SelectModel::GetInstance()->SetMenuAlign(menuAlignObj);
778 }
779 
SetAvoidance(const JSCallbackInfo & info)780 void JSSelect::SetAvoidance(const JSCallbackInfo& info)
781 {
782     AvoidanceMode mode = AvoidanceMode::COVER_TARGET;
783     if (info.Length() < 1) {
784         return;
785     }
786     if (!info[0]->IsNumber()) {
787         SelectModel::GetInstance()->SetAvoidance(mode);
788         return;
789     }
790 
791     int32_t value = info[0]->ToNumber<int32_t>();
792     switch (value) {
793         case static_cast<int32_t>(AvoidanceMode::COVER_TARGET):
794             mode = AvoidanceMode::COVER_TARGET;
795             break;
796         case static_cast<int32_t>(AvoidanceMode::AVOID_AROUND_TARGET):
797             mode = AvoidanceMode::AVOID_AROUND_TARGET;
798             break;
799         default:
800             break;
801     }
802     SelectModel::GetInstance()->SetAvoidance(mode);
803 }
804 
IsPercentStr(std::string & percent)805 bool JSSelect::IsPercentStr(std::string& percent)
806 {
807     if (percent.find("%") != std::string::npos) {
808         size_t index = percent.find("%");
809         percent = percent.substr(0, index);
810         return true;
811     }
812     return false;
813 }
814 
SetOptionWidth(const JSCallbackInfo & info)815 void JSSelect::SetOptionWidth(const JSCallbackInfo& info)
816 {
817     CalcDimension value;
818     if (info[0]->IsUndefined() || info[0]->IsNull()) {
819         SelectModel::GetInstance()->SetHasOptionWidth(false);
820         SelectModel::GetInstance()->SetOptionWidth(value);
821         return;
822     } else if (info[0]->IsString()) {
823         SelectModel::GetInstance()->SetHasOptionWidth(true);
824         std::string modeFlag = info[0]->ToString();
825         if (modeFlag.compare("fit_content") == 0) {
826             SelectModel::GetInstance()->SetOptionWidthFitTrigger(false);
827         } else if (modeFlag.compare("fit_trigger") == 0) {
828             SelectModel::GetInstance()->SetOptionWidthFitTrigger(true);
829         } else if (IsPercentStr(modeFlag)) {
830             return;
831         } else {
832             ParseJsDimensionVpNG(info[0], value);
833             if (value.IsNegative()) {
834                 value.Reset();
835             }
836             SelectModel::GetInstance()->SetOptionWidth(value);
837         }
838     } else {
839         SelectModel::GetInstance()->SetHasOptionWidth(true);
840         ParseJsDimensionVpNG(info[0], value);
841         if (value.IsNegative()) {
842             value.Reset();
843         }
844         SelectModel::GetInstance()->SetOptionWidth(value);
845     }
846 }
847 
SetOptionHeight(const JSCallbackInfo & info)848 void JSSelect::SetOptionHeight(const JSCallbackInfo& info)
849 {
850     CalcDimension value;
851     if (info[0]->IsUndefined() || info[0]->IsNull()) {
852         return;
853     } else if (info[0]->IsString()) {
854         std::string modeFlag = info[0]->ToString();
855         if (IsPercentStr(modeFlag)) {
856             return;
857         } else {
858             ParseJsDimensionVpNG(info[0], value);
859             if (value.IsNonPositive()) {
860                 return;
861             }
862             SelectModel::GetInstance()->SetOptionHeight(value);
863         }
864     } else {
865         ParseJsDimensionVpNG(info[0], value);
866         if (value.IsNonPositive()) {
867             return;
868         }
869         SelectModel::GetInstance()->SetOptionHeight(value);
870     }
871 }
872 
SetOptionWidthFitTrigger(const JSCallbackInfo & info)873 void JSSelect::SetOptionWidthFitTrigger(const JSCallbackInfo& info)
874 {
875     bool isFitTrigger = false;
876     if (info[0]->IsBoolean()) {
877         isFitTrigger = info[0]->ToBoolean();
878     }
879 
880     SelectModel::GetInstance()->SetOptionWidthFitTrigger(isFitTrigger);
881 }
882 
SetMenuBackgroundColor(const JSCallbackInfo & info)883 void JSSelect::SetMenuBackgroundColor(const JSCallbackInfo& info)
884 {
885     if (info.Length() < 1) {
886         return;
887     }
888     Color menuBackgroundColor;
889     RefPtr<ResourceObject> resObj;
890     if (!ParseJsColor(info[0], menuBackgroundColor, resObj)) {
891         if (info[0]->IsNull() || info[0]->IsUndefined()) {
892             menuBackgroundColor = Color::TRANSPARENT;
893         } else {
894             return;
895         }
896     }
897     TAG_LOGD(AceLogTag::ACE_SELECT_COMPONENT, "set menu background color %{public}s",
898         menuBackgroundColor.ColorToString().c_str());
899     SelectModel::GetInstance()->SetMenuBackgroundColor(menuBackgroundColor);
900     if (SystemProperties::ConfigChangePerform()) {
901         SelectModel::GetInstance()->SetMenuBackgroundColorByUser(true);
902         SelectModel::GetInstance()->CreateWithColorResourceObj(resObj, SelectColorType::MENU_BACKGROUND_COLOR);
903     }
904 }
905 
SetMenuBackgroundBlurStyle(const JSCallbackInfo & info)906 void JSSelect::SetMenuBackgroundBlurStyle(const JSCallbackInfo& info)
907 {
908     if (info.Length() < 1) {
909         return;
910     }
911 
912     BlurStyleOption styleOption;
913     if (info[0]->IsNumber()) {
914         auto blurStyle = info[0]->ToNumber<int32_t>();
915         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
916             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
917             styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
918             TAG_LOGD(AceLogTag::ACE_SELECT_COMPONENT, "set menu blurStyle %{public}d", blurStyle);
919             SelectModel::GetInstance()->SetMenuBackgroundBlurStyle(styleOption);
920         }
921     }
922 }
923 
SetControlSize(const JSCallbackInfo & info)924 void JSSelect::SetControlSize(const JSCallbackInfo& info)
925 {
926     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
927         return;
928     }
929     if (info.Length() < 1) {
930         return;
931     }
932     if (info[0]->IsNumber()) {
933         auto controlSize = static_cast<ControlSize>(info[0]->ToNumber<int32_t>());
934         SelectModel::GetInstance()->SetControlSize(controlSize);
935     } else {
936         LOGE("JSSelect::SetControlSize Is not Number.");
937     }
938 }
939 
SetDivider(const JSCallbackInfo & info)940 void JSSelect::SetDivider(const JSCallbackInfo& info)
941 {
942     NG::SelectDivider divider;
943     auto selectTheme = GetTheme<SelectTheme>();
944     Dimension defaultStrokeWidth = 0.0_vp;
945     Dimension defaultMargin = -1.0_vp;
946     Color defaultColor = Color::TRANSPARENT;
947     // Set default strokeWidth and color
948     if (selectTheme) {
949         defaultStrokeWidth = selectTheme->GetDefaultDividerWidth();
950         defaultColor = selectTheme->GetLineColor();
951         divider.strokeWidth = defaultStrokeWidth;
952         divider.color = defaultColor;
953         divider.startMargin = defaultMargin;
954         divider.endMargin = defaultMargin;
955     }
956 
957     if (info.Length() >= 1 && info[0]->IsObject()) {
958         JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
959 
960         Dimension strokeWidth = defaultStrokeWidth;
961         if (ConvertFromJSValueNG(obj->GetProperty("strokeWidth"), strokeWidth) && CheckDividerValue(strokeWidth)) {
962             divider.strokeWidth = strokeWidth;
963         }
964 
965         Color color = defaultColor;
966         if (ConvertFromJSValue(obj->GetProperty("color"), color)) {
967             divider.color = color;
968         }
969 
970         Dimension startMargin = defaultMargin;
971         if (ConvertFromJSValueNG(obj->GetProperty("startMargin"), startMargin) && CheckDividerValue(startMargin)) {
972             divider.startMargin = startMargin;
973         }
974 
975         Dimension endMargin = defaultMargin;
976         if (ConvertFromJSValueNG(obj->GetProperty("endMargin"), endMargin) &&  CheckDividerValue(endMargin)) {
977             divider.endMargin = endMargin;
978         }
979     } else if (info.Length() >= 1 && info[0]->IsNull()) {
980         divider.strokeWidth = 0.0_vp;
981     }
982     SelectModel::GetInstance()->SetDivider(divider);
983 }
984 
SetDividerStyle(const JSCallbackInfo & info)985 void JSSelect::SetDividerStyle(const JSCallbackInfo& info)
986 {
987     NG::SelectDivider divider;
988     Dimension defaultStrokeWidth = 0.0_vp;
989     Dimension defaultMargin = -1.0_vp;
990     Color defaultColor = Color::TRANSPARENT;
991     auto selectTheme = GetTheme<SelectTheme>();
992     if (selectTheme) {
993         defaultStrokeWidth = selectTheme->GetDefaultDividerWidth();
994         defaultColor = selectTheme->GetLineColor();
995         divider.strokeWidth = defaultStrokeWidth;
996         divider.color = defaultColor;
997         divider.startMargin = defaultMargin;
998         divider.endMargin = defaultMargin;
999     }
1000     if (info.Length() >= 1 && info[0]->IsObject()) {
1001         auto mode = DividerMode::FLOATING_ABOVE_MENU;
1002         divider.isDividerStyle = true;
1003         JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
1004         CalcDimension value;
1005         if (ParseLengthMetricsToPositiveDimension(obj->GetProperty("strokeWidth"), value) && value.IsNonNegative()) {
1006             divider.strokeWidth = value;
1007         }
1008         if (ParseLengthMetricsToPositiveDimension(obj->GetProperty("startMargin"), value) && value.IsNonNegative()) {
1009             divider.startMargin = value;
1010         }
1011         if (ParseLengthMetricsToPositiveDimension(obj->GetProperty("endMargin"), value) && value.IsNonNegative()) {
1012             divider.endMargin = value;
1013         }
1014         if (!ConvertFromJSValue(obj->GetProperty("color"), divider.color)) {
1015             divider.color = defaultColor;
1016         }
1017         auto modeVal = obj->GetProperty("mode");
1018         if (modeVal->IsNumber() && modeVal->ToNumber<int32_t>() == 1) {
1019             mode = DividerMode::EMBEDDED_IN_MENU;
1020         }
1021         SelectModel::GetInstance()->SetDividerStyle(divider, mode);
1022     } else {
1023         divider.isDividerStyle = false;
1024         SelectModel::GetInstance()->SetDivider(divider);
1025     }
1026 }
1027 
CheckDividerValue(const Dimension & dimension)1028 bool JSSelect::CheckDividerValue(const Dimension &dimension)
1029 {
1030     if (dimension.Value() >= 0.0f && dimension.Unit() != DimensionUnit::PERCENT) {
1031         return true;
1032     }
1033     return false;
1034 }
1035 
SetDirection(const std::string & dir)1036 void JSSelect::SetDirection(const std::string& dir)
1037 {
1038     TextDirection direction = TextDirection::AUTO;
1039     if (dir == "Ltr") {
1040         direction = TextDirection::LTR;
1041     } else if (dir == "Rtl") {
1042         direction = TextDirection::RTL;
1043     } else if (dir == "Auto") {
1044         direction = TextDirection::AUTO;
1045     } else if (dir == "undefined" && Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
1046         direction = TextDirection::AUTO;
1047     }
1048     SelectModel::GetInstance()->SetLayoutDirection(direction);
1049 }
1050 
SetMenuOutline(const JSCallbackInfo & info)1051 void JSSelect::SetMenuOutline(const JSCallbackInfo& info)
1052 {
1053     if (info.Length() < 1) {
1054         return;
1055     }
1056     auto menuOptionArg = info[0];
1057     auto menuTheme = GetTheme<NG::MenuTheme>();
1058     NG::MenuParam menuParam;
1059     MenuDefaultParam(menuParam);
1060     if (!menuOptionArg->IsObject()) {
1061         NG::BorderWidthProperty outlineWidth;
1062         outlineWidth.SetBorderWidth(Dimension(menuTheme->GetOuterBorderWidth()));
1063         menuParam.outlineWidth = outlineWidth;
1064         NG::BorderColorProperty outlineColor;
1065         outlineColor.SetColor(menuTheme->GetOuterBorderColor());
1066         menuParam.outlineColor = outlineColor;
1067     } else {
1068         auto menuOptions = JSRef<JSObject>::Cast(menuOptionArg);
1069         auto outlineWidthValue = menuOptions->GetProperty("width");
1070         JSViewPopups::ParseMenuOutlineWidth(outlineWidthValue, menuParam);
1071         auto outlineColorValue = menuOptions->GetProperty("color");
1072         JSViewPopups::ParseMenuOutlineColor(outlineColorValue, menuParam);
1073     }
1074     SelectModel::GetInstance()->SetMenuOutline(menuParam);
1075 }
1076 
SetArrowModifier(const JSCallbackInfo & info)1077 void JSSelect::SetArrowModifier(const JSCallbackInfo& info)
1078 {
1079     std::function<void(WeakPtr<NG::FrameNode>)> applyFunc = nullptr;
1080     if (info.Length() < 1 || info[0]->IsNull() || info[0]->IsUndefined() || !info[0]->IsObject() ||
1081         !SystemProperties::IsNeedSymbol()) {
1082         SelectModel::GetInstance()->SetArrowModifierApply(applyFunc);
1083         return;
1084     }
1085     JSViewAbstract::SetSymbolOptionApply(info, applyFunc, info[0]);
1086     SelectModel::GetInstance()->SetArrowModifierApply(applyFunc);
1087 }
1088 
SetTextModifier(const JSCallbackInfo & info)1089 void JSSelect::SetTextModifier(const JSCallbackInfo& info)
1090 {
1091     std::function<void(WeakPtr<NG::FrameNode>)> applyFunc = nullptr;
1092     if (info.Length() < 1 || info[0]->IsNull() || info[0]->IsUndefined() || !info[0]->IsObject()) {
1093         SelectModel::GetInstance()->SetTextModifierApply(applyFunc);
1094         return;
1095     }
1096     JSViewAbstract::SetTextStyleApply(info, applyFunc, info[0]);
1097     SelectModel::GetInstance()->SetTextModifierApply(applyFunc);
1098 }
1099 
SetOptionTextModifier(const JSCallbackInfo & info)1100 void JSSelect::SetOptionTextModifier(const JSCallbackInfo& info)
1101 {
1102     std::function<void(WeakPtr<NG::FrameNode>)> applyFunc = nullptr;
1103     if (info.Length() < 1 || info[0]->IsNull() || info[0]->IsUndefined() || !info[0]->IsObject()) {
1104         SelectModel::GetInstance()->SetOptionTextModifier(applyFunc);
1105         return;
1106     }
1107     JSViewAbstract::SetTextStyleApply(info, applyFunc, info[0]);
1108     SelectModel::GetInstance()->SetOptionTextModifier(applyFunc);
1109 }
1110 
SetSelectedOptionTextModifier(const JSCallbackInfo & info)1111 void JSSelect::SetSelectedOptionTextModifier(const JSCallbackInfo& info)
1112 {
1113     std::function<void(WeakPtr<NG::FrameNode>)> applyFunc = nullptr;
1114     if (info.Length() < 1 || info[0]->IsNull() || info[0]->IsUndefined() || !info[0]->IsObject()) {
1115         SelectModel::GetInstance()->SetSelectedOptionTextModifier(applyFunc);
1116         return;
1117     }
1118     JSViewAbstract::SetTextStyleApply(info, applyFunc, info[0]);
1119     SelectModel::GetInstance()->SetSelectedOptionTextModifier(applyFunc);
1120 }
1121 
SetShowInSubWindow(const JSCallbackInfo & info)1122 void JSSelect::SetShowInSubWindow(const JSCallbackInfo& info)
1123 {
1124     if (info.Length() < 1) {
1125         return;
1126     }
1127     if (!info[0]->IsBoolean()) {
1128         SelectModel::GetInstance()->ResetShowInSubWindow();
1129         return;
1130     }
1131     SelectModel::GetInstance()->SetShowInSubWindow(info[0]->ToBoolean());
1132 }
1133 
SetShowDefaultSelectedIcon(const JSCallbackInfo & info)1134 void JSSelect::SetShowDefaultSelectedIcon(const JSCallbackInfo& info)
1135 {
1136     if (info.Length() < 1) {
1137         return;
1138     }
1139     if (!info[0]->IsBoolean()) {
1140         SelectModel::GetInstance()->ResetShowDefaultSelectedIcon();
1141         return;
1142     }
1143     SelectModel::GetInstance()->SetShowDefaultSelectedIcon(info[0]->ToBoolean());
1144 }
1145 } // namespace OHOS::Ace::Framework
1146