• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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_textpicker.h"
17 
18 #include <cstdint>
19 #include <securec.h>
20 
21 #include "base/log/ace_scoring_log.h"
22 #include "bridge/common/utils/engine_helper.h"
23 #include "bridge/declarative_frontend/ark_theme/theme_apply/js_text_picker_theme.h"
24 #include "bridge/declarative_frontend/engine/functions/js_function.h"
25 #include "bridge/declarative_frontend/jsview/js_datepicker.h"
26 #include "bridge/declarative_frontend/jsview/js_interactable_view.h"
27 #include "bridge/declarative_frontend/jsview/js_utils.h"
28 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
29 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
30 #include "bridge/declarative_frontend/jsview/models/textpicker_model_impl.h"
31 #include "bridge/declarative_frontend/view_stack_processor.h"
32 #include "core/components/picker/picker_base_component.h"
33 #include "core/components/picker/picker_theme.h"
34 #include "core/components_ng/base/view_stack_processor.h"
35 #include "core/components_ng/pattern/text_picker/textpicker_model.h"
36 #include "core/components_ng/pattern/text_picker/textpicker_model_ng.h"
37 #include "core/components_ng/pattern/text_picker/textpicker_properties.h"
38 #include "core/pipeline_ng/pipeline_context.h"
39 
40 namespace OHOS::Ace {
41 namespace {
42 const DimensionOffset TEXT_PICKER_OFFSET_DEFAULT_TOP = DimensionOffset(0.0_vp, 40.0_vp);
43 const std::vector<DialogAlignment> DIALOG_ALIGNMENT = { DialogAlignment::TOP, DialogAlignment::CENTER,
44     DialogAlignment::BOTTOM, DialogAlignment::DEFAULT, DialogAlignment::TOP_START, DialogAlignment::TOP_END,
45     DialogAlignment::CENTER_START, DialogAlignment::CENTER_END, DialogAlignment::BOTTOM_START,
46     DialogAlignment::BOTTOM_END };
47 const std::vector<HoverModeAreaType> HOVER_MODE_AREA_TYPE = { HoverModeAreaType::TOP_SCREEN,
48     HoverModeAreaType::BOTTOM_SCREEN };
49 const std::regex DIMENSION_REGEX(R"(^[-+]?\d+(?:\.\d+)?(?:px|vp|fp|lpx)?$)", std::regex::icase);
50 const std::vector<TextOverflow> TEXT_OVERFLOWS = { TextOverflow::NONE, TextOverflow::CLIP, TextOverflow::ELLIPSIS,
51     TextOverflow::MARQUEE };
52 }
53 
54 std::unique_ptr<TextPickerModel> TextPickerModel::textPickerInstance_ = nullptr;
55 std::unique_ptr<TextPickerDialogModel> TextPickerDialogModel::textPickerDialogInstance_ = nullptr;
56 std::mutex TextPickerModel::mutex_;
57 std::mutex TextPickerDialogModel::mutex_;
58 
GetInstance()59 TextPickerModel* TextPickerModel::GetInstance()
60 {
61     if (!textPickerInstance_) {
62         std::lock_guard<std::mutex> lock(mutex_);
63         if (!textPickerInstance_) {
64 #ifdef NG_BUILD
65             textPickerInstance_.reset(new NG::TextPickerModelNG());
66 #else
67             if (Container::IsCurrentUseNewPipeline()) {
68                 textPickerInstance_.reset(new NG::TextPickerModelNG());
69             } else {
70                 textPickerInstance_.reset(new Framework::TextPickerModelImpl());
71             }
72 #endif
73         }
74     }
75     return textPickerInstance_.get();
76 }
77 
GetInstance()78 TextPickerDialogModel* TextPickerDialogModel::GetInstance()
79 {
80     if (!textPickerDialogInstance_) {
81         std::lock_guard<std::mutex> lock(mutex_);
82         if (!textPickerDialogInstance_) {
83 #ifdef NG_BUILD
84             textPickerDialogInstance_.reset(new NG::TextPickerDialogModelNG());
85 #else
86             if (Container::IsCurrentUseNewPipeline()) {
87                 textPickerDialogInstance_.reset(new NG::TextPickerDialogModelNG());
88             } else {
89                 textPickerDialogInstance_.reset(new Framework::TextPickerDialogModelImpl());
90             }
91 #endif
92         }
93     }
94     return textPickerDialogInstance_.get();
95 }
96 } // namespace OHOS::Ace
97 
98 namespace OHOS::Ace::Framework {
99 namespace {
ParseFontOfButtonStyle(const JSRef<JSObject> & pickerButtonParamObject,ButtonInfo & buttonInfo)100 void ParseFontOfButtonStyle(const JSRef<JSObject>& pickerButtonParamObject, ButtonInfo& buttonInfo)
101 {
102     CalcDimension fontSize;
103     JSRef<JSVal> sizeProperty = pickerButtonParamObject->GetProperty("fontSize");
104     if (JSViewAbstract::ParseJsDimensionVpNG(sizeProperty, fontSize) && fontSize.Unit() != DimensionUnit::PERCENT &&
105         GreatOrEqual(fontSize.Value(), 0.0)) {
106         if (JSViewAbstract::ParseJsDimensionFp(sizeProperty, fontSize)) {
107             buttonInfo.fontSize = fontSize;
108         }
109     }
110     Color fontColor;
111     if (JSViewAbstract::ParseJsColor(pickerButtonParamObject->GetProperty("fontColor"), fontColor)) {
112         buttonInfo.fontColor = fontColor;
113     }
114     auto fontWeight = pickerButtonParamObject->GetProperty("fontWeight");
115     if (fontWeight->IsString() || fontWeight->IsNumber()) {
116         buttonInfo.fontWeight = ConvertStrToFontWeight(fontWeight->ToString(), FontWeight::MEDIUM);
117     }
118     JSRef<JSVal> style = pickerButtonParamObject->GetProperty("fontStyle");
119     if (style->IsNumber()) {
120         auto value = style->ToNumber<int32_t>();
121         if (value >= 0 && value < static_cast<int32_t>(FontStyle::NONE)) {
122             buttonInfo.fontStyle = static_cast<FontStyle>(value);
123         }
124     }
125     JSRef<JSVal> family = pickerButtonParamObject->GetProperty("fontFamily");
126     std::vector<std::string> fontFamilies;
127     if (JSViewAbstract::ParseJsFontFamilies(family, fontFamilies)) {
128         buttonInfo.fontFamily = fontFamilies;
129     }
130 }
131 
ParseButtonStyle(const JSRef<JSObject> & pickerButtonParamObject)132 ButtonInfo ParseButtonStyle(const JSRef<JSObject>& pickerButtonParamObject)
133 {
134     ButtonInfo buttonInfo;
135     if (pickerButtonParamObject->GetProperty("type")->IsNumber()) {
136         buttonInfo.type =
137             static_cast<ButtonType>(pickerButtonParamObject->GetProperty("type")->ToNumber<int32_t>());
138     }
139     if (pickerButtonParamObject->GetProperty("style")->IsNumber()) {
140         auto styleModeIntValue = pickerButtonParamObject->GetProperty("style")->ToNumber<int32_t>();
141         if (styleModeIntValue >= static_cast<int32_t>(ButtonStyleMode::NORMAL) &&
142             styleModeIntValue <= static_cast<int32_t>(ButtonStyleMode::TEXT)) {
143             buttonInfo.buttonStyle = static_cast<ButtonStyleMode>(styleModeIntValue);
144         }
145     }
146     if (pickerButtonParamObject->GetProperty("role")->IsNumber()) {
147         auto buttonRoleIntValue = pickerButtonParamObject->GetProperty("role")->ToNumber<int32_t>();
148         if (buttonRoleIntValue >= static_cast<int32_t>(ButtonRole::NORMAL) &&
149             buttonRoleIntValue <= static_cast<int32_t>(ButtonRole::ERROR)) {
150             buttonInfo.role = static_cast<ButtonRole>(buttonRoleIntValue);
151         }
152     }
153     ParseFontOfButtonStyle(pickerButtonParamObject, buttonInfo);
154     Color backgroundColor;
155     if (JSViewAbstract::ParseJsColor(pickerButtonParamObject->GetProperty("backgroundColor"), backgroundColor)) {
156         buttonInfo.backgroundColor = backgroundColor;
157     }
158     auto radius = ParseBorderRadiusAttr(pickerButtonParamObject->GetProperty("borderRadius"));
159     if (radius.has_value()) {
160         buttonInfo.borderRadius = radius.value();
161     }
162 
163     auto primaryValue = pickerButtonParamObject->GetProperty("primary");
164     if (primaryValue->IsBoolean()) {
165         buttonInfo.isPrimary = primaryValue->ToBoolean();
166     }
167 
168     return buttonInfo;
169 }
170 
ParseButtonStyles(const JSRef<JSObject> & paramObject)171 std::vector<ButtonInfo> ParseButtonStyles(const JSRef<JSObject>& paramObject)
172 {
173     std::vector<ButtonInfo> buttonInfos;
174     auto acceptButtonStyle = paramObject->GetProperty("acceptButtonStyle");
175     if (acceptButtonStyle->IsObject()) {
176         auto acceptButtonStyleParamObject = JSRef<JSObject>::Cast(acceptButtonStyle);
177         buttonInfos.emplace_back(ParseButtonStyle(acceptButtonStyleParamObject));
178         buttonInfos[0].isAcceptButton = true;
179     } else {
180         ButtonInfo buttonInfo;
181         buttonInfos.emplace_back(buttonInfo);
182     }
183     auto cancelButtonStyle = paramObject->GetProperty("cancelButtonStyle");
184     if (cancelButtonStyle->IsObject()) {
185         auto cancelButtonStyleParamObject = JSRef<JSObject>::Cast(cancelButtonStyle);
186         buttonInfos.emplace_back(ParseButtonStyle(cancelButtonStyleParamObject));
187     }
188 
189     return buttonInfos;
190 }
191 } // namespace
192 
JSBind(BindingTarget globalObj)193 void JSTextPicker::JSBind(BindingTarget globalObj)
194 {
195     JSClass<JSTextPicker>::Declare("TextPicker");
196     MethodOptions opt = MethodOptions::NONE;
197     JSClass<JSTextPicker>::StaticMethod("create", &JSTextPicker::Create, opt);
198     JSClass<JSTextPicker>::StaticMethod("defaultPickerItemHeight", &JSTextPicker::SetDefaultPickerItemHeight);
199     JSClass<JSTextPicker>::StaticMethod("canLoop", &JSTextPicker::SetCanLoop);
200     JSClass<JSTextPicker>::StaticMethod("disappearTextStyle", &JSTextPicker::SetDisappearTextStyle);
201     JSClass<JSTextPicker>::StaticMethod("textStyle", &JSTextPicker::SetTextStyle);
202     JSClass<JSTextPicker>::StaticMethod("selectedTextStyle", &JSTextPicker::SetSelectedTextStyle);
203     JSClass<JSTextPicker>::StaticMethod("selectedIndex", &JSTextPicker::SetSelectedIndex);
204     JSClass<JSTextPicker>::StaticMethod("divider", &JSTextPicker::SetDivider);
205     JSClass<JSTextPicker>::StaticMethod("opacity", &JSTextPicker::JsOpacity);
206     JSClass<JSTextPicker>::StaticMethod("disableTextStyleAnimation", &JSTextPicker::SetDisableTextStyleAnimation);
207     JSClass<JSTextPicker>::StaticMethod("defaultTextStyle", &JSTextPicker::SetDefaultTextStyle);
208 
209     JSClass<JSTextPicker>::StaticMethod("onAccept", &JSTextPicker::OnAccept);
210     JSClass<JSTextPicker>::StaticMethod("onCancel", &JSTextPicker::OnCancel);
211     JSClass<JSTextPicker>::StaticMethod("onChange", &JSTextPicker::OnChange);
212     JSClass<JSTextPicker>::StaticMethod("onScrollStop", &JSTextPicker::OnScrollStop);
213     JSClass<JSTextPicker>::StaticMethod("backgroundColor", &JSTextPicker::PickerBackgroundColor);
214     JSClass<JSTextPicker>::StaticMethod("gradientHeight", &JSTextPicker::SetGradientHeight);
215     JSClass<JSTextPicker>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
216     JSClass<JSTextPicker>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
217     JSClass<JSTextPicker>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
218     JSClass<JSTextPicker>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
219     JSClass<JSTextPicker>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
220     JSClass<JSTextPicker>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
221     JSClass<JSTextPicker>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
222     JSClass<JSTextPicker>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
223     JSClass<JSTextPicker>::InheritAndBind<JSViewAbstract>(globalObj);
224 }
225 
SetDisableTextStyleAnimation(const JSCallbackInfo & info)226 void JSTextPicker::SetDisableTextStyleAnimation(const JSCallbackInfo& info)
227 {
228     bool value = false;
229     if (info[0]->IsBoolean()) {
230         value = info[0]->ToBoolean();
231     }
232     TextPickerModel::GetInstance()->SetDisableTextStyleAnimation(value);
233 }
234 
SetDefaultTextStyle(const JSCallbackInfo & info)235 void JSTextPicker::SetDefaultTextStyle(const JSCallbackInfo& info)
236 {
237     auto theme = GetTheme<TextTheme>();
238     CHECK_NULL_VOID(theme);
239     NG::PickerTextStyle textStyle;
240     if (info[0]->IsObject()) {
241         JSTextPickerParser::ParseTextStyle(info[0], textStyle, "defaultTextStyle");
242     }
243     TextPickerModel::GetInstance()->SetDefaultTextStyle(theme, textStyle);
244 }
245 
PickerBackgroundColor(const JSCallbackInfo & info)246 void JSTextPicker::PickerBackgroundColor(const JSCallbackInfo& info)
247 {
248     JSViewAbstract::JsBackgroundColor(info);
249 
250     if (info.Length() < 1) {
251         return;
252     }
253     Color backgroundColor;
254     if (!ParseJsColor(info[0], backgroundColor)) {
255         return;
256     }
257     TextPickerModel::GetInstance()->SetBackgroundColor(backgroundColor);
258 }
259 
JsOpacity(const JSCallbackInfo & info)260 void JSTextPicker::JsOpacity(const JSCallbackInfo& info)
261 {
262     JSViewAbstract::JsOpacity(info);
263     TextPickerModel::GetInstance()->HasUserDefinedOpacity();
264 }
265 
ProcessCascadeOptionDepth(const NG::TextCascadePickerOptions & option)266 size_t JSTextPicker::ProcessCascadeOptionDepth(const NG::TextCascadePickerOptions& option)
267 {
268     size_t depth = 1;
269     if (option.children.size() == 0) {
270         return depth;
271     }
272 
273     for (auto&& pos : option.children) {
274         size_t tmpDep = 1;
275         tmpDep += ProcessCascadeOptionDepth(pos);
276         if (tmpDep > depth) {
277             depth = tmpDep;
278         }
279     }
280     return depth;
281 }
282 
CreateMulti(const RefPtr<PickerTheme> & theme,const std::vector<std::string> & values,const std::vector<uint32_t> & selectedValues,const NG::TextCascadePickerOptionsAttr & attr,const std::vector<NG::TextCascadePickerOptions> & options)283 void JSTextPicker::CreateMulti(const RefPtr<PickerTheme>& theme, const std::vector<std::string>& values,
284     const std::vector<uint32_t>& selectedValues, const NG::TextCascadePickerOptionsAttr& attr,
285     const std::vector<NG::TextCascadePickerOptions>& options)
286 {
287     TextPickerModel::GetInstance()->MultiInit(theme);
288     TextPickerModel::GetInstance()->SetValues(values);
289     TextPickerModel::GetInstance()->SetSelecteds(selectedValues);
290     TextPickerModel::GetInstance()->SetIsCascade(attr.isCascade);
291     TextPickerModel::GetInstance()->SetHasSelectAttr(attr.isHasSelectAttr);
292     TextPickerModel::GetInstance()->SetColumns(options);
293 }
294 
ParseTextPickerValueObject(const JSCallbackInfo & info,const JSRef<JSVal> & changeEventVal)295 void ParseTextPickerValueObject(const JSCallbackInfo& info, const JSRef<JSVal>& changeEventVal)
296 {
297     CHECK_NULL_VOID(changeEventVal->IsFunction());
298 
299     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
300     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
301     auto onValueChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
302                              const std::vector<std::string>& value) {
303         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
304         ACE_SCORING_EVENT("TextPicker.onValueChange");
305         if (value.size() == 1) {
306             JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(value[0]));
307             PipelineContext::SetCallBackNode(node);
308             func->ExecuteJS(1, &newJSVal);
309         } else {
310             JSRef<JSArray> valueArray = JSRef<JSArray>::New();
311             for (uint32_t i = 0; i < value.size(); i++) {
312                 valueArray->SetValueAt(i, JSRef<JSVal>::Make(ToJSValue(value[i])));
313             }
314             JSRef<JSVal> newJSVal = JSRef<JSVal>::Cast(valueArray);
315             PipelineContext::SetCallBackNode(node);
316             func->ExecuteJS(1, &newJSVal);
317         }
318     };
319     TextPickerModel::GetInstance()->SetOnValueChangeEvent(std::move(onValueChange));
320 }
321 
ParseTextPickerSelectedObject(const JSCallbackInfo & info,const JSRef<JSVal> & changeEventVal)322 void ParseTextPickerSelectedObject(const JSCallbackInfo& info, const JSRef<JSVal>& changeEventVal)
323 {
324     CHECK_NULL_VOID(changeEventVal->IsFunction());
325 
326     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
327     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
328     auto onSelectedChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
329                                 const std::vector<double>& index) {
330         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
331         ACE_SCORING_EVENT("TextPicker.onSelectedChange");
332         if (index.size() == 1) {
333             PipelineContext::SetCallBackNode(node);
334             JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(index[0]));
335             func->ExecuteJS(1, &newJSVal);
336         } else {
337             JSRef<JSArray> indexArray = JSRef<JSArray>::New();
338             for (uint32_t i = 0; i < index.size(); i++) {
339                 indexArray->SetValueAt(i, JSRef<JSVal>::Make(ToJSValue(index[i])));
340             }
341             PipelineContext::SetCallBackNode(node);
342             JSRef<JSVal> newJSVal = JSRef<JSVal>::Cast(indexArray);
343             func->ExecuteJS(1, &newJSVal);
344         }
345     };
346     TextPickerModel::GetInstance()->SetOnSelectedChangeEvent(std::move(onSelectedChange));
347 }
348 
Create(const JSCallbackInfo & info)349 void JSTextPicker::Create(const JSCallbackInfo& info)
350 {
351     if (info.Length() >= 1 && info[0]->IsObject()) {
352         auto paramObject = JSRef<JSObject>::Cast(info[0]);
353         ParseTextArrayParam param;
354         NG::TextCascadePickerOptionsAttr optionsAttr;
355         bool optionsMultiContentCheckErr = false;
356         bool optionsCascadeContentCheckErr = false;
357         auto isSingleRange = ProcessSingleRangeValue(paramObject, param);
358         TextPickerModel::GetInstance()->SetSingleRange(isSingleRange);
359         if (!isSingleRange) {
360             if (!JSTextPickerParser::ParseMultiTextArray(paramObject, param)) {
361                 param.options.clear();
362                 optionsMultiContentCheckErr = true;
363             }
364             if (optionsMultiContentCheckErr) {
365                 optionsCascadeContentCheckErr =
366                     !ProcessCascadeOptions(paramObject, param.options, param.selecteds, param.values, optionsAttr);
367             }
368         }
369         if (!isSingleRange && optionsMultiContentCheckErr && optionsCascadeContentCheckErr) {
370             param.result.clear();
371             param.options.clear();
372 
373             auto targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
374             bool firstBuild = targetNode && targetNode->IsFirstBuilding();
375             if (!firstBuild) {
376                 return;
377             }
378         }
379         auto theme = GetTheme<PickerTheme>();
380         CHECK_NULL_VOID(theme);
381         if (!param.result.empty()) {
382             TextPickerModel::GetInstance()->Create(theme, param.kind);
383             TextPickerModel::GetInstance()->SetRange(param.result);
384             TextPickerModel::GetInstance()->SetSelected(param.selected);
385             TextPickerModel::GetInstance()->SetValue(param.value);
386         } else {
387             CreateMulti(theme, param.values, param.selecteds, optionsAttr, param.options);
388         }
389         TextPickerModel::GetInstance()->SetDefaultAttributes(theme);
390         JSInteractableView::SetFocusable(true);
391         JSInteractableView::SetFocusNode(true);
392         if (param.valueChangeEventVal->IsFunction()) {
393             ParseTextPickerValueObject(info, param.valueChangeEventVal);
394         }
395         if (param.selectedChangeEventVal->IsFunction()) {
396             ParseTextPickerSelectedObject(info, param.selectedChangeEventVal);
397         }
398         JSTextPickerTheme::ApplyTheme();
399     }
400 }
401 
ProcessSingleRangeValue(const JSRef<JSObject> & paramObjec,ParseTextArrayParam & param)402 bool JSTextPicker::ProcessSingleRangeValue(const JSRef<JSObject>& paramObjec, ParseTextArrayParam& param)
403 {
404     bool ret = true;
405     auto getRange = paramObjec->GetProperty("range");
406     if (getRange->IsNull() || getRange->IsUndefined()) {
407         if (TextPickerModel::GetInstance()->GetSingleRange()) {
408             return ret;
409         }
410         return false;
411     }
412     if (!JSTextPickerParser::ParseTextArray(paramObjec, param)) {
413         if (!JSTextPickerParser::ParseIconTextArray(paramObjec, param.result, param.kind, param.selected)) {
414             param.result.clear();
415             ret = false;
416         }
417     }
418     return ret;
419 }
420 
ProcessCascadeOptions(const JSRef<JSObject> & paramObject,std::vector<NG::TextCascadePickerOptions> & options,std::vector<uint32_t> & selectedValues,std::vector<std::string> & values,NG::TextCascadePickerOptionsAttr & attr)421 bool JSTextPicker::ProcessCascadeOptions(const JSRef<JSObject>& paramObject,
422     std::vector<NG::TextCascadePickerOptions>& options, std::vector<uint32_t>& selectedValues,
423     std::vector<std::string>& values, NG::TextCascadePickerOptionsAttr& attr)
424 {
425     auto getRange = paramObject->GetProperty("range");
426     if (getRange->IsNull() || getRange->IsUndefined()) {
427         options.clear();
428         return false;
429     }
430     if (!JSTextPickerParser::ParseCascadeTextArray(paramObject, selectedValues, values, attr)) {
431         options.clear();
432         return false;
433     } else {
434         JSTextPickerParser::GenerateCascadeOptions(getRange, options);
435         uint32_t maxCount = options.empty() ? 0 : 1;
436         for (size_t i = 0; i < options.size(); i++) {
437             size_t tmp = ProcessCascadeOptionDepth(options[i]);
438             if (tmp > maxCount) {
439                 maxCount = tmp;
440             }
441         }
442         if (selectedValues.size() < maxCount) {
443             auto differ = maxCount - selectedValues.size();
444             for (uint32_t i = 0; i < differ; i++) {
445                 selectedValues.emplace_back(0);
446             }
447         }
448         if (values.size() < maxCount) {
449             auto differ = maxCount - values.size();
450             for (uint32_t i = 0; i < differ; i++) {
451                 values.emplace_back("");
452             }
453         }
454         attr.isCascade = true;
455         TextPickerModel::GetInstance()->SetMaxCount(maxCount);
456     }
457     return true;
458 }
459 
GenerateCascadeOptionsInternal(const JSRef<JSObject> & jsObj,std::vector<NG::TextCascadePickerOptions> & options)460 bool JSTextPickerParser::GenerateCascadeOptionsInternal(
461     const JSRef<JSObject>& jsObj, std::vector<NG::TextCascadePickerOptions>& options)
462 {
463     NG::TextCascadePickerOptions option;
464     auto text = jsObj->GetProperty("text");
465     std::string textStr = "";
466     if (ParseJsString(text, textStr)) {
467         option.rangeResult.emplace_back(textStr);
468     } else {
469         return false;
470     }
471 
472     auto children = jsObj->GetProperty("children");
473     if (children->IsArray()) {
474         JSRef<JSArray> arrayChildren = JSRef<JSArray>::Cast(children);
475         if (arrayChildren->Length() > 0) {
476             if (!GenerateCascadeOptions(arrayChildren, option.children)) {
477                 return false;
478             }
479         }
480     }
481     options.emplace_back(option);
482     return true;
483 }
484 
GenerateCascadeOptions(const JSRef<JSArray> & array,std::vector<NG::TextCascadePickerOptions> & options)485 bool JSTextPickerParser::GenerateCascadeOptions(
486     const JSRef<JSArray>& array, std::vector<NG::TextCascadePickerOptions>& options)
487 {
488     for (size_t i = 0; i < array->Length(); i++) {
489         if (array->GetValueAt(i)->IsObject()) {
490             auto jsObj = JSRef<JSObject>::Cast(array->GetValueAt(i));
491             if (!GenerateCascadeOptionsInternal(jsObj, options)) {
492                 return false;
493             }
494         } else {
495             options.clear();
496             return false;
497         }
498     }
499     return true;
500 }
501 
ParseMultiTextArrayRangeInternal(const JSRef<JSVal> & value,std::vector<NG::TextCascadePickerOptions> & options)502 bool JSTextPickerParser::ParseMultiTextArrayRangeInternal(
503     const JSRef<JSVal>& value, std::vector<NG::TextCascadePickerOptions>& options)
504 {
505     if (value->IsArray()) {
506         NG::TextCascadePickerOptions option;
507         if (!ParseJsStrArray(value, option.rangeResult)) {
508             return false;
509         } else {
510             options.emplace_back(option);
511         }
512     } else {
513         return false;
514     }
515     return true;
516 }
517 
ParseMultiTextArrayRange(const JSRef<JSArray> & jsRangeValue,std::vector<NG::TextCascadePickerOptions> & options)518 bool JSTextPickerParser::ParseMultiTextArrayRange(
519     const JSRef<JSArray>& jsRangeValue, std::vector<NG::TextCascadePickerOptions>& options)
520 {
521     options.clear();
522     if (jsRangeValue->Length() > 0) {
523         for (size_t i = 0; i < jsRangeValue->Length(); i++) {
524             JSRef<JSVal> value = jsRangeValue->GetValueAt(i);
525             if (!ParseMultiTextArrayRangeInternal(value, options)) {
526                 return false;
527             }
528         }
529     } else {
530         return false;
531     }
532     return true;
533 }
534 
ParseMultiTextArraySelectInternal(const std::vector<NG::TextCascadePickerOptions> & options,const std::vector<std::string> & values,std::vector<uint32_t> & selectedValues)535 void JSTextPickerParser::ParseMultiTextArraySelectInternal(const std::vector<NG::TextCascadePickerOptions>& options,
536     const std::vector<std::string>& values, std::vector<uint32_t>& selectedValues)
537 {
538     uint32_t selectedValue = 0;
539     auto sizeOfValues = values.size();
540     for (uint32_t i = 0; i < options.size(); i++) {
541         if ((sizeOfValues >= 0 && sizeOfValues < i + 1) || values[i].empty()) {
542             selectedValues.emplace_back(0);
543             continue;
544         }
545 
546         auto valueIterator = std::find(options[i].rangeResult.begin(), options[i].rangeResult.end(), values[i]);
547         if (valueIterator != options[i].rangeResult.end()) {
548             selectedValue = static_cast<uint32_t>(std::distance(options[i].rangeResult.begin(), valueIterator));
549             selectedValues.emplace_back(selectedValue);
550         } else {
551             selectedValues.emplace_back(0);
552         }
553     }
554 }
555 
ParseMultiTextArraySelectArrayInternal(const std::vector<NG::TextCascadePickerOptions> & options,std::vector<uint32_t> & selectedValues)556 void JSTextPickerParser::ParseMultiTextArraySelectArrayInternal(
557     const std::vector<NG::TextCascadePickerOptions>& options, std::vector<uint32_t>& selectedValues)
558 {
559     for (uint32_t i = 0; i < options.size(); i++) {
560         if (selectedValues.size() > 0 && selectedValues.size() < i + 1) {
561             selectedValues.emplace_back(0);
562         } else {
563             if (selectedValues[i] >= options[i].rangeResult.size()) {
564                 selectedValues[i] = 0;
565             }
566         }
567     }
568 }
569 
ParseMultiTextArraySelect(const JsiRef<JsiValue> & jsSelectedValue,ParseTextArrayParam & param)570 bool JSTextPickerParser::ParseMultiTextArraySelect(const JsiRef<JsiValue>& jsSelectedValue, ParseTextArrayParam& param)
571 {
572     if (jsSelectedValue->IsArray()) {
573         if (!ParseJsIntegerArray(jsSelectedValue, param.selecteds)) {
574             return false;
575         }
576         ParseMultiTextArraySelectArrayInternal(param.options, param.selecteds);
577     } else {
578         uint32_t selectedValue = 0;
579         if (ParseJsInteger(jsSelectedValue, selectedValue)) {
580             if (param.options.size() < 1 || selectedValue >= param.options[0].rangeResult.size()) {
581                 selectedValue = 0;
582             }
583             param.selecteds.emplace_back(selectedValue);
584             for (uint32_t i = 1; i < param.options.size(); i++) {
585                 param.selecteds.emplace_back(0);
586             }
587         } else {
588             ParseMultiTextArraySelectInternal(param.options, param.values, param.selecteds);
589         }
590     }
591     return true;
592 }
593 
ParseMultiTextArrayValueInternal(const std::vector<NG::TextCascadePickerOptions> & options,std::vector<std::string> & values)594 void JSTextPickerParser::ParseMultiTextArrayValueInternal(
595     const std::vector<NG::TextCascadePickerOptions>& options, std::vector<std::string>& values)
596 {
597     for (uint32_t i = 0; i < options.size(); i++) {
598         if (values.size() > 0 && values.size() < i + 1) {
599             if (options[i].rangeResult.size() > 0) {
600                 values.emplace_back(options[i].rangeResult[0]);
601             } else {
602                 values.emplace_back("");
603             }
604         } else {
605             auto valueIterator = std::find(options[i].rangeResult.begin(), options[i].rangeResult.end(), values[i]);
606             if (valueIterator == options[i].rangeResult.end()) {
607                 values[i] = options[i].rangeResult.front();
608             }
609         }
610     }
611 }
612 
ParseMultiTextArrayValueSingleInternal(const std::vector<NG::TextCascadePickerOptions> & options,const std::string & value,std::vector<std::string> & values)613 void JSTextPickerParser::ParseMultiTextArrayValueSingleInternal(
614     const std::vector<NG::TextCascadePickerOptions>& options, const std::string& value,
615     std::vector<std::string>& values)
616 {
617     if (options.size() > 0) {
618         auto valueIterator = std::find(options[0].rangeResult.begin(), options[0].rangeResult.end(), value);
619         if (valueIterator != options[0].rangeResult.end()) {
620             values.emplace_back(value);
621         } else {
622             values.emplace_back(options[0].rangeResult.front());
623         }
624         for (uint32_t i = 1; i < options.size(); i++) {
625             values.emplace_back(options[i].rangeResult.front());
626         }
627     } else {
628         for (uint32_t i = 0; i < options.size(); i++) {
629             values.emplace_back(options[i].rangeResult.front());
630         }
631     }
632 }
633 
ParseMultiTextArrayValue(const JsiRef<JsiValue> & jsValue,ParseTextArrayParam & param)634 bool JSTextPickerParser::ParseMultiTextArrayValue(const JsiRef<JsiValue>& jsValue, ParseTextArrayParam& param)
635 {
636     if (jsValue->IsArray()) {
637         if (!ParseJsStrArray(jsValue, param.values)) {
638             return false;
639         }
640         ParseMultiTextArrayValueInternal(param.options, param.values);
641     } else {
642         std::string value;
643         if (ParseJsString(jsValue, value)) {
644             ParseMultiTextArrayValueSingleInternal(param.options, value, param.values);
645         } else {
646             for (uint32_t i = 0; i < param.options.size(); i++) {
647                 if (param.options[i].rangeResult.size() > 0) {
648                     param.values.emplace_back(param.options[i].rangeResult.front());
649                 }
650             }
651         }
652     }
653     return true;
654 }
655 
ParseMultiTextArray(const JSRef<JSObject> & paramObject,ParseTextArrayParam & param)656 bool JSTextPickerParser::ParseMultiTextArray(const JSRef<JSObject>& paramObject, ParseTextArrayParam& param)
657 {
658     auto getSelected = paramObject->GetProperty("selected");
659     auto getValue = paramObject->GetProperty("value");
660     auto getRange = paramObject->GetProperty("range");
661     if (getRange->IsNull() || getRange->IsUndefined()) {
662         return false;
663     }
664     if (!getRange->IsArray()) {
665         return false;
666     }
667     JSRef<JSArray> array = JSRef<JSArray>::Cast(getRange);
668     if (!ParseMultiTextArrayRange(array, param.options)) {
669         return false;
670     }
671     if (getValue->IsObject()) {
672         JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(getValue);
673         param.valueChangeEventVal = valueObj->GetProperty("changeEvent");
674         if (param.valueChangeEventVal->IsFunction()) {
675             getValue = valueObj->GetProperty("value");
676         }
677     }
678     if (!ParseMultiTextArrayValue(getValue, param)) {
679         return false;
680     }
681     if (getSelected->IsObject()) {
682         JSRef<JSObject> selectedObj = JSRef<JSObject>::Cast(getSelected);
683         param.selectedChangeEventVal = selectedObj->GetProperty("changeEvent");
684         if (param.selectedChangeEventVal->IsFunction()) {
685             getSelected = selectedObj->GetProperty("value");
686         }
687     }
688     if (!ParseMultiTextArraySelect(getSelected, param)) {
689         return false;
690     }
691     return true;
692 }
693 
ParseInternalArray(const JSRef<JSArray> & jsRangeValue,std::vector<uint32_t> & selectedValues,std::vector<std::string> & values,uint32_t index,bool isHasSelectAttr)694 bool JSTextPickerParser::ParseInternalArray(const JSRef<JSArray>& jsRangeValue, std::vector<uint32_t>& selectedValues,
695     std::vector<std::string>& values, uint32_t index, bool isHasSelectAttr)
696 {
697     std::vector<std::string> resultStr;
698     for (size_t i = 0; i < jsRangeValue->Length(); i++) {
699         if (jsRangeValue->GetValueAt(i)->IsObject()) {
700             auto jsObj = JSRef<JSObject>::Cast(jsRangeValue->GetValueAt(i));
701             auto getText = jsObj->GetProperty("text");
702             std::string textStr = "";
703             if (ParseJsString(getText, textStr)) {
704                 resultStr.emplace_back(textStr);
705             } else {
706                 return false;
707             }
708         }
709     }
710     if (index + 1 > values.size()) {
711         if (resultStr.size() > 0) {
712             values.emplace_back(resultStr.front());
713         } else {
714             values.emplace_back("");
715         }
716     } else {
717         if (resultStr.size() > 0) {
718             auto valueIterator = std::find(resultStr.begin(), resultStr.end(), values[index]);
719             if (valueIterator == resultStr.end()) {
720                 values[index] = resultStr.front();
721             }
722         } else {
723             values[index] = "";
724         }
725     }
726 
727     SetSelectedValues(selectedValues, values, index, isHasSelectAttr, resultStr);
728 
729     if (!jsRangeValue->GetValueAt(selectedValues[index])->IsObject()) {
730         return true;
731     }
732     auto jsObj = JSRef<JSObject>::Cast(jsRangeValue->GetValueAt(selectedValues[index]));
733     auto getChildren = jsObj->GetProperty("children");
734     if (getChildren->IsArray()) {
735         ParseInternalArray(getChildren, selectedValues, values, index + 1, isHasSelectAttr);
736     }
737     return true;
738 }
739 
SetSelectedValues(std::vector<uint32_t> & selectedValues,std::vector<std::string> & values,uint32_t index,bool isHasSelectAttr,std::vector<std::string> & resultStr)740 void JSTextPickerParser::SetSelectedValues(std::vector<uint32_t>& selectedValues, std::vector<std::string>& values,
741     uint32_t index, bool isHasSelectAttr, std::vector<std::string>& resultStr)
742 {
743     if (index + 1 > selectedValues.size()) {
744         selectedValues.emplace_back(0);
745     } else {
746         if (selectedValues[index] >= resultStr.size()) {
747             selectedValues[index] = 0;
748         }
749     }
750 
751     if (!isHasSelectAttr && selectedValues[index] == 0 && !values[index].empty()) {
752         auto valueIterator = std::find(resultStr.begin(), resultStr.end(), values[index]);
753         if (valueIterator != resultStr.end()) {
754             auto localDistance = std::distance(resultStr.begin(), valueIterator);
755             selectedValues[index] = localDistance > 0 ? static_cast<uint32_t>(localDistance) : 0;
756         }
757     }
758 }
759 
ParseCascadeTextArray(const JSRef<JSObject> & paramObject,std::vector<uint32_t> & selectedValues,std::vector<std::string> & values,NG::TextCascadePickerOptionsAttr & attr)760 bool JSTextPickerParser::ParseCascadeTextArray(const JSRef<JSObject>& paramObject,
761     std::vector<uint32_t>& selectedValues, std::vector<std::string>& values, NG::TextCascadePickerOptionsAttr& attr)
762 {
763     JSRef<JSArray> getRange = paramObject->GetProperty("range");
764     auto getSelected = paramObject->GetProperty("selected");
765     auto getValue = paramObject->GetProperty("value");
766     if (getValue->IsArray()) {
767         if (!ParseJsStrArray(getValue, values)) {
768             return false;
769         }
770     } else {
771         std::string value = "";
772         if (!ParseJsString(getValue, value)) {
773             value = "";
774         }
775         values.emplace_back(value);
776     }
777     if (getSelected->IsArray()) {
778         if (!ParseJsIntegerArray(getSelected, selectedValues)) {
779             attr.isHasSelectAttr = false;
780             return false;
781         } else {
782             attr.isHasSelectAttr = true;
783         }
784     } else {
785         uint32_t selectValue = 0;
786         if (!ParseJsInteger(getSelected, selectValue)) {
787             selectValue = 0;
788             attr.isHasSelectAttr = false;
789         } else {
790             attr.isHasSelectAttr = true;
791         }
792         selectedValues.emplace_back(selectValue);
793     }
794     return ParseInternalArray(getRange, selectedValues, values, 0, attr.isHasSelectAttr);
795 }
796 
ParseTextArray(const JSRef<JSObject> & paramObject,ParseTextArrayParam & param)797 bool JSTextPickerParser::ParseTextArray(const JSRef<JSObject>& paramObject, ParseTextArrayParam& param)
798 {
799     auto getSelected = paramObject->GetProperty("selected");
800     auto getValue = paramObject->GetProperty("value");
801     JSRef<JSArray> getRange = paramObject->GetProperty("range");
802     std::vector<std::string> getRangeVector;
803     if (getRange->Length() > 0) {
804         if (!ParseJsStrArray(getRange, getRangeVector)) {
805             return false;
806         }
807 
808         param.result.clear();
809         for (const auto& text : getRangeVector) {
810             NG::RangeContent content;
811             content.icon_ = "";
812             content.text_ = text;
813             param.result.emplace_back(content);
814         }
815         param.kind = NG::TEXT;
816         if (getValue->IsObject()) {
817             JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(getValue);
818             param.valueChangeEventVal = valueObj->GetProperty("changeEvent");
819             if (param.valueChangeEventVal->IsFunction()) {
820                 getValue = valueObj->GetProperty("value");
821             }
822         }
823         if (!ParseJsString(getValue, param.value)) {
824             param.value = getRangeVector.front();
825         }
826         if (getSelected->IsObject()) {
827             JSRef<JSObject> selectedObj = JSRef<JSObject>::Cast(getSelected);
828             param.selectedChangeEventVal = selectedObj->GetProperty("changeEvent");
829             if (param.selectedChangeEventVal->IsFunction()) {
830                 getSelected = selectedObj->GetProperty("value");
831             }
832         }
833         if (!ParseJsInteger(getSelected, param.selected) && !param.value.empty()) {
834             auto valueIterator = std::find(getRangeVector.begin(), getRangeVector.end(), param.value);
835             if (valueIterator != getRangeVector.end()) {
836                 param.selected = static_cast<uint32_t>(std::distance(getRangeVector.begin(), valueIterator));
837             }
838         }
839         if (param.selected >= getRangeVector.size()) {
840             param.selected = 0;
841         }
842     }
843 
844     return true;
845 }
846 
ParseIconTextArray(const JSRef<JSObject> & paramObject,std::vector<NG::RangeContent> & result,uint32_t & kind,uint32_t & selectedValue)847 bool JSTextPickerParser::ParseIconTextArray(
848     const JSRef<JSObject>& paramObject, std::vector<NG::RangeContent>& result, uint32_t& kind, uint32_t& selectedValue)
849 {
850     auto getSelected = paramObject->GetProperty("selected");
851     auto getRange = paramObject->GetProperty("range");
852     if (!getRange->IsArray()) {
853         return false;
854     }
855     JSRef<JSArray> array = JSRef<JSArray>::Cast(getRange);
856     result.clear();
857     kind = 0;
858     for (size_t i = 0; i < array->Length(); i++) {
859         if (!array->GetValueAt(i)->IsObject()) {
860             continue;
861         }
862         auto jsObj = JSRef<JSObject>::Cast(array->GetValueAt(i));
863         auto rangeIcon = jsObj->GetProperty("icon");
864         auto rangeText = jsObj->GetProperty("text");
865         NG::RangeContent content;
866         std::string icon;
867         std::string text;
868         if (ParseJsMedia(rangeIcon, icon)) {
869             content.icon_ = icon;
870             kind |= NG::ICON;
871         }
872 
873         if (ParseJsString(rangeText, text)) {
874             content.text_ = text;
875             kind |= NG::TEXT;
876         }
877         result.emplace_back(content);
878     }
879 
880     if (kind != NG::ICON && kind != (NG::ICON | NG::TEXT)) {
881         return false;
882     }
883 
884     if (!ParseJsInteger(getSelected, selectedValue)) {
885         selectedValue = 0;
886     }
887     return true;
888 }
889 
IsUserDefinedFontFamily(const std::string & pos)890 void JSTextPickerParser::IsUserDefinedFontFamily(const std::string& pos)
891 {
892     if (pos == "disappearTextStyle") {
893         TextPickerModel::GetInstance()->HasUserDefinedDisappearFontFamily(true);
894     } else if (pos == "textStyle") {
895         TextPickerModel::GetInstance()->HasUserDefinedNormalFontFamily(true);
896     } else if (pos == "selectedTextStyle") {
897         TextPickerModel::GetInstance()->HasUserDefinedSelectedFontFamily(true);
898     }
899 }
900 
ParseDefaultTextStyle(const JSRef<JSObject> & paramObj,NG::PickerTextStyle & textStyle)901 void JSTextPickerParser::ParseDefaultTextStyle(const JSRef<JSObject>& paramObj, NG::PickerTextStyle& textStyle)
902 {
903     auto minFontSize = paramObj->GetProperty("minFontSize");
904     auto maxFontSize = paramObj->GetProperty("maxFontSize");
905     if (!minFontSize->IsNull() && !minFontSize->IsUndefined()) {
906         CalcDimension minSize;
907         if (ParseJsDimensionFp(minFontSize, minSize) && minSize.Unit() != DimensionUnit::PERCENT) {
908             textStyle.minFontSize = minSize;
909         }
910     }
911     if (!maxFontSize->IsNull() && !maxFontSize->IsUndefined()) {
912         CalcDimension maxSize;
913         if (ParseJsDimensionFp(maxFontSize, maxSize) && maxSize.Unit() != DimensionUnit::PERCENT) {
914             textStyle.maxFontSize = maxSize;
915         }
916     }
917 
918     auto overflow = paramObj->GetProperty("overflow");
919     if (!overflow->IsNull() && !overflow->IsUndefined()) {
920         if (overflow->IsNumber()) {
921             auto overflowValue = overflow->ToNumber<int32_t>();
922             if (overflowValue >= 0 && overflowValue < static_cast<int32_t>(TEXT_OVERFLOWS.size())) {
923                 textStyle.textOverflow = TEXT_OVERFLOWS[overflowValue];
924             }
925         }
926     }
927 }
928 
ParseTextStyle(const JSRef<JSObject> & paramObj,NG::PickerTextStyle & textStyle,const std::string & pos)929 void JSTextPickerParser::ParseTextStyle(
930     const JSRef<JSObject>& paramObj, NG::PickerTextStyle& textStyle, const std::string& pos)
931 {
932     auto fontColor = paramObj->GetProperty("color");
933     auto fontOptions = paramObj->GetProperty("font");
934 
935     Color textColor;
936     if (ParseJsColor(fontColor, textColor)) {
937         textStyle.textColor = textColor;
938     }
939 
940     ParseDefaultTextStyle(paramObj, textStyle);
941 
942     if (!fontOptions->IsObject()) {
943         return;
944     }
945     JSRef<JSObject> fontObj = JSRef<JSObject>::Cast(fontOptions);
946     auto fontSize = fontObj->GetProperty("size");
947     auto fontWeight = fontObj->GetProperty("weight");
948     auto fontFamily = fontObj->GetProperty("family");
949     auto fontStyle = fontObj->GetProperty("style");
950     if (fontSize->IsNull() || fontSize->IsUndefined()) {
951         textStyle.fontSize = Dimension(-1);
952     } else {
953         CalcDimension size;
954         if (!ParseJsDimensionFp(fontSize, size) || size.Unit() == DimensionUnit::PERCENT) {
955             textStyle.fontSize = Dimension(-1);
956         } else {
957             textStyle.fontSize = size;
958         }
959     }
960 
961     if (!fontWeight->IsNull() && !fontWeight->IsUndefined()) {
962         std::string weight;
963         if (fontWeight->IsNumber()) {
964             weight = std::to_string(fontWeight->ToNumber<int32_t>());
965         } else {
966             ParseJsString(fontWeight, weight);
967         }
968         textStyle.fontWeight = ConvertStrToFontWeight(weight);
969     }
970 
971     if (!fontFamily->IsNull() && !fontFamily->IsUndefined()) {
972         std::vector<std::string> families;
973         if (ParseJsFontFamilies(fontFamily, families)) {
974             textStyle.fontFamily = families;
975             IsUserDefinedFontFamily(pos);
976         }
977     }
978 
979     if (fontStyle->IsNumber()) {
980         auto style = fontStyle->ToNumber<int32_t>();
981         if (style < 0 || style > 1) {
982             return;
983         }
984         textStyle.fontStyle = static_cast<FontStyle>(style);
985     }
986 }
987 
SetDefaultPickerItemHeight(const JSCallbackInfo & info)988 void JSTextPicker::SetDefaultPickerItemHeight(const JSCallbackInfo& info)
989 {
990     if (info.Length() < 1) {
991         return;
992     }
993     CalcDimension height;
994     if (info[0]->IsNumber() || info[0]->IsString()) {
995         if (!ParseJsDimensionFp(info[0], height)) {
996             return;
997         }
998     }
999     TextPickerModel::GetInstance()->SetDefaultPickerItemHeight(height);
1000 }
1001 
SetGradientHeight(const JSCallbackInfo & info)1002 void JSTextPicker::SetGradientHeight(const JSCallbackInfo& info)
1003 {
1004     CalcDimension height;
1005     auto pickerTheme = GetTheme<PickerTheme>();
1006     if (info[0]->IsNull() || info[0]->IsUndefined()) {
1007         if (pickerTheme) {
1008             height = pickerTheme->GetGradientHeight();
1009         } else {
1010             height = 0.0_vp;
1011         }
1012     }
1013     if (info.Length() >= 1) {
1014         if (!ConvertFromJSValueNG(info[0], height)) {
1015             if (pickerTheme) {
1016                 height = pickerTheme->GetGradientHeight();
1017             }
1018         }
1019         if ((height.Unit() == DimensionUnit::PERCENT) &&
1020             ((height.Value() > 1.0f) || (height.Value() < 0.0f))) {
1021             if (pickerTheme) {
1022                 height = pickerTheme->GetGradientHeight();
1023             } else {
1024                 height = 0.0_vp;
1025             }
1026         }
1027     }
1028     TextPickerModel::GetInstance()->SetGradientHeight(height);
1029 }
1030 
SetCanLoop(const JSCallbackInfo & info)1031 void JSTextPicker::SetCanLoop(const JSCallbackInfo& info)
1032 {
1033     bool value = true;
1034     if (info[0]->IsBoolean()) {
1035         value = info[0]->ToBoolean();
1036     }
1037     TextPickerModel::GetInstance()->SetCanLoop(value);
1038 }
1039 
SetDisappearTextStyle(const JSCallbackInfo & info)1040 void JSTextPicker::SetDisappearTextStyle(const JSCallbackInfo& info)
1041 {
1042     auto theme = GetTheme<PickerTheme>();
1043     CHECK_NULL_VOID(theme);
1044     NG::PickerTextStyle textStyle;
1045     JSTextPickerTheme::ObtainTextStyle(textStyle);
1046     if (info[0]->IsObject()) {
1047         JSTextPickerParser::ParseTextStyle(info[0], textStyle, "disappearTextStyle");
1048     }
1049     TextPickerModel::GetInstance()->SetDisappearTextStyle(theme, textStyle);
1050 }
1051 
SetTextStyle(const JSCallbackInfo & info)1052 void JSTextPicker::SetTextStyle(const JSCallbackInfo& info)
1053 {
1054     auto theme = GetTheme<PickerTheme>();
1055     CHECK_NULL_VOID(theme);
1056     NG::PickerTextStyle textStyle;
1057     JSTextPickerTheme::ObtainTextStyle(textStyle);
1058     if (info[0]->IsObject()) {
1059         JSTextPickerParser::ParseTextStyle(info[0], textStyle, "textStyle");
1060     }
1061     TextPickerModel::GetInstance()->SetNormalTextStyle(theme, textStyle);
1062 }
1063 
SetSelectedTextStyle(const JSCallbackInfo & info)1064 void JSTextPicker::SetSelectedTextStyle(const JSCallbackInfo& info)
1065 {
1066     auto theme = GetTheme<PickerTheme>();
1067     CHECK_NULL_VOID(theme);
1068     NG::PickerTextStyle textStyle;
1069     JSTextPickerTheme::ObtainSelectedTextStyle(textStyle);
1070     if (info[0]->IsObject()) {
1071         JSTextPickerParser::ParseTextStyle(info[0], textStyle, "selectedTextStyle");
1072     }
1073     TextPickerModel::GetInstance()->SetSelectedTextStyle(theme, textStyle);
1074 }
1075 
ProcessCascadeSelected(const std::vector<NG::TextCascadePickerOptions> & options,uint32_t index,std::vector<uint32_t> & selectedValues)1076 void JSTextPicker::ProcessCascadeSelected(
1077     const std::vector<NG::TextCascadePickerOptions>& options, uint32_t index, std::vector<uint32_t>& selectedValues)
1078 {
1079     std::vector<std::string> rangeResultValue;
1080     for (size_t i = 0; i < options.size(); i++) {
1081         rangeResultValue.emplace_back(options[i].rangeResult[0]);
1082     }
1083 
1084     if (static_cast<int32_t>(index) > static_cast<int32_t>(selectedValues.size()) - 1) {
1085         selectedValues.emplace_back(0);
1086     }
1087     if (selectedValues[index] >= rangeResultValue.size()) {
1088         selectedValues[index] = 0;
1089     }
1090     if (static_cast<int32_t>(selectedValues[index]) <= static_cast<int32_t>(options.size()) - 1 &&
1091         options[selectedValues[index]].children.size() > 0) {
1092         ProcessCascadeSelected(options[selectedValues[index]].children, index + 1, selectedValues);
1093     }
1094 }
1095 
SetSelectedInternal(uint32_t count,std::vector<NG::TextCascadePickerOptions> & options,std::vector<uint32_t> & selectedValues)1096 void JSTextPicker::SetSelectedInternal(
1097     uint32_t count, std::vector<NG::TextCascadePickerOptions>& options, std::vector<uint32_t>& selectedValues)
1098 {
1099     for (uint32_t i = 0; i < count; i++) {
1100         if (selectedValues.size() > 0 && selectedValues.size() < i + 1) {
1101             selectedValues.emplace_back(0);
1102         } else {
1103             if (selectedValues[i] >= options[i].rangeResult.size()) {
1104                 selectedValues[i] = 0;
1105             }
1106         }
1107     }
1108 }
1109 
SetSelectedIndexMultiInternal(uint32_t count,std::vector<NG::TextCascadePickerOptions> & options,std::vector<uint32_t> & selectedValues)1110 void JSTextPicker::SetSelectedIndexMultiInternal(
1111     uint32_t count, std::vector<NG::TextCascadePickerOptions>& options, std::vector<uint32_t>& selectedValues)
1112 {
1113     if (!TextPickerModel::GetInstance()->IsCascade()) {
1114         SetSelectedInternal(count, options, selectedValues);
1115     } else {
1116         TextPickerModel::GetInstance()->SetHasSelectAttr(true);
1117         ProcessCascadeSelected(options, 0, selectedValues);
1118         uint32_t maxCount = TextPickerModel::GetInstance()->GetMaxCount();
1119         if (selectedValues.size() < maxCount) {
1120             auto differ = maxCount - selectedValues.size();
1121             for (uint32_t i = 0; i < differ; i++) {
1122                 selectedValues.emplace_back(0);
1123             }
1124         }
1125     }
1126 }
1127 
SetSelectedIndexSingleInternal(const std::vector<NG::TextCascadePickerOptions> & options,uint32_t count,uint32_t & selectedValue,std::vector<uint32_t> & selectedValues)1128 void JSTextPicker::SetSelectedIndexSingleInternal(const std::vector<NG::TextCascadePickerOptions>& options,
1129     uint32_t count, uint32_t& selectedValue, std::vector<uint32_t>& selectedValues)
1130 {
1131     if (options.size() > 0) {
1132         if (selectedValue >= options[0].rangeResult.size()) {
1133             selectedValue = 0;
1134         }
1135         selectedValues.emplace_back(selectedValue);
1136         for (uint32_t i = 1; i < count; i++) {
1137             selectedValues.emplace_back(0);
1138         }
1139     } else {
1140         for (uint32_t i = 0; i < count; i++) {
1141             selectedValues.emplace_back(0);
1142         }
1143     }
1144 }
1145 
SetSelectedIndexMulti(const JsiRef<JsiValue> & jsSelectedValue)1146 void JSTextPicker::SetSelectedIndexMulti(const JsiRef<JsiValue>& jsSelectedValue)
1147 {
1148     std::vector<uint32_t> selectedValues;
1149     std::vector<NG::TextCascadePickerOptions> options;
1150     TextPickerModel::GetInstance()->GetMultiOptions(options);
1151     auto count =
1152         TextPickerModel::GetInstance()->IsCascade() ? TextPickerModel::GetInstance()->GetMaxCount() : options.size();
1153     if (jsSelectedValue->IsArray()) {
1154         if (!ParseJsIntegerArray(jsSelectedValue, selectedValues)) {
1155             selectedValues.clear();
1156             for (uint32_t i = 0; i < count; i++) {
1157                 selectedValues.emplace_back(0);
1158             }
1159             TextPickerModel::GetInstance()->SetSelecteds(selectedValues);
1160             TextPickerModel::GetInstance()->SetHasSelectAttr(false);
1161             return;
1162         }
1163         SetSelectedIndexMultiInternal(count, options, selectedValues);
1164     } else {
1165         uint32_t selectedValue = 0;
1166         if (ParseJsInteger(jsSelectedValue, selectedValue)) {
1167             TextPickerModel::GetInstance()->SetHasSelectAttr(true);
1168             SetSelectedIndexSingleInternal(options, count, selectedValue, selectedValues);
1169         } else {
1170             selectedValues.clear();
1171             TextPickerModel::GetInstance()->SetHasSelectAttr(false);
1172             for (uint32_t i = 0; i < count; i++) {
1173                 selectedValues.emplace_back(0);
1174             }
1175         }
1176     }
1177     TextPickerModel::GetInstance()->SetSelecteds(selectedValues);
1178 }
1179 
SetSelectedIndexSingle(const JsiRef<JsiValue> & jsSelectedValue)1180 void JSTextPicker::SetSelectedIndexSingle(const JsiRef<JsiValue>& jsSelectedValue)
1181 {
1182     // Single
1183     std::vector<NG::RangeContent> rangeResult;
1184     TextPickerModel::GetInstance()->GetSingleRange(rangeResult);
1185     if (jsSelectedValue->IsArray()) {
1186         std::vector<uint32_t> selectedValues;
1187         if (!ParseJsIntegerArray(jsSelectedValue, selectedValues)) {
1188             uint32_t selectedValue = 0;
1189             TextPickerModel::GetInstance()->SetSelected(selectedValue);
1190             return;
1191         }
1192         if (selectedValues.size() > 0) {
1193             if (selectedValues[0] >= rangeResult.size()) {
1194                 selectedValues[0] = 0;
1195             }
1196         } else {
1197             selectedValues.emplace_back(0);
1198         }
1199 
1200         TextPickerModel::GetInstance()->SetSelected(selectedValues[0]);
1201     } else {
1202         uint32_t selectedValue = 0;
1203         if (ParseJsInteger(jsSelectedValue, selectedValue)) {
1204             if (selectedValue >= rangeResult.size()) {
1205                 selectedValue = 0;
1206             }
1207         }
1208         TextPickerModel::GetInstance()->SetSelected(selectedValue);
1209     }
1210 }
1211 
SetSelectedIndex(const JSCallbackInfo & info)1212 void JSTextPicker::SetSelectedIndex(const JSCallbackInfo& info)
1213 {
1214     if (info.Length() >= 1) {
1215         auto jsSelectedValue = info[0];
1216         if (jsSelectedValue->IsNull() || jsSelectedValue->IsUndefined()) {
1217             return;
1218         }
1219         if (TextPickerModel::GetInstance()->IsSingle()) {
1220             SetSelectedIndexSingle(jsSelectedValue);
1221         } else {
1222             SetSelectedIndexMulti(jsSelectedValue);
1223         }
1224     }
1225 }
1226 
CheckDividerValue(const Dimension & dimension)1227 bool JSTextPicker::CheckDividerValue(const Dimension &dimension)
1228 {
1229     if (dimension.Value() >= 0.0f && dimension.Unit() != DimensionUnit::PERCENT) {
1230         return true;
1231     }
1232     return false;
1233 }
1234 
SetDivider(const JSCallbackInfo & info)1235 void JSTextPicker::SetDivider(const JSCallbackInfo& info)
1236 {
1237     NG::ItemDivider divider;
1238     auto pickerTheme = GetTheme<PickerTheme>();
1239     Dimension defaultStrokeWidth = 0.0_vp;
1240     Dimension defaultMargin = 0.0_vp;
1241     Color defaultColor = Color::TRANSPARENT;
1242     // Set default strokeWidth and color
1243     if (pickerTheme) {
1244         defaultStrokeWidth = pickerTheme->GetDividerThickness();
1245         defaultColor = pickerTheme->GetDividerColor();
1246         divider.strokeWidth = defaultStrokeWidth;
1247         divider.color = defaultColor;
1248     }
1249 
1250     if (info.Length() >= 1 && info[0]->IsObject()) {
1251         JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
1252 
1253         Dimension strokeWidth = defaultStrokeWidth;
1254         if (ConvertFromJSValueNG(obj->GetProperty("strokeWidth"), strokeWidth) && CheckDividerValue(strokeWidth)) {
1255             divider.strokeWidth = strokeWidth;
1256         }
1257 
1258         Color color = defaultColor;
1259         if (ConvertFromJSValue(obj->GetProperty("color"), color)) {
1260             divider.color = color;
1261         }
1262 
1263         Dimension startMargin = defaultMargin;
1264         if (ConvertFromJSValueNG(obj->GetProperty("startMargin"), startMargin) && CheckDividerValue(startMargin)) {
1265             divider.startMargin = startMargin;
1266         }
1267 
1268         Dimension endMargin = defaultMargin;
1269         if (ConvertFromJSValueNG(obj->GetProperty("endMargin"), endMargin) &&  CheckDividerValue(endMargin)) {
1270             divider.endMargin = endMargin;
1271         }
1272     } else if (info.Length() >= 1 && info[0]->IsNull()) {
1273         divider.strokeWidth = 0.0_vp;
1274     }
1275     TextPickerModel::GetInstance()->SetDivider(divider);
1276 }
1277 
OnAccept(const JSCallbackInfo & info)1278 void JSTextPicker::OnAccept(const JSCallbackInfo& info) {}
1279 
OnCancel(const JSCallbackInfo & info)1280 void JSTextPicker::OnCancel(const JSCallbackInfo& info) {}
1281 
OnChange(const JSCallbackInfo & info)1282 void JSTextPicker::OnChange(const JSCallbackInfo& info)
1283 {
1284     if (!info[0]->IsFunction()) {
1285         return;
1286     }
1287     auto jsFunc = JSRef<JSFunc>::Cast(info[0]);
1288     auto onChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](
1289                         const std::vector<std::string>& value, const std::vector<double>& index) {
1290         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1291         ACE_SCORING_EVENT("TextPicker.onChange");
1292         if (value.size() == 1 && index.size() == 1) {
1293             auto params = ConvertToJSValues(value[0], index[0]);
1294             func->Call(JSRef<JSObject>(), static_cast<int>(params.size()), params.data());
1295         } else {
1296             std::vector<JSRef<JSVal>> result;
1297             JSRef<JSArray> valueArray = JSRef<JSArray>::New();
1298             for (uint32_t i = 0; i < value.size(); i++) {
1299                 valueArray->SetValueAt(i, JSRef<JSVal>::Make(ToJSValue(value[i])));
1300             }
1301             JSRef<JSVal> valueJs = JSRef<JSVal>::Cast(valueArray);
1302             result.emplace_back(valueJs);
1303             JSRef<JSArray> selectedArray = JSRef<JSArray>::New();
1304             for (uint32_t i = 0; i < index.size(); i++) {
1305                 selectedArray->SetValueAt(i, JSRef<JSVal>::Make(ToJSValue(index[i])));
1306             }
1307             JSRef<JSVal> selectedJs = JSRef<JSVal>::Cast(selectedArray);
1308             result.emplace_back(selectedJs);
1309             func->Call(JSRef<JSObject>(), static_cast<int>(result.size()), result.data());
1310         }
1311     };
1312     TextPickerModel::GetInstance()->SetOnCascadeChange(std::move(onChange));
1313     info.ReturnSelf();
1314 }
1315 
OnScrollStop(const JSCallbackInfo & info)1316 void JSTextPicker::OnScrollStop(const JSCallbackInfo& info)
1317 {
1318     if (!info[0]->IsFunction()) {
1319         return;
1320     }
1321     auto jsFunc = JSRef<JSFunc>::Cast(info[0]);
1322     auto onScrollStop = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](
1323                         const std::vector<std::string>& value, const std::vector<double>& index) {
1324         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1325         ACE_SCORING_EVENT("TextPicker.onScrollStop");
1326         if (value.size() == 1 && index.size() == 1) {
1327             auto params = ConvertToJSValues(value[0], index[0]);
1328             func->Call(JSRef<JSObject>(), static_cast<int>(params.size()), params.data());
1329         } else {
1330             std::vector<JSRef<JSVal>> result;
1331             JSRef<JSArray> valueArray = JSRef<JSArray>::New();
1332             for (uint32_t i = 0; i < value.size(); i++) {
1333                 valueArray->SetValueAt(i, JSRef<JSVal>::Make(ToJSValue(value[i])));
1334             }
1335             JSRef<JSVal> valueJs = JSRef<JSVal>::Cast(valueArray);
1336             result.emplace_back(valueJs);
1337             JSRef<JSArray> selectedArray = JSRef<JSArray>::New();
1338             for (uint32_t i = 0; i < index.size(); i++) {
1339                 selectedArray->SetValueAt(i, JSRef<JSVal>::Make(ToJSValue(index[i])));
1340             }
1341             JSRef<JSVal> selectedJs = JSRef<JSVal>::Cast(selectedArray);
1342             result.emplace_back(selectedJs);
1343             func->Call(JSRef<JSObject>(), static_cast<int>(result.size()), result.data());
1344         }
1345     };
1346     TextPickerModel::GetInstance()->SetOnScrollStop(std::move(onScrollStop));
1347     info.ReturnSelf();
1348 }
1349 
JSBind(BindingTarget globalObj)1350 void JSTextPickerDialog::JSBind(BindingTarget globalObj)
1351 {
1352     JSClass<JSTextPickerDialog>::Declare("TextPickerDialog");
1353     JSClass<JSTextPickerDialog>::StaticMethod("show", &JSTextPickerDialog::Show);
1354 
1355     JSClass<JSTextPickerDialog>::Bind<>(globalObj);
1356 }
1357 
TextPickerDialogAppearEvent(const JSCallbackInfo & info,TextPickerDialogEvent & textPickerDialogEvent)1358 void TextPickerDialogAppearEvent(const JSCallbackInfo& info, TextPickerDialogEvent& textPickerDialogEvent)
1359 {
1360     std::function<void()> didAppearEvent;
1361     std::function<void()> willAppearEvent;
1362     if (!info[0]->IsObject()) {
1363         return;
1364     }
1365     auto paramObject = JSRef<JSObject>::Cast(info[0]);
1366     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1367     auto onDidAppear = paramObject->GetProperty("onDidAppear");
1368     if (!onDidAppear->IsUndefined() && onDidAppear->IsFunction()) {
1369         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidAppear));
1370         didAppearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1371             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1372             ACE_SCORING_EVENT("TextPickerDialog.onDidAppear");
1373             PipelineContext::SetCallBackNode(node);
1374             func->Execute();
1375         };
1376     }
1377     auto onWillAppear = paramObject->GetProperty("onWillAppear");
1378     if (!onWillAppear->IsUndefined() && onWillAppear->IsFunction()) {
1379         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillAppear));
1380         willAppearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1381             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1382             ACE_SCORING_EVENT("TextPickerDialog.onWillAppear");
1383             PipelineContext::SetCallBackNode(node);
1384             func->Execute();
1385         };
1386     }
1387     textPickerDialogEvent.onDidAppear = std::move(didAppearEvent);
1388     textPickerDialogEvent.onWillAppear = std::move(willAppearEvent);
1389 }
1390 
TextPickerDialogDisappearEvent(const JSCallbackInfo & info,TextPickerDialogEvent & textPickerDialogEvent)1391 void TextPickerDialogDisappearEvent(const JSCallbackInfo& info, TextPickerDialogEvent& textPickerDialogEvent)
1392 {
1393     std::function<void()> didDisappearEvent;
1394     std::function<void()> willDisappearEvent;
1395     if (!info[0]->IsObject()) {
1396         return;
1397     }
1398     auto paramObject = JSRef<JSObject>::Cast(info[0]);
1399     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1400     auto onDidDisappear = paramObject->GetProperty("onDidDisappear");
1401     if (!onDidDisappear->IsUndefined() && onDidDisappear->IsFunction()) {
1402         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidDisappear));
1403         didDisappearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1404             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1405             ACE_SCORING_EVENT("TextPickerDialog.onDidDisappear");
1406             PipelineContext::SetCallBackNode(node);
1407             func->Execute();
1408         };
1409     }
1410     auto onWillDisappear = paramObject->GetProperty("onWillDisappear");
1411     if (!onWillDisappear->IsUndefined() && onWillDisappear->IsFunction()) {
1412         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDisappear));
1413         willDisappearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1414             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1415             ACE_SCORING_EVENT("TextPickerDialog.onWillDisappear");
1416             PipelineContext::SetCallBackNode(node);
1417             func->Execute();
1418         };
1419     }
1420     textPickerDialogEvent.onDidDisappear = std::move(didDisappearEvent);
1421     textPickerDialogEvent.onWillDisappear = std::move(willDisappearEvent);
1422 }
1423 
Show(const JSCallbackInfo & info)1424 void JSTextPickerDialog::Show(const JSCallbackInfo& info)
1425 {
1426     auto scopedDelegate = EngineHelper::GetCurrentDelegateSafely();
1427     CHECK_NULL_VOID(scopedDelegate);
1428     if (!info[0]->IsObject()) {
1429         return;
1430     }
1431 
1432     auto paramObject = JSRef<JSObject>::Cast(info[0]);
1433     std::function<void()> cancelEvent;
1434     std::function<void(const std::string&)> acceptEvent;
1435     std::function<void(const std::string&)> changeEvent;
1436     auto onCancel = paramObject->GetProperty("onCancel");
1437     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1438     if (!onCancel->IsUndefined() && onCancel->IsFunction()) {
1439         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onCancel));
1440         cancelEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1441             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1442             ACE_SCORING_EVENT("TextPickerDialog.onCancel");
1443             PipelineContext::SetCallBackNode(node);
1444             func->Execute();
1445         };
1446     }
1447     auto onAccept = paramObject->GetProperty("onAccept");
1448     if (!onAccept->IsUndefined() && onAccept->IsFunction()) {
1449         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAccept));
1450         acceptEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1451                           const std::string& info) {
1452             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1453             std::vector<std::string> keys = { "value", "index" };
1454             ACE_SCORING_EVENT("TextPickerDialog.onAccept");
1455             PipelineContext::SetCallBackNode(node);
1456             func->Execute(keys, info);
1457         };
1458     }
1459     auto onChange = paramObject->GetProperty("onChange");
1460     if (!onChange->IsUndefined() && onChange->IsFunction()) {
1461         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onChange));
1462         changeEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1463                           const std::string& info) {
1464             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1465             std::vector<std::string> keys = { "value", "index" };
1466             ACE_SCORING_EVENT("TextPickerDialog.onChange");
1467             PipelineContext::SetCallBackNode(node);
1468             func->Execute(keys, info);
1469         };
1470     }
1471     std::function<void(const std::string&)> scrollStopEvent;
1472     auto onScrollStop = paramObject->GetProperty("onScrollStop");
1473     if (!onScrollStop->IsUndefined() && onScrollStop->IsFunction()) {
1474         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onScrollStop));
1475         scrollStopEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1476                               const std::string& info) {
1477             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1478             std::vector<std::string> keys = { "value", "index" };
1479             ACE_SCORING_EVENT("TextPickerDialog.onScrollStop");
1480             PipelineContext::SetCallBackNode(node);
1481             func->Execute(keys, info);
1482         };
1483     }
1484     NG::TextPickerSettingData settingData;
1485     TextPickerDialog textPickerDialog;
1486 
1487     auto pickerText = TextPickerDialogModel::GetInstance()->CreateObject();
1488     if (pickerText == nullptr) {
1489         // parse Multi column text
1490         if (!ParseShowData(paramObject, settingData)) {
1491             return;
1492         }
1493     } else {
1494         auto getSelected = paramObject->GetProperty("selected");
1495         auto defaultHeight = paramObject->GetProperty("defaultPickerItemHeight");
1496         auto canLoop = paramObject->GetProperty("canLoop");
1497         JSRef<JSArray> getRange = paramObject->GetProperty("range");
1498         std::vector<std::string> getRangeVector;
1499         if (!JSViewAbstract::ParseJsStrArray(getRange, getRangeVector)) {
1500             return;
1501         }
1502         std::string value = "";
1503         uint32_t selectedValue = 0;
1504         auto getValue = paramObject->GetProperty("value");
1505         if (!JSViewAbstract::ParseJsInteger(getSelected, selectedValue) &&
1506             JSViewAbstract::ParseJsString(getValue, value)) {
1507             auto valueIterator = std::find(getRangeVector.begin(), getRangeVector.end(), value);
1508             if (valueIterator != getRangeVector.end()) {
1509                 selectedValue = static_cast<uint32_t>(std::distance(getRangeVector.begin(), valueIterator));
1510             }
1511         }
1512         if (selectedValue >= getRangeVector.size()) {
1513             selectedValue = 0;
1514         }
1515         CalcDimension height;
1516         if (defaultHeight->IsNumber() || defaultHeight->IsString()) {
1517             if (!JSViewAbstract::ParseJsDimensionFp(defaultHeight, height)) {
1518                 return;
1519             }
1520         }
1521         if (!defaultHeight->IsEmpty()) {
1522             textPickerDialog.isDefaultHeight = true;
1523         }
1524         textPickerDialog.height = height;
1525         textPickerDialog.selectedValue = selectedValue;
1526         textPickerDialog.getRangeVector = getRangeVector;
1527     }
1528 
1529     // Parse alignment
1530     auto alignmentValue = paramObject->GetProperty("alignment");
1531     if (alignmentValue->IsNumber()) {
1532         auto alignment = alignmentValue->ToNumber<int32_t>();
1533         if (alignment >= 0 && alignment < static_cast<int32_t>(DIALOG_ALIGNMENT.size())) {
1534             textPickerDialog.alignment = DIALOG_ALIGNMENT[alignment];
1535         }
1536         if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1537             if (alignment == static_cast<int32_t>(DialogAlignment::TOP) ||
1538                 alignment == static_cast<int32_t>(DialogAlignment::TOP_START) ||
1539                 alignment == static_cast<int32_t>(DialogAlignment::TOP_END)) {
1540                 textPickerDialog.offset = TEXT_PICKER_OFFSET_DEFAULT_TOP;
1541             }
1542         }
1543     }
1544 
1545     // Parse offset
1546     auto offsetValue = paramObject->GetProperty("offset");
1547     if (offsetValue->IsObject()) {
1548         auto offsetObj = JSRef<JSObject>::Cast(offsetValue);
1549         CalcDimension dx;
1550         auto dxValue = offsetObj->GetProperty("dx");
1551         JSAlertDialog::ParseJsDimensionVp(dxValue, dx);
1552         CalcDimension dy;
1553         auto dyValue = offsetObj->GetProperty("dy");
1554         JSAlertDialog::ParseJsDimensionVp(dyValue, dy);
1555         textPickerDialog.offset = DimensionOffset(dx, dy);
1556     }
1557 
1558     // Parse maskRect.
1559     auto maskRectValue = paramObject->GetProperty("maskRect");
1560     DimensionRect maskRect;
1561     if (JSViewAbstract::ParseJsDimensionRect(maskRectValue, maskRect)) {
1562         textPickerDialog.maskRect = maskRect;
1563     }
1564 
1565     auto backgroundColorValue = paramObject->GetProperty("backgroundColor");
1566     Color backgroundColor;
1567     if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor)) {
1568         textPickerDialog.backgroundColor = backgroundColor;
1569     }
1570 
1571     auto backgroundBlurStyle = paramObject->GetProperty("backgroundBlurStyle");
1572     if (backgroundBlurStyle->IsNumber()) {
1573         auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>();
1574         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
1575             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
1576             textPickerDialog.backgroundBlurStyle = blurStyle;
1577         }
1578     }
1579     auto shadowValue = paramObject->GetProperty("shadow");
1580     Shadow shadow;
1581     if ((shadowValue->IsObject() || shadowValue->IsNumber()) && JSViewAbstract::ParseShadowProps(shadowValue, shadow)) {
1582         textPickerDialog.shadow = shadow;
1583     }
1584 
1585     auto enableHoverModeValue = paramObject->GetProperty("enableHoverMode");
1586     if (enableHoverModeValue->IsBoolean()) {
1587         textPickerDialog.enableHoverMode = enableHoverModeValue->ToBoolean();
1588     }
1589 
1590     auto hoverModeAreaValue = paramObject->GetProperty("hoverModeArea");
1591     if (hoverModeAreaValue->IsNumber()) {
1592         auto hoverModeArea = hoverModeAreaValue->ToNumber<int32_t>();
1593         if (hoverModeArea >= 0 && hoverModeArea < static_cast<int32_t>(HOVER_MODE_AREA_TYPE.size())) {
1594             textPickerDialog.hoverModeArea = HOVER_MODE_AREA_TYPE[hoverModeArea];
1595         }
1596     }
1597 
1598     auto buttonInfos = ParseButtonStyles(paramObject);
1599 
1600     TextPickerDialogEvent textPickerDialogEvent { nullptr, nullptr, nullptr, nullptr };
1601     TextPickerDialogAppearEvent(info, textPickerDialogEvent);
1602     TextPickerDialogDisappearEvent(info, textPickerDialogEvent);
1603     TextPickerDialogModel::GetInstance()->SetTextPickerDialogShow(pickerText, settingData, std::move(cancelEvent),
1604         std::move(acceptEvent), std::move(changeEvent), std::move(scrollStopEvent), textPickerDialog,
1605         textPickerDialogEvent, buttonInfos);
1606 }
1607 
TextPickerDialogShow(const JSRef<JSObject> & paramObj,const std::map<std::string,NG::DialogTextEvent> & dialogEvent,const std::map<std::string,NG::DialogGestureEvent> & dialogCancelEvent)1608 void JSTextPickerDialog::TextPickerDialogShow(const JSRef<JSObject>& paramObj,
1609     const std::map<std::string, NG::DialogTextEvent>& dialogEvent,
1610     const std::map<std::string, NG::DialogGestureEvent>& dialogCancelEvent)
1611 {
1612     auto container = Container::CurrentSafely();
1613     if (!container) {
1614         return;
1615     }
1616     auto pipelineContext = AccessibilityManager::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
1617     if (!pipelineContext) {
1618         return;
1619     }
1620 
1621     auto executor = pipelineContext->GetTaskExecutor();
1622     if (!executor) {
1623         return;
1624     }
1625 
1626     auto theme = JSTextPicker::GetTheme<DialogTheme>();
1627     CHECK_NULL_VOID(theme);
1628 
1629     NG::TextPickerSettingData settingData;
1630     if (!ParseShowData(paramObj, settingData)) {
1631         return;
1632     }
1633 
1634     DialogProperties properties;
1635     properties.alignment = theme->GetAlignment();
1636     if (properties.alignment == DialogAlignment::BOTTOM &&
1637         Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_ELEVEN)) {
1638         properties.offset = DimensionOffset(Offset(0, -theme->GetMarginBottom().ConvertToPx()));
1639     }
1640 
1641     properties.customStyle = false;
1642     if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1643         properties.offset = DimensionOffset(Offset(0, -theme->GetMarginBottom().ConvertToPx()));
1644     }
1645     auto context = AccessibilityManager::DynamicCast<NG::PipelineContext>(pipelineContext);
1646     auto overlayManager = context ? context->GetOverlayManager() : nullptr;
1647     executor->PostTask(
1648         [properties, settingData, dialogEvent, dialogCancelEvent, weak = WeakPtr<NG::OverlayManager>(overlayManager)] {
1649             auto overlayManager = weak.Upgrade();
1650             CHECK_NULL_VOID(overlayManager);
1651             overlayManager->ShowTextDialog(properties, settingData, dialogEvent, dialogCancelEvent);
1652         },
1653         TaskExecutor::TaskType::UI, "ArkUIDialogShowTextPicker");
1654 }
1655 
ParseShowDataOptions(const JSRef<JSObject> & paramObject,ParseTextArrayParam & param,NG::TextCascadePickerOptionsAttr & attr)1656 bool JSTextPickerDialog::ParseShowDataOptions(
1657     const JSRef<JSObject>& paramObject, ParseTextArrayParam& param, NG::TextCascadePickerOptionsAttr& attr)
1658 {
1659     bool optionsMultiContentCheckErr = false;
1660     bool optionsCascadeContentCheckErr = false;
1661     if (!JSTextPickerParser::ParseMultiTextArray(paramObject, param)) {
1662         param.options.clear();
1663         optionsMultiContentCheckErr = true;
1664     }
1665 
1666     if (optionsMultiContentCheckErr) {
1667         if (!JSTextPickerParser::ParseCascadeTextArray(paramObject, param.selecteds, param.values, attr)) {
1668             param.options.clear();
1669             optionsCascadeContentCheckErr = true;
1670         } else {
1671             JSRef<JSArray> getRange = paramObject->GetProperty("range");
1672             JSTextPickerParser::GenerateCascadeOptions(getRange, param.options);
1673             attr.isCascade = true;
1674         }
1675     }
1676     if (optionsMultiContentCheckErr && optionsCascadeContentCheckErr) {
1677         param.options.clear();
1678         return false;
1679     }
1680     return true;
1681 }
1682 
ParseShowDataAttribute(const JSRef<JSObject> & paramObject,NG::TextPickerSettingData & settingData)1683 bool JSTextPickerDialog::ParseShowDataAttribute(
1684     const JSRef<JSObject>& paramObject, NG::TextPickerSettingData& settingData)
1685 {
1686     CalcDimension height;
1687     auto defaultHeight = paramObject->GetProperty("defaultPickerItemHeight");
1688     if (defaultHeight->IsNumber() || defaultHeight->IsString()) {
1689         if (!JSViewAbstract::ParseJsDimensionFp(defaultHeight, height)) {
1690             return false;
1691         }
1692     }
1693     settingData.height = height;
1694     ParseTextProperties(paramObject, settingData.properties);
1695     return true;
1696 }
1697 
ParseCanLoop(const JSRef<JSObject> & paramObject,bool & canLoop)1698 bool JSTextPickerDialog::ParseCanLoop(const JSRef<JSObject>& paramObject, bool& canLoop)
1699 {
1700     bool result = false;
1701     auto prop = paramObject->GetProperty("canLoop");
1702     bool value = false;
1703     if (prop->IsBoolean() && JSViewAbstract::ParseJsBool(prop, value)) {
1704         canLoop = value;
1705         result = true;
1706     } else {
1707         canLoop = true;
1708         result = false;
1709     }
1710     return result;
1711 }
1712 
ParseDisableTextStyleAnimation(const JSRef<JSObject> & paramObject,bool & isDisableTextStyleAnimation)1713 void JSTextPickerDialog::ParseDisableTextStyleAnimation(
1714     const JSRef<JSObject>& paramObject, bool& isDisableTextStyleAnimation)
1715 {
1716     auto prop = paramObject->GetProperty("disableTextStyleAnimation");
1717     bool value = false;
1718     if (prop->IsBoolean() && JSViewAbstract::ParseJsBool(prop, value)) {
1719         isDisableTextStyleAnimation = value;
1720     } else {
1721         isDisableTextStyleAnimation = false;
1722     }
1723 }
1724 
ParseShowDataMultiContent(const std::vector<NG::TextCascadePickerOptions> & options,const std::vector<uint32_t> & selectedValues,const std::vector<std::string> & values,NG::TextCascadePickerOptionsAttr & attr,NG::TextPickerSettingData & settingData)1725 void JSTextPickerDialog::ParseShowDataMultiContent(const std::vector<NG::TextCascadePickerOptions>& options,
1726     const std::vector<uint32_t>& selectedValues, const std::vector<std::string>& values,
1727     NG::TextCascadePickerOptionsAttr& attr, NG::TextPickerSettingData& settingData)
1728 {
1729     settingData.columnKind = NG::TEXT;
1730     for (auto& item : selectedValues) {
1731         settingData.selectedValues.emplace_back(item);
1732     }
1733     for (auto& item : values) {
1734         settingData.values.emplace_back(item);
1735     }
1736     for (auto& item : options) {
1737         settingData.options.emplace_back(item);
1738     }
1739     settingData.attr.isCascade = attr.isCascade;
1740     settingData.attr.isHasSelectAttr = attr.isHasSelectAttr;
1741 }
1742 
ParseShowData(const JSRef<JSObject> & paramObject,NG::TextPickerSettingData & settingData)1743 bool JSTextPickerDialog::ParseShowData(const JSRef<JSObject>& paramObject, NG::TextPickerSettingData& settingData)
1744 {
1745     ParseTextArrayParam param;
1746     bool rangeContentCheckErr = false;
1747     bool optionsCascadeContentCheckErr = false;
1748     NG::TextCascadePickerOptionsAttr attr;
1749     auto getRange = paramObject->GetProperty("range");
1750     if (getRange->IsNull() || getRange->IsUndefined()) {
1751         return false;
1752     }
1753     if (!JSTextPickerParser::ParseTextArray(paramObject, param)) {
1754         if (!JSTextPickerParser::ParseIconTextArray(paramObject, param.result, param.kind, param.selected)) {
1755             rangeContentCheckErr = true;
1756             param.result.clear();
1757         }
1758     }
1759     if (rangeContentCheckErr) {
1760         optionsCascadeContentCheckErr = !ParseShowDataOptions(paramObject, param, attr);
1761     }
1762     if (rangeContentCheckErr && optionsCascadeContentCheckErr) {
1763         return false;
1764     }
1765     if (memset_s(&settingData, sizeof(NG::TextPickerSettingData), 0, sizeof(NG::TextPickerSettingData)) != EOK) {
1766         return false;
1767     }
1768     if (!ParseShowDataAttribute(paramObject, settingData)) {
1769         return false;
1770     }
1771     ParseCanLoop(paramObject, settingData.canLoop);
1772     ParseDisableTextStyleAnimation(paramObject, settingData.isDisableTextStyleAnimation);
1773     if (param.result.size() > 0) {
1774         settingData.selected = param.selected;
1775         settingData.columnKind = param.kind;
1776         for (const auto& item : param.result) {
1777             settingData.rangeVector.emplace_back(item);
1778         }
1779     } else {
1780         ParseShowDataMultiContent(param.options, param.selecteds, param.values, attr, settingData);
1781     }
1782     return true;
1783 }
1784 
ParseTextProperties(const JSRef<JSObject> & paramObj,NG::PickerTextProperties & result)1785 void JSTextPickerDialog::ParseTextProperties(const JSRef<JSObject>& paramObj, NG::PickerTextProperties& result)
1786 {
1787     auto disappearProperty = paramObj->GetProperty("disappearTextStyle");
1788     auto normalProperty = paramObj->GetProperty("textStyle");
1789     auto selectedProperty = paramObj->GetProperty("selectedTextStyle");
1790     auto defaultProperty = paramObj->GetProperty("defaultTextStyle");
1791 
1792     if (!disappearProperty->IsNull() && disappearProperty->IsObject()) {
1793         JSRef<JSObject> disappearObj = JSRef<JSObject>::Cast(disappearProperty);
1794         JSTextPickerParser::ParseTextStyle(disappearObj, result.disappearTextStyle_, "disappearTextStyle");
1795     }
1796 
1797     if (!normalProperty->IsNull() && normalProperty->IsObject()) {
1798         JSRef<JSObject> noramlObj = JSRef<JSObject>::Cast(normalProperty);
1799         JSTextPickerParser::ParseTextStyle(noramlObj, result.normalTextStyle_, "textStyle");
1800     }
1801 
1802     if (!selectedProperty->IsNull() && selectedProperty->IsObject()) {
1803         JSRef<JSObject> selectedObj = JSRef<JSObject>::Cast(selectedProperty);
1804         JSTextPickerParser::ParseTextStyle(selectedObj, result.selectedTextStyle_, "selectedTextStyle");
1805     }
1806 
1807     if (!defaultProperty->IsNull() && defaultProperty->IsObject()) {
1808         JSRef<JSObject> defaultObj = JSRef<JSObject>::Cast(defaultProperty);
1809         JSTextPickerParser::ParseTextStyle(defaultObj, result.defaultTextStyle_, "defaultTextStyle");
1810     }
1811 }
1812 
DialogEvent(const JSCallbackInfo & info)1813 std::map<std::string, NG::DialogTextEvent> JSTextPickerDialog::DialogEvent(const JSCallbackInfo& info)
1814 {
1815     std::map<std::string, NG::DialogTextEvent> dialogEvent;
1816     if (!info[0]->IsObject()) {
1817         return dialogEvent;
1818     }
1819     auto paramObject = JSRef<JSObject>::Cast(info[0]);
1820     auto onAccept = paramObject->GetProperty("onAccept");
1821     auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1822     if (!onAccept->IsUndefined() && onAccept->IsFunction()) {
1823         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAccept));
1824         auto acceptId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1825                             const std::string& info) {
1826             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1827             std::vector<std::string> keys = { "value", "index" };
1828             ACE_SCORING_EVENT("TextPickerDialog.onAccept");
1829             PipelineContext::SetCallBackNode(node);
1830             func->Execute(keys, info);
1831         };
1832         dialogEvent["acceptId"] = acceptId;
1833     }
1834     auto onChange = paramObject->GetProperty("onChange");
1835     if (!onChange->IsUndefined() && onChange->IsFunction()) {
1836         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onChange));
1837         auto changeId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1838                             const std::string& info) {
1839             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1840             std::vector<std::string> keys = { "value", "index" };
1841             ACE_SCORING_EVENT("TextPickerDialog.onChange");
1842             PipelineContext::SetCallBackNode(node);
1843             func->Execute(keys, info);
1844         };
1845         dialogEvent["changeId"] = changeId;
1846     }
1847     auto onScrollStop = paramObject->GetProperty("onScrollStop");
1848     if (!onScrollStop->IsUndefined() && onScrollStop->IsFunction()) {
1849         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onScrollStop));
1850         auto scrollStopId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1851                             const std::string& info) {
1852             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1853             std::vector<std::string> keys = { "value", "index" };
1854             ACE_SCORING_EVENT("TextPickerDialog.onScrollStop");
1855             PipelineContext::SetCallBackNode(node);
1856             func->Execute(keys, info);
1857         };
1858         dialogEvent["scrollStopId"] = scrollStopId;
1859     }
1860     return dialogEvent;
1861 }
1862 
DialogCancelEvent(const JSCallbackInfo & info)1863 std::map<std::string, NG::DialogGestureEvent> JSTextPickerDialog::DialogCancelEvent(const JSCallbackInfo& info)
1864 {
1865     std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent;
1866     if (!info[0]->IsObject()) {
1867         return dialogCancelEvent;
1868     }
1869     auto paramObject = JSRef<JSObject>::Cast(info[0]);
1870     auto onCancel = paramObject->GetProperty("onCancel");
1871     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1872     if (!onCancel->IsUndefined() && onCancel->IsFunction()) {
1873         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onCancel));
1874         auto cancelId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1875                             const GestureEvent& /* info */) {
1876             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1877             ACE_SCORING_EVENT("TextPickerDialog.onCancel");
1878             PipelineContext::SetCallBackNode(node);
1879             func->Execute();
1880         };
1881         dialogCancelEvent["cancelId"] = cancelId;
1882     }
1883     return dialogCancelEvent;
1884 }
1885 
AddEvent(RefPtr<PickerTextComponent> & picker,const JSCallbackInfo & info)1886 void JSTextPickerDialog::AddEvent(RefPtr<PickerTextComponent>& picker, const JSCallbackInfo& info)
1887 {
1888     if (!info[0]->IsObject()) {
1889         return;
1890     }
1891     auto paramObject = JSRef<JSObject>::Cast(info[0]);
1892     auto onAccept = paramObject->GetProperty("onAccept");
1893     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1894     if (!onAccept->IsUndefined() && onAccept->IsFunction()) {
1895         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAccept));
1896         auto acceptId = EventMarker([execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1897                                         const std::string& info) {
1898             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1899             std::vector<std::string> keys = { "value", "index" };
1900             ACE_SCORING_EVENT("TextPickerDialog.onAccept");
1901             PipelineContext::SetCallBackNode(node);
1902             func->Execute(keys, info);
1903         });
1904         picker->SetDialogAcceptEvent(acceptId);
1905     }
1906     auto onCancel = paramObject->GetProperty("onCancel");
1907     if (!onCancel->IsUndefined() && onCancel->IsFunction()) {
1908         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onCancel));
1909         auto cancelId =
1910             EventMarker([execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1911                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1912                 ACE_SCORING_EVENT("TextPickerDialog.onCancel");
1913                 PipelineContext::SetCallBackNode(node);
1914                 func->Execute();
1915             });
1916         picker->SetDialogCancelEvent(cancelId);
1917     }
1918     auto onChange = paramObject->GetProperty("onChange");
1919     if (!onChange->IsUndefined() && onChange->IsFunction()) {
1920         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onChange));
1921         auto changeId = EventMarker([execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1922                                         const std::string& info) {
1923             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1924             std::vector<std::string> keys = { "value", "index" };
1925             ACE_SCORING_EVENT("TextPickerDialog.onChange");
1926             PipelineContext::SetCallBackNode(node);
1927             func->Execute(keys, info);
1928         });
1929         picker->SetDialogChangeEvent(changeId);
1930     }
1931 }
1932 
ParseText(RefPtr<PickerTextComponent> & component,const JSRef<JSObject> & paramObj)1933 void JSTextPickerDialog::ParseText(RefPtr<PickerTextComponent>& component, const JSRef<JSObject>& paramObj)
1934 {
1935     auto getSelected = paramObj->GetProperty("selected");
1936     auto defaultHeight = paramObj->GetProperty("defaultPickerItemHeight");
1937     auto canLoop = paramObj->GetProperty("canLoop");
1938     JSRef<JSArray> getRange = paramObj->GetProperty("range");
1939     std::vector<std::string> getRangeVector;
1940     if (!JSViewAbstract::ParseJsStrArray(getRange, getRangeVector)) {
1941         return;
1942     }
1943 
1944     std::string value = "";
1945     uint32_t selectedValue = 0;
1946     auto getValue = paramObj->GetProperty("value");
1947     if (!JSViewAbstract::ParseJsInteger(getSelected, selectedValue) && JSViewAbstract::ParseJsString(getValue, value)) {
1948         auto valueIterator = std::find(getRangeVector.begin(), getRangeVector.end(), value);
1949         if (valueIterator != getRangeVector.end()) {
1950             selectedValue = static_cast<uint32_t>(std::distance(getRangeVector.begin(), valueIterator));
1951         }
1952     }
1953 
1954     if (selectedValue >= getRangeVector.size()) {
1955         selectedValue = 0;
1956     }
1957 
1958     CalcDimension height;
1959     if (defaultHeight->IsNumber() || defaultHeight->IsString()) {
1960         if (!JSViewAbstract::ParseJsDimensionFp(defaultHeight, height)) {
1961             return;
1962         }
1963     }
1964 
1965     component->SetIsDialog(true);
1966     component->SetIsCreateDialogComponent(true);
1967     if (!defaultHeight->IsEmpty()) {
1968         component->SetColumnHeight(height);
1969         component->SetDefaultHeight(true);
1970     }
1971     component->SetSelected(selectedValue);
1972     component->SetRange(getRangeVector);
1973 }
1974 } // namespace OHOS::Ace::Framework
1975