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