• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "bridge/declarative_frontend/jsview/js_textpicker.h"
17 
18 #include <securec.h>
19 
20 #include "base/log/ace_scoring_log.h"
21 #include "bridge/common/utils/engine_helper.h"
22 #include "bridge/declarative_frontend/engine/functions/js_function.h"
23 #include "bridge/declarative_frontend/jsview/js_datepicker.h"
24 #include "bridge/declarative_frontend/jsview/js_interactable_view.h"
25 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
26 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
27 #include "bridge/declarative_frontend/jsview/models/textpicker_model_impl.h"
28 #include "bridge/declarative_frontend/view_stack_processor.h"
29 #include "core/components/picker/picker_base_component.h"
30 #include "core/components/picker/picker_theme.h"
31 #include "core/components_ng/base/view_stack_processor.h"
32 #include "core/components_ng/pattern/text_picker/textpicker_model.h"
33 #include "core/components_ng/pattern/text_picker/textpicker_model_ng.h"
34 #include "core/pipeline_ng/pipeline_context.h"
35 
36 namespace OHOS::Ace {
37 namespace {
38 const DimensionOffset TEXT_PICKER_OFFSET_DEFAULT_TOP = DimensionOffset(0.0_vp, 40.0_vp);
39 const std::vector<DialogAlignment> DIALOG_ALIGNMENT = { DialogAlignment::TOP, DialogAlignment::CENTER,
40     DialogAlignment::BOTTOM, DialogAlignment::DEFAULT, DialogAlignment::TOP_START, DialogAlignment::TOP_END,
41     DialogAlignment::CENTER_START, DialogAlignment::CENTER_END, DialogAlignment::BOTTOM_START,
42     DialogAlignment::BOTTOM_END };
43 }
44 
45 std::unique_ptr<TextPickerModel> TextPickerModel::textPickerInstance_ = nullptr;
46 std::unique_ptr<TextPickerDialogModel> TextPickerDialogModel::textPickerDialogInstance_ = nullptr;
47 std::mutex TextPickerModel::mutex_;
48 std::mutex TextPickerDialogModel::mutex_;
49 
GetInstance()50 TextPickerModel* TextPickerModel::GetInstance()
51 {
52     if (!textPickerInstance_) {
53         std::lock_guard<std::mutex> lock(mutex_);
54         if (!textPickerInstance_) {
55 #ifdef NG_BUILD
56             textPickerInstance_.reset(new NG::TextPickerModelNG());
57 #else
58             if (Container::IsCurrentUseNewPipeline()) {
59                 textPickerInstance_.reset(new NG::TextPickerModelNG());
60             } else {
61                 textPickerInstance_.reset(new Framework::TextPickerModelImpl());
62             }
63 #endif
64         }
65     }
66     return textPickerInstance_.get();
67 }
68 
GetInstance()69 TextPickerDialogModel* TextPickerDialogModel::GetInstance()
70 {
71     if (!textPickerDialogInstance_) {
72         std::lock_guard<std::mutex> lock(mutex_);
73         if (!textPickerDialogInstance_) {
74 #ifdef NG_BUILD
75             textPickerDialogInstance_.reset(new NG::TextPickerDialogModelNG());
76 #else
77             if (Container::IsCurrentUseNewPipeline()) {
78                 textPickerDialogInstance_.reset(new NG::TextPickerDialogModelNG());
79             } else {
80                 textPickerDialogInstance_.reset(new Framework::TextPickerDialogModelImpl());
81             }
82 #endif
83         }
84     }
85     return textPickerDialogInstance_.get();
86 }
87 } // namespace OHOS::Ace
88 
89 namespace OHOS::Ace::Framework {
JSBind(BindingTarget globalObj)90 void JSTextPicker::JSBind(BindingTarget globalObj)
91 {
92     JSClass<JSTextPicker>::Declare("TextPicker");
93     MethodOptions opt = MethodOptions::NONE;
94     JSClass<JSTextPicker>::StaticMethod("create", &JSTextPicker::Create, opt);
95     JSClass<JSTextPicker>::StaticMethod("defaultPickerItemHeight", &JSTextPicker::SetDefaultPickerItemHeight);
96     JSClass<JSTextPicker>::StaticMethod("canLoop", &JSTextPicker::SetCanLoop);
97     JSClass<JSTextPicker>::StaticMethod("disappearTextStyle", &JSTextPicker::SetDisappearTextStyle);
98     JSClass<JSTextPicker>::StaticMethod("textStyle", &JSTextPicker::SetTextStyle);
99     JSClass<JSTextPicker>::StaticMethod("selectedTextStyle", &JSTextPicker::SetSelectedTextStyle);
100     JSClass<JSTextPicker>::StaticMethod("selectedIndex", &JSTextPicker::SetSelectedIndex);
101     JSClass<JSTextPicker>::StaticMethod("onAccept", &JSTextPicker::OnAccept);
102     JSClass<JSTextPicker>::StaticMethod("onCancel", &JSTextPicker::OnCancel);
103     JSClass<JSTextPicker>::StaticMethod("onChange", &JSTextPicker::OnChange);
104     JSClass<JSTextPicker>::StaticMethod("backgroundColor", &JSTextPicker::PickerBackgroundColor);
105     JSClass<JSTextPicker>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
106     JSClass<JSTextPicker>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
107     JSClass<JSTextPicker>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
108     JSClass<JSTextPicker>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
109     JSClass<JSTextPicker>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
110     JSClass<JSTextPicker>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
111     JSClass<JSTextPicker>::InheritAndBind<JSViewAbstract>(globalObj);
112 }
113 
PickerBackgroundColor(const JSCallbackInfo & info)114 void JSTextPicker::PickerBackgroundColor(const JSCallbackInfo& info)
115 {
116     JSViewAbstract::JsBackgroundColor(info);
117 
118     if (info.Length() < 1) {
119         return;
120     }
121     Color backgroundColor;
122     if (!ParseJsColor(info[0], backgroundColor)) {
123         return;
124     }
125     TextPickerModel::GetInstance()->SetBackgroundColor(backgroundColor);
126 }
127 
ProcessCascadeOptionDepth(const NG::TextCascadePickerOptions & option)128 size_t JSTextPicker::ProcessCascadeOptionDepth(const NG::TextCascadePickerOptions& option)
129 {
130     size_t depth = 1;
131     if (option.children.size() == 0) {
132         return depth;
133     }
134 
135     for (auto&& pos : option.children) {
136         size_t tmpDep = 1;
137         tmpDep += ProcessCascadeOptionDepth(pos);
138         if (tmpDep > depth) {
139             depth = tmpDep;
140         }
141     }
142     return depth;
143 }
144 
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)145 void JSTextPicker::CreateMulti(const RefPtr<PickerTheme>& theme, const std::vector<std::string>& values,
146     const std::vector<uint32_t>& selectedValues, const NG::TextCascadePickerOptionsAttr& attr,
147     const std::vector<NG::TextCascadePickerOptions>& options)
148 {
149     TextPickerModel::GetInstance()->MultiInit(theme);
150     TextPickerModel::GetInstance()->SetValues(values);
151     TextPickerModel::GetInstance()->SetSelecteds(selectedValues);
152     TextPickerModel::GetInstance()->SetIsCascade(attr.isCascade);
153     TextPickerModel::GetInstance()->SetHasSelectAttr(attr.isHasSelectAttr);
154     TextPickerModel::GetInstance()->SetColumns(options);
155 }
156 
ParseTextPickerValueObject(const JSCallbackInfo & info,const JSRef<JSVal> & changeEventVal)157 void ParseTextPickerValueObject(const JSCallbackInfo& info, const JSRef<JSVal>& changeEventVal)
158 {
159     CHECK_NULL_VOID(changeEventVal->IsFunction());
160 
161     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
162     WeakPtr<NG::FrameNode> targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
163     auto onValueChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
164                              const std::vector<std::string>& value) {
165         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
166         ACE_SCORING_EVENT("TextPicker.onValueChange");
167         if (value.size() == 1) {
168             JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(value[0]));
169             PipelineContext::SetCallBackNode(node);
170             func->ExecuteJS(1, &newJSVal);
171         } else {
172             JSRef<JSArray> valueArray = JSRef<JSArray>::New();
173             for (uint32_t i = 0; i < value.size(); i++) {
174                 valueArray->SetValueAt(i, JSRef<JSVal>::Make(ToJSValue(value[i])));
175             }
176             JSRef<JSVal> newJSVal = JSRef<JSVal>::Cast(valueArray);
177             PipelineContext::SetCallBackNode(node);
178             func->ExecuteJS(1, &newJSVal);
179         }
180     };
181     TextPickerModel::GetInstance()->SetOnValueChangeEvent(std::move(onValueChange));
182 }
183 
ParseTextPickerSelectedObject(const JSCallbackInfo & info,const JSRef<JSVal> & changeEventVal)184 void ParseTextPickerSelectedObject(const JSCallbackInfo& info, const JSRef<JSVal>& changeEventVal)
185 {
186     CHECK_NULL_VOID(changeEventVal->IsFunction());
187 
188     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
189     WeakPtr<NG::FrameNode> targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
190     auto onSelectedChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
191                                 const std::vector<double>& index) {
192         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
193         ACE_SCORING_EVENT("TextPicker.onSelectedChange");
194         if (index.size() == 1) {
195             PipelineContext::SetCallBackNode(node);
196             JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(index[0]));
197             func->ExecuteJS(1, &newJSVal);
198         } else {
199             JSRef<JSArray> indexArray = JSRef<JSArray>::New();
200             for (uint32_t i = 0; i < index.size(); i++) {
201                 indexArray->SetValueAt(i, JSRef<JSVal>::Make(ToJSValue(index[i])));
202             }
203             PipelineContext::SetCallBackNode(node);
204             JSRef<JSVal> newJSVal = JSRef<JSVal>::Cast(indexArray);
205             func->ExecuteJS(1, &newJSVal);
206         }
207     };
208     TextPickerModel::GetInstance()->SetOnSelectedChangeEvent(std::move(onSelectedChange));
209 }
210 
Create(const JSCallbackInfo & info)211 void JSTextPicker::Create(const JSCallbackInfo& info)
212 {
213     if (info.Length() >= 1 && info[0]->IsObject()) {
214         auto paramObject = JSRef<JSObject>::Cast(info[0]);
215         ParseTextArrayParam param;
216         NG::TextCascadePickerOptionsAttr optionsAttr;
217         bool optionsMultiContentCheckErr = false;
218         bool optionsCascadeContentCheckErr = false;
219         auto isSingleRange = ProcessSingleRangeValue(paramObject, param);
220         TextPickerModel::GetInstance()->SetSingleRange(isSingleRange);
221         if (!isSingleRange) {
222             if (!JSTextPickerParser::ParseMultiTextArray(paramObject, param)) {
223                 param.options.clear();
224                 optionsMultiContentCheckErr = true;
225             }
226             if (optionsMultiContentCheckErr) {
227                 optionsCascadeContentCheckErr =
228                     !ProcessCascadeOptions(paramObject, param.options, param.selecteds, param.values, optionsAttr);
229             }
230         }
231         if (!isSingleRange && optionsMultiContentCheckErr && optionsCascadeContentCheckErr) {
232             param.result.clear();
233             param.options.clear();
234 
235             RefPtr<NG::FrameNode> targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
236             bool firstBuild = targetNode && targetNode->IsFirstBuilding();
237             if (!firstBuild) {
238                 return;
239             }
240         }
241         auto theme = GetTheme<PickerTheme>();
242         CHECK_NULL_VOID(theme);
243         if (!param.result.empty()) {
244             TextPickerModel::GetInstance()->Create(theme, param.kind);
245             TextPickerModel::GetInstance()->SetRange(param.result);
246             TextPickerModel::GetInstance()->SetSelected(param.selected);
247             TextPickerModel::GetInstance()->SetValue(param.value);
248         } else {
249             CreateMulti(theme, param.values, param.selecteds, optionsAttr, param.options);
250         }
251         TextPickerModel::GetInstance()->SetDefaultAttributes(theme);
252         JSInteractableView::SetFocusable(true);
253         JSInteractableView::SetFocusNode(true);
254         if (param.valueChangeEventVal->IsFunction()) {
255             ParseTextPickerValueObject(info, param.valueChangeEventVal);
256         }
257         if (param.selectedChangeEventVal->IsFunction()) {
258             ParseTextPickerSelectedObject(info, param.selectedChangeEventVal);
259         }
260     }
261 }
262 
ProcessSingleRangeValue(const JSRef<JSObject> & paramObjec,ParseTextArrayParam & param)263 bool JSTextPicker::ProcessSingleRangeValue(const JSRef<JSObject>& paramObjec, ParseTextArrayParam& param)
264 {
265     bool ret = true;
266     auto getRange = paramObjec->GetProperty("range");
267     if (getRange->IsNull() || getRange->IsUndefined()) {
268         if (TextPickerModel::GetInstance()->GetSingleRange()) {
269             return ret;
270         }
271         return false;
272     }
273     if (!JSTextPickerParser::ParseTextArray(paramObjec, param)) {
274         if (!JSTextPickerParser::ParseIconTextArray(paramObjec, param.result, param.kind, param.selected)) {
275             param.result.clear();
276             ret = false;
277         }
278     }
279     return ret;
280 }
281 
ProcessCascadeOptions(const JSRef<JSObject> & paramObject,std::vector<NG::TextCascadePickerOptions> & options,std::vector<uint32_t> & selectedValues,std::vector<std::string> & values,NG::TextCascadePickerOptionsAttr & attr)282 bool JSTextPicker::ProcessCascadeOptions(const JSRef<JSObject>& paramObject,
283     std::vector<NG::TextCascadePickerOptions>& options, std::vector<uint32_t>& selectedValues,
284     std::vector<std::string>& values, NG::TextCascadePickerOptionsAttr& attr)
285 {
286     auto getRange = paramObject->GetProperty("range");
287     if (getRange->IsNull() || getRange->IsUndefined()) {
288         options.clear();
289         return false;
290     }
291     if (!JSTextPickerParser::ParseCascadeTextArray(paramObject, selectedValues, values, attr)) {
292         options.clear();
293         return false;
294     } else {
295         JSTextPickerParser::GenerateCascadeOptions(getRange, options);
296         uint32_t maxCount = options.empty() ? 0 : 1;
297         for (size_t i = 0; i < options.size(); i++) {
298             size_t tmp = ProcessCascadeOptionDepth(options[i]);
299             if (tmp > maxCount) {
300                 maxCount = tmp;
301             }
302         }
303         if (selectedValues.size() < maxCount) {
304             auto differ = maxCount - selectedValues.size();
305             for (uint32_t i = 0; i < differ; i++) {
306                 selectedValues.emplace_back(0);
307             }
308         }
309         if (values.size() < maxCount) {
310             auto differ = maxCount - values.size();
311             for (uint32_t i = 0; i < differ; i++) {
312                 values.emplace_back("");
313             }
314         }
315         attr.isCascade = true;
316         TextPickerModel::GetInstance()->SetMaxCount(maxCount);
317     }
318     return true;
319 }
320 
GenerateCascadeOptionsInternal(const JSRef<JSObject> & jsObj,std::vector<NG::TextCascadePickerOptions> & options)321 bool JSTextPickerParser::GenerateCascadeOptionsInternal(
322     const JSRef<JSObject>& jsObj, std::vector<NG::TextCascadePickerOptions>& options)
323 {
324     NG::TextCascadePickerOptions option;
325     auto text = jsObj->GetProperty("text");
326     std::string textStr = "";
327     if (ParseJsString(text, textStr)) {
328         option.rangeResult.emplace_back(textStr);
329     } else {
330         return false;
331     }
332 
333     auto children = jsObj->GetProperty("children");
334     if (children->IsArray()) {
335         JSRef<JSArray> arrayChildren = JSRef<JSArray>::Cast(children);
336         if (arrayChildren->Length() > 0) {
337             if (!GenerateCascadeOptions(arrayChildren, option.children)) {
338                 return false;
339             }
340         }
341     }
342     options.emplace_back(option);
343     return true;
344 }
345 
GenerateCascadeOptions(const JSRef<JSArray> & array,std::vector<NG::TextCascadePickerOptions> & options)346 bool JSTextPickerParser::GenerateCascadeOptions(
347     const JSRef<JSArray>& array, std::vector<NG::TextCascadePickerOptions>& options)
348 {
349     for (size_t i = 0; i < array->Length(); i++) {
350         if (array->GetValueAt(i)->IsObject()) {
351             auto jsObj = JSRef<JSObject>::Cast(array->GetValueAt(i));
352             if (!GenerateCascadeOptionsInternal(jsObj, options)) {
353                 return false;
354             }
355         } else {
356             options.clear();
357             return false;
358         }
359     }
360     return true;
361 }
362 
ParseMultiTextArrayRangeInternal(const JSRef<JSVal> & value,std::vector<NG::TextCascadePickerOptions> & options)363 bool JSTextPickerParser::ParseMultiTextArrayRangeInternal(
364     const JSRef<JSVal>& value, std::vector<NG::TextCascadePickerOptions>& options)
365 {
366     if (value->IsArray()) {
367         NG::TextCascadePickerOptions option;
368         if (!ParseJsStrArray(value, option.rangeResult)) {
369             return false;
370         } else {
371             options.emplace_back(option);
372         }
373     } else {
374         return false;
375     }
376     return true;
377 }
378 
ParseMultiTextArrayRange(const JSRef<JSArray> & jsRangeValue,std::vector<NG::TextCascadePickerOptions> & options)379 bool JSTextPickerParser::ParseMultiTextArrayRange(
380     const JSRef<JSArray>& jsRangeValue, std::vector<NG::TextCascadePickerOptions>& options)
381 {
382     options.clear();
383     if (jsRangeValue->Length() > 0) {
384         for (size_t i = 0; i < jsRangeValue->Length(); i++) {
385             JSRef<JSVal> value = jsRangeValue->GetValueAt(i);
386             if (!ParseMultiTextArrayRangeInternal(value, options)) {
387                 return false;
388             }
389         }
390     } else {
391         return false;
392     }
393     return true;
394 }
395 
ParseMultiTextArraySelectInternal(const std::vector<NG::TextCascadePickerOptions> & options,const std::vector<std::string> & values,std::vector<uint32_t> & selectedValues)396 void JSTextPickerParser::ParseMultiTextArraySelectInternal(const std::vector<NG::TextCascadePickerOptions>& options,
397     const std::vector<std::string>& values, std::vector<uint32_t>& selectedValues)
398 {
399     uint32_t selectedValue = 0;
400     for (uint32_t i = 0; i < options.size(); i++) {
401         if (i > values.size() - 1 || values[i].empty()) {
402             selectedValues.emplace_back(0);
403             continue;
404         }
405 
406         auto valueIterator = std::find(options[i].rangeResult.begin(), options[i].rangeResult.end(), values[i]);
407         if (valueIterator != options[i].rangeResult.end()) {
408             selectedValue = std::distance(options[i].rangeResult.begin(), valueIterator);
409             selectedValues.emplace_back(selectedValue);
410         } else {
411             selectedValues.emplace_back(0);
412         }
413     }
414 }
415 
ParseMultiTextArraySelectArrayInternal(const std::vector<NG::TextCascadePickerOptions> & options,std::vector<uint32_t> & selectedValues)416 void JSTextPickerParser::ParseMultiTextArraySelectArrayInternal(
417     const std::vector<NG::TextCascadePickerOptions>& options, std::vector<uint32_t>& selectedValues)
418 {
419     for (uint32_t i = 0; i < options.size(); i++) {
420         if (i > selectedValues.size() - 1) {
421             selectedValues.emplace_back(0);
422         } else {
423             if (selectedValues[i] >= options[i].rangeResult.size()) {
424                 selectedValues[i] = 0;
425             }
426         }
427     }
428 }
429 
ParseMultiTextArraySelect(const JsiRef<JsiValue> & jsSelectedValue,ParseTextArrayParam & param)430 bool JSTextPickerParser::ParseMultiTextArraySelect(const JsiRef<JsiValue>& jsSelectedValue, ParseTextArrayParam& param)
431 {
432     if (jsSelectedValue->IsArray()) {
433         if (!ParseJsIntegerArray(jsSelectedValue, param.selecteds)) {
434             return false;
435         }
436         ParseMultiTextArraySelectArrayInternal(param.options, param.selecteds);
437     } else {
438         uint32_t selectedValue = 0;
439         if (ParseJsInteger(jsSelectedValue, selectedValue)) {
440             if (param.options.size() < 1 || selectedValue >= param.options[0].rangeResult.size()) {
441                 selectedValue = 0;
442             }
443             param.selecteds.emplace_back(selectedValue);
444             for (uint32_t i = 1; i < param.options.size(); i++) {
445                 param.selecteds.emplace_back(0);
446             }
447         } else {
448             ParseMultiTextArraySelectInternal(param.options, param.values, param.selecteds);
449         }
450     }
451     return true;
452 }
453 
ParseMultiTextArrayValueInternal(const std::vector<NG::TextCascadePickerOptions> & options,std::vector<std::string> & values)454 void JSTextPickerParser::ParseMultiTextArrayValueInternal(
455     const std::vector<NG::TextCascadePickerOptions>& options, std::vector<std::string>& values)
456 {
457     for (uint32_t i = 0; i < options.size(); i++) {
458         if (i > values.size() - 1) {
459             if (options[i].rangeResult.size() > 0) {
460                 values.emplace_back(options[i].rangeResult[0]);
461             } else {
462                 values.emplace_back("");
463             }
464         } else {
465             auto valueIterator = std::find(options[i].rangeResult.begin(), options[i].rangeResult.end(), values[i]);
466             if (valueIterator == options[i].rangeResult.end()) {
467                 values[i] = options[i].rangeResult.front();
468             }
469         }
470     }
471 }
472 
ParseMultiTextArrayValueSingleInternal(const std::vector<NG::TextCascadePickerOptions> & options,const std::string & value,std::vector<std::string> & values)473 void JSTextPickerParser::ParseMultiTextArrayValueSingleInternal(
474     const std::vector<NG::TextCascadePickerOptions>& options, const std::string& value,
475     std::vector<std::string>& values)
476 {
477     if (options.size() > 0) {
478         auto valueIterator = std::find(options[0].rangeResult.begin(), options[0].rangeResult.end(), value);
479         if (valueIterator != options[0].rangeResult.end()) {
480             values.emplace_back(value);
481         } else {
482             values.emplace_back(options[0].rangeResult.front());
483         }
484         for (uint32_t i = 1; i < options.size(); i++) {
485             values.emplace_back(options[i].rangeResult.front());
486         }
487     } else {
488         for (uint32_t i = 0; i < options.size(); i++) {
489             values.emplace_back(options[i].rangeResult.front());
490         }
491     }
492 }
493 
ParseMultiTextArrayValue(const JsiRef<JsiValue> & jsValue,ParseTextArrayParam & param)494 bool JSTextPickerParser::ParseMultiTextArrayValue(const JsiRef<JsiValue>& jsValue, ParseTextArrayParam& param)
495 {
496     if (jsValue->IsArray()) {
497         if (!ParseJsStrArray(jsValue, param.values)) {
498             return false;
499         }
500         ParseMultiTextArrayValueInternal(param.options, param.values);
501     } else {
502         std::string value;
503         if (ParseJsString(jsValue, value)) {
504             ParseMultiTextArrayValueSingleInternal(param.options, value, param.values);
505         } else {
506             for (uint32_t i = 0; i < param.options.size(); i++) {
507                 if (param.options[i].rangeResult.size() > 0) {
508                     param.values.emplace_back(param.options[i].rangeResult.front());
509                 }
510             }
511         }
512     }
513     return true;
514 }
515 
ParseMultiTextArray(const JSRef<JSObject> & paramObject,ParseTextArrayParam & param)516 bool JSTextPickerParser::ParseMultiTextArray(const JSRef<JSObject>& paramObject, ParseTextArrayParam& param)
517 {
518     auto getSelected = paramObject->GetProperty("selected");
519     auto getValue = paramObject->GetProperty("value");
520     auto getRange = paramObject->GetProperty("range");
521     if (getRange->IsNull() || getRange->IsUndefined()) {
522         return false;
523     }
524     JSRef<JSArray> array = JSRef<JSArray>::Cast(getRange);
525     if (!ParseMultiTextArrayRange(array, param.options)) {
526         return false;
527     }
528     if (getValue->IsObject()) {
529         JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(getValue);
530         param.valueChangeEventVal = valueObj->GetProperty("changeEvent");
531         if (param.valueChangeEventVal->IsFunction()) {
532             getValue = valueObj->GetProperty("value");
533         }
534     }
535     if (!ParseMultiTextArrayValue(getValue, param)) {
536         return false;
537     }
538     if (getSelected->IsObject()) {
539         JSRef<JSObject> selectedObj = JSRef<JSObject>::Cast(getSelected);
540         param.selectedChangeEventVal = selectedObj->GetProperty("changeEvent");
541         if (param.selectedChangeEventVal->IsFunction()) {
542             getSelected = selectedObj->GetProperty("value");
543         }
544     }
545     if (!ParseMultiTextArraySelect(getSelected, param)) {
546         return false;
547     }
548     return true;
549 }
550 
ParseInternalArray(const JSRef<JSArray> & jsRangeValue,std::vector<uint32_t> & selectedValues,std::vector<std::string> & values,uint32_t index,bool isHasSelectAttr)551 bool JSTextPickerParser::ParseInternalArray(const JSRef<JSArray>& jsRangeValue, std::vector<uint32_t>& selectedValues,
552     std::vector<std::string>& values, uint32_t index, bool isHasSelectAttr)
553 {
554     std::vector<std::string> resultStr;
555     for (size_t i = 0; i < jsRangeValue->Length(); i++) {
556         if (jsRangeValue->GetValueAt(i)->IsObject()) {
557             auto jsObj = JSRef<JSObject>::Cast(jsRangeValue->GetValueAt(i));
558             auto getText = jsObj->GetProperty("text");
559             std::string textStr = "";
560             if (ParseJsString(getText, textStr)) {
561                 resultStr.emplace_back(textStr);
562             } else {
563                 return false;
564             }
565         }
566     }
567     if (index > values.size() - 1) {
568         if (resultStr.size() > 0) {
569             values.emplace_back(resultStr.front());
570         } else {
571             values.emplace_back("");
572         }
573     } else {
574         if (resultStr.size() > 0) {
575             auto valueIterator = std::find(resultStr.begin(), resultStr.end(), values[index]);
576             if (valueIterator == resultStr.end()) {
577                 values[index] = resultStr.front();
578             }
579         } else {
580             values[index] = "";
581         }
582     }
583 
584     if (index > selectedValues.size() - 1) {
585         selectedValues.emplace_back(0);
586     } else {
587         if (selectedValues[index] >= resultStr.size()) {
588             selectedValues[index] = 0;
589         }
590     }
591 
592     if (!isHasSelectAttr && selectedValues[index] == 0 && !values[index].empty()) {
593         auto valueIterator = std::find(resultStr.begin(), resultStr.end(), values[index]);
594         if (valueIterator != resultStr.end()) {
595             selectedValues[index] = std::distance(resultStr.begin(), valueIterator);
596         }
597     }
598     auto jsObj = JSRef<JSObject>::Cast(jsRangeValue->GetValueAt(selectedValues[index]));
599     auto getChildren = jsObj->GetProperty("children");
600     if (getChildren->IsArray()) {
601         ParseInternalArray(getChildren, selectedValues, values, index + 1, isHasSelectAttr);
602     }
603     return true;
604 }
605 
ParseCascadeTextArray(const JSRef<JSObject> & paramObject,std::vector<uint32_t> & selectedValues,std::vector<std::string> & values,NG::TextCascadePickerOptionsAttr & attr)606 bool JSTextPickerParser::ParseCascadeTextArray(const JSRef<JSObject>& paramObject,
607     std::vector<uint32_t>& selectedValues, std::vector<std::string>& values, NG::TextCascadePickerOptionsAttr& attr)
608 {
609     JSRef<JSArray> getRange = paramObject->GetProperty("range");
610     auto getSelected = paramObject->GetProperty("selected");
611     auto getValue = paramObject->GetProperty("value");
612     if (getValue->IsArray()) {
613         if (!ParseJsStrArray(getValue, values)) {
614             return false;
615         }
616     } else {
617         std::string value = "";
618         if (!ParseJsString(getValue, value)) {
619             value = "";
620         }
621         values.emplace_back(value);
622     }
623     if (getSelected->IsArray()) {
624         if (!ParseJsIntegerArray(getSelected, selectedValues)) {
625             attr.isHasSelectAttr = false;
626             return false;
627         } else {
628             attr.isHasSelectAttr = true;
629         }
630     } else {
631         uint32_t selectValue = 0;
632         if (!ParseJsInteger(getSelected, selectValue)) {
633             selectValue = 0;
634             attr.isHasSelectAttr = false;
635         } else {
636             attr.isHasSelectAttr = true;
637         }
638         selectedValues.emplace_back(selectValue);
639     }
640     return ParseInternalArray(getRange, selectedValues, values, 0, attr.isHasSelectAttr);
641 }
642 
ParseTextArray(const JSRef<JSObject> & paramObject,ParseTextArrayParam & param)643 bool JSTextPickerParser::ParseTextArray(const JSRef<JSObject>& paramObject, ParseTextArrayParam& param)
644 {
645     auto getSelected = paramObject->GetProperty("selected");
646     auto getValue = paramObject->GetProperty("value");
647     JSRef<JSArray> getRange = paramObject->GetProperty("range");
648     std::vector<std::string> getRangeVector;
649     if (getRange->Length() > 0) {
650         if (!ParseJsStrArray(getRange, getRangeVector)) {
651             return false;
652         }
653 
654         param.result.clear();
655         for (const auto& text : getRangeVector) {
656             NG::RangeContent content;
657             content.icon_ = "";
658             content.text_ = text;
659             param.result.emplace_back(content);
660         }
661         param.kind = NG::TEXT;
662         if (getValue->IsObject()) {
663             JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(getValue);
664             param.valueChangeEventVal = valueObj->GetProperty("changeEvent");
665             if (param.valueChangeEventVal->IsFunction()) {
666                 getValue = valueObj->GetProperty("value");
667             }
668         }
669         if (!ParseJsString(getValue, param.value)) {
670             param.value = getRangeVector.front();
671         }
672         if (getSelected->IsObject()) {
673             JSRef<JSObject> selectedObj = JSRef<JSObject>::Cast(getSelected);
674             param.selectedChangeEventVal = selectedObj->GetProperty("changeEvent");
675             if (param.selectedChangeEventVal->IsFunction()) {
676                 getSelected = selectedObj->GetProperty("value");
677             }
678         }
679         if (!ParseJsInteger(getSelected, param.selected) && !param.value.empty()) {
680             auto valueIterator = std::find(getRangeVector.begin(), getRangeVector.end(), param.value);
681             if (valueIterator != getRangeVector.end()) {
682                 param.selected = std::distance(getRangeVector.begin(), valueIterator);
683             }
684         }
685         if (param.selected >= getRangeVector.size()) {
686             param.selected = 0;
687         }
688     }
689 
690     return true;
691 }
692 
ParseIconTextArray(const JSRef<JSObject> & paramObject,std::vector<NG::RangeContent> & result,uint32_t & kind,uint32_t & selectedValue)693 bool JSTextPickerParser::ParseIconTextArray(
694     const JSRef<JSObject>& paramObject, std::vector<NG::RangeContent>& result, uint32_t& kind, uint32_t& selectedValue)
695 {
696     auto getSelected = paramObject->GetProperty("selected");
697     auto getRange = paramObject->GetProperty("range");
698     if (!getRange->IsArray()) {
699         return false;
700     }
701     JSRef<JSArray> array = JSRef<JSArray>::Cast(getRange);
702     result.clear();
703     kind = 0;
704     for (size_t i = 0; i < array->Length(); i++) {
705         if (!array->GetValueAt(i)->IsObject()) {
706             continue;
707         }
708         auto jsObj = JSRef<JSObject>::Cast(array->GetValueAt(i));
709         auto rangeIcon = jsObj->GetProperty("icon");
710         auto rangeText = jsObj->GetProperty("text");
711         NG::RangeContent content;
712         std::string icon;
713         std::string text;
714         if (ParseJsMedia(rangeIcon, icon)) {
715             content.icon_ = icon;
716             kind |= NG::ICON;
717         }
718 
719         if (ParseJsString(rangeText, text)) {
720             content.text_ = text;
721             kind |= NG::TEXT;
722         }
723         result.emplace_back(content);
724     }
725 
726     if (kind != NG::ICON && kind != (NG::ICON | NG::TEXT)) {
727         return false;
728     }
729 
730     if (!ParseJsInteger(getSelected, selectedValue)) {
731         selectedValue = 0;
732     }
733     return true;
734 }
735 
ParseTextStyle(const JSRef<JSObject> & paramObj,NG::PickerTextStyle & textStyle)736 void JSTextPickerParser::ParseTextStyle(const JSRef<JSObject>& paramObj, NG::PickerTextStyle& textStyle)
737 {
738     auto fontColor = paramObj->GetProperty("color");
739     auto fontOptions = paramObj->GetProperty("font");
740 
741     Color textColor;
742     if (ParseJsColor(fontColor, textColor)) {
743         textStyle.textColor = textColor;
744     }
745 
746     if (!fontOptions->IsObject()) {
747         return;
748     }
749     JSRef<JSObject> fontObj = JSRef<JSObject>::Cast(fontOptions);
750     auto fontSize = fontObj->GetProperty("size");
751     auto fontWeight = fontObj->GetProperty("weight");
752     auto fontFamily = fontObj->GetProperty("family");
753     auto fontStyle = fontObj->GetProperty("style");
754     if (fontSize->IsNull() || fontSize->IsUndefined()) {
755         textStyle.fontSize = Dimension(-1);
756     } else {
757         CalcDimension size;
758         if (!ParseJsDimensionFp(fontSize, size) || size.Unit() == DimensionUnit::PERCENT) {
759             textStyle.fontSize = Dimension(-1);
760         } else {
761             textStyle.fontSize = size;
762         }
763     }
764 
765     if (!fontWeight->IsNull() && !fontWeight->IsUndefined()) {
766         std::string weight;
767         if (fontWeight->IsNumber()) {
768             weight = std::to_string(fontWeight->ToNumber<int32_t>());
769         } else {
770             ParseJsString(fontWeight, weight);
771         }
772         textStyle.fontWeight = ConvertStrToFontWeight(weight);
773     }
774 
775     if (!fontFamily->IsNull() && !fontFamily->IsUndefined()) {
776         std::vector<std::string> families;
777         if (ParseJsFontFamilies(fontFamily, families)) {
778             textStyle.fontFamily = families;
779         }
780     }
781 
782     if (fontStyle->IsNumber()) {
783         auto style = fontStyle->ToNumber<int32_t>();
784         if (style < 0 || style > 1) {
785             return;
786         }
787         textStyle.fontStyle = static_cast<FontStyle>(style);
788     }
789 }
790 
SetDefaultPickerItemHeight(const JSCallbackInfo & info)791 void JSTextPicker::SetDefaultPickerItemHeight(const JSCallbackInfo& info)
792 {
793     if (info.Length() < 1) {
794         return;
795     }
796     CalcDimension height;
797     if (info[0]->IsNumber() || info[0]->IsString()) {
798         if (!ParseJsDimensionFp(info[0], height)) {
799             return;
800         }
801     }
802     TextPickerModel::GetInstance()->SetDefaultPickerItemHeight(height);
803 }
SetCanLoop(const JSCallbackInfo & info)804 void JSTextPicker::SetCanLoop(const JSCallbackInfo& info)
805 {
806     bool value = true;
807     if (info[0]->IsBoolean()) {
808         value = info[0]->ToBoolean();
809     }
810     TextPickerModel::GetInstance()->SetCanLoop(value);
811 }
812 
SetDisappearTextStyle(const JSCallbackInfo & info)813 void JSTextPicker::SetDisappearTextStyle(const JSCallbackInfo& info)
814 {
815     auto theme = GetTheme<PickerTheme>();
816     CHECK_NULL_VOID(theme);
817     NG::PickerTextStyle textStyle;
818     if (info[0]->IsObject()) {
819         JSTextPickerParser::ParseTextStyle(info[0], textStyle);
820     }
821     TextPickerModel::GetInstance()->SetDisappearTextStyle(theme, textStyle);
822 }
823 
SetTextStyle(const JSCallbackInfo & info)824 void JSTextPicker::SetTextStyle(const JSCallbackInfo& info)
825 {
826     auto theme = GetTheme<PickerTheme>();
827     CHECK_NULL_VOID(theme);
828     NG::PickerTextStyle textStyle;
829     if (info[0]->IsObject()) {
830         JSTextPickerParser::ParseTextStyle(info[0], textStyle);
831     }
832     TextPickerModel::GetInstance()->SetNormalTextStyle(theme, textStyle);
833 }
834 
SetSelectedTextStyle(const JSCallbackInfo & info)835 void JSTextPicker::SetSelectedTextStyle(const JSCallbackInfo& info)
836 {
837     auto theme = GetTheme<PickerTheme>();
838     CHECK_NULL_VOID(theme);
839     NG::PickerTextStyle textStyle;
840     if (info[0]->IsObject()) {
841         JSTextPickerParser::ParseTextStyle(info[0], textStyle);
842     }
843     TextPickerModel::GetInstance()->SetSelectedTextStyle(theme, textStyle);
844 }
845 
ProcessCascadeSelected(const std::vector<NG::TextCascadePickerOptions> & options,uint32_t index,std::vector<uint32_t> & selectedValues)846 void JSTextPicker::ProcessCascadeSelected(
847     const std::vector<NG::TextCascadePickerOptions>& options, uint32_t index, std::vector<uint32_t>& selectedValues)
848 {
849     std::vector<std::string> rangeResultValue;
850     for (size_t i = 0; i < options.size(); i++) {
851         rangeResultValue.emplace_back(options[i].rangeResult[0]);
852     }
853 
854     if (index > selectedValues.size() - 1) {
855         selectedValues.emplace_back(0);
856     }
857     if (selectedValues[index] >= rangeResultValue.size()) {
858         selectedValues[index] = 0;
859     }
860     if (selectedValues[index] <= options.size() - 1 && options[selectedValues[index]].children.size() > 0) {
861         ProcessCascadeSelected(options[selectedValues[index]].children, index + 1, selectedValues);
862     }
863 }
864 
SetSelectedInternal(uint32_t count,std::vector<NG::TextCascadePickerOptions> & options,std::vector<uint32_t> & selectedValues)865 void JSTextPicker::SetSelectedInternal(
866     uint32_t count, std::vector<NG::TextCascadePickerOptions>& options, std::vector<uint32_t>& selectedValues)
867 {
868     for (uint32_t i = 0; i < count; i++) {
869         if (i > selectedValues.size() - 1) {
870             selectedValues.emplace_back(0);
871         } else {
872             if (selectedValues[i] >= options[i].rangeResult.size()) {
873                 selectedValues[i] = 0;
874             }
875         }
876     }
877 }
878 
SetSelectedIndexMultiInternal(uint32_t count,std::vector<NG::TextCascadePickerOptions> & options,std::vector<uint32_t> & selectedValues)879 void JSTextPicker::SetSelectedIndexMultiInternal(
880     uint32_t count, std::vector<NG::TextCascadePickerOptions>& options, std::vector<uint32_t>& selectedValues)
881 {
882     if (!TextPickerModel::GetInstance()->IsCascade()) {
883         SetSelectedInternal(count, options, selectedValues);
884     } else {
885         TextPickerModel::GetInstance()->SetHasSelectAttr(true);
886         ProcessCascadeSelected(options, 0, selectedValues);
887         uint32_t maxCount = TextPickerModel::GetInstance()->GetMaxCount();
888         if (selectedValues.size() < maxCount) {
889             auto differ = maxCount - selectedValues.size();
890             for (uint32_t i = 0; i < differ; i++) {
891                 selectedValues.emplace_back(0);
892             }
893         }
894     }
895 }
896 
SetSelectedIndexSingleInternal(const std::vector<NG::TextCascadePickerOptions> & options,uint32_t count,uint32_t & selectedValue,std::vector<uint32_t> & selectedValues)897 void JSTextPicker::SetSelectedIndexSingleInternal(const std::vector<NG::TextCascadePickerOptions>& options,
898     uint32_t count, uint32_t& selectedValue, std::vector<uint32_t>& selectedValues)
899 {
900     if (options.size() > 0) {
901         if (selectedValue >= options[0].rangeResult.size()) {
902             selectedValue = 0;
903         }
904         selectedValues.emplace_back(selectedValue);
905         for (uint32_t i = 1; i < count; i++) {
906             selectedValues.emplace_back(0);
907         }
908     } else {
909         for (uint32_t i = 0; i < count; i++) {
910             selectedValues.emplace_back(0);
911         }
912     }
913 }
914 
SetSelectedIndexMulti(const JsiRef<JsiValue> & jsSelectedValue)915 void JSTextPicker::SetSelectedIndexMulti(const JsiRef<JsiValue>& jsSelectedValue)
916 {
917     std::vector<uint32_t> selectedValues;
918     std::vector<NG::TextCascadePickerOptions> options;
919     TextPickerModel::GetInstance()->GetMultiOptions(options);
920     auto count =
921         TextPickerModel::GetInstance()->IsCascade() ? TextPickerModel::GetInstance()->GetMaxCount() : options.size();
922     if (jsSelectedValue->IsArray()) {
923         if (!ParseJsIntegerArray(jsSelectedValue, selectedValues)) {
924             selectedValues.clear();
925             for (uint32_t i = 0; i < count; i++) {
926                 selectedValues.emplace_back(0);
927             }
928             TextPickerModel::GetInstance()->SetSelecteds(selectedValues);
929             TextPickerModel::GetInstance()->SetHasSelectAttr(false);
930             return;
931         }
932         SetSelectedIndexMultiInternal(count, options, selectedValues);
933     } else {
934         uint32_t selectedValue = 0;
935         if (ParseJsInteger(jsSelectedValue, selectedValue)) {
936             TextPickerModel::GetInstance()->SetHasSelectAttr(true);
937             SetSelectedIndexSingleInternal(options, count, selectedValue, selectedValues);
938         } else {
939             selectedValues.clear();
940             TextPickerModel::GetInstance()->SetHasSelectAttr(false);
941             for (uint32_t i = 0; i < count; i++) {
942                 selectedValues.emplace_back(0);
943             }
944         }
945     }
946     TextPickerModel::GetInstance()->SetSelecteds(selectedValues);
947 }
948 
SetSelectedIndexSingle(const JsiRef<JsiValue> & jsSelectedValue)949 void JSTextPicker::SetSelectedIndexSingle(const JsiRef<JsiValue>& jsSelectedValue)
950 {
951     // Single
952     std::vector<NG::RangeContent> rangeResult;
953     TextPickerModel::GetInstance()->GetSingleRange(rangeResult);
954     if (jsSelectedValue->IsArray()) {
955         std::vector<uint32_t> selectedValues;
956         if (!ParseJsIntegerArray(jsSelectedValue, selectedValues)) {
957             uint32_t selectedValue = 0;
958             TextPickerModel::GetInstance()->SetSelected(selectedValue);
959             return;
960         }
961         if (selectedValues.size() > 0) {
962             if (selectedValues[0] >= rangeResult.size()) {
963                 selectedValues[0] = 0;
964             }
965         } else {
966             selectedValues.emplace_back(0);
967         }
968 
969         TextPickerModel::GetInstance()->SetSelected(selectedValues[0]);
970     } else {
971         uint32_t selectedValue = 0;
972         if (ParseJsInteger(jsSelectedValue, selectedValue)) {
973             if (selectedValue >= rangeResult.size()) {
974                 selectedValue = 0;
975             }
976         }
977         TextPickerModel::GetInstance()->SetSelected(selectedValue);
978     }
979 }
980 
SetSelectedIndex(const JSCallbackInfo & info)981 void JSTextPicker::SetSelectedIndex(const JSCallbackInfo& info)
982 {
983     if (info.Length() >= 1) {
984         auto jsSelectedValue = info[0];
985         if (jsSelectedValue->IsNull() || jsSelectedValue->IsUndefined()) {
986             return;
987         }
988         if (TextPickerModel::GetInstance()->IsSingle()) {
989             SetSelectedIndexSingle(jsSelectedValue);
990         } else {
991             SetSelectedIndexMulti(jsSelectedValue);
992         }
993     }
994 }
995 
OnAccept(const JSCallbackInfo & info)996 void JSTextPicker::OnAccept(const JSCallbackInfo& info) {}
997 
OnCancel(const JSCallbackInfo & info)998 void JSTextPicker::OnCancel(const JSCallbackInfo& info) {}
999 
OnChange(const JSCallbackInfo & info)1000 void JSTextPicker::OnChange(const JSCallbackInfo& info)
1001 {
1002     if (!info[0]->IsFunction()) {
1003         return;
1004     }
1005     auto jsFunc = JSRef<JSFunc>::Cast(info[0]);
1006     auto onChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](
1007                         const std::vector<std::string>& value, const std::vector<double>& index) {
1008         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1009         ACE_SCORING_EVENT("TextPicker.onChange");
1010         if (value.size() == 1 && index.size() == 1) {
1011             auto params = ConvertToJSValues(value[0], index[0]);
1012             func->Call(JSRef<JSObject>(), static_cast<int>(params.size()), params.data());
1013         } else {
1014             std::vector<JSRef<JSVal>> result;
1015             JSRef<JSArray> valueArray = JSRef<JSArray>::New();
1016             for (uint32_t i = 0; i < value.size(); i++) {
1017                 valueArray->SetValueAt(i, JSRef<JSVal>::Make(ToJSValue(value[i])));
1018             }
1019             JSRef<JSVal> valueJs = JSRef<JSVal>::Cast(valueArray);
1020             result.emplace_back(valueJs);
1021             JSRef<JSArray> selectedArray = JSRef<JSArray>::New();
1022             for (uint32_t i = 0; i < index.size(); i++) {
1023                 selectedArray->SetValueAt(i, JSRef<JSVal>::Make(ToJSValue(index[i])));
1024             }
1025             JSRef<JSVal> selectedJs = JSRef<JSVal>::Cast(selectedArray);
1026             result.emplace_back(selectedJs);
1027             func->Call(JSRef<JSObject>(), static_cast<int>(result.size()), result.data());
1028         }
1029     };
1030     TextPickerModel::GetInstance()->SetOnCascadeChange(std::move(onChange));
1031     info.ReturnSelf();
1032 }
1033 
JSBind(BindingTarget globalObj)1034 void JSTextPickerDialog::JSBind(BindingTarget globalObj)
1035 {
1036     JSClass<JSTextPickerDialog>::Declare("TextPickerDialog");
1037     JSClass<JSTextPickerDialog>::StaticMethod("show", &JSTextPickerDialog::Show);
1038 
1039     JSClass<JSTextPickerDialog>::Bind<>(globalObj);
1040 }
1041 
Show(const JSCallbackInfo & info)1042 void JSTextPickerDialog::Show(const JSCallbackInfo& info)
1043 {
1044     auto scopedDelegate = EngineHelper::GetCurrentDelegateSafely();
1045     CHECK_NULL_VOID(scopedDelegate);
1046     if (!info[0]->IsObject()) {
1047         return;
1048     }
1049 
1050     auto paramObject = JSRef<JSObject>::Cast(info[0]);
1051     std::function<void()> cancelEvent;
1052     std::function<void(const std::string&)> acceptEvent;
1053     std::function<void(const std::string&)> changeEvent;
1054     auto onCancel = paramObject->GetProperty("onCancel");
1055     WeakPtr<NG::FrameNode> targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
1056     if (!onCancel->IsUndefined() && onCancel->IsFunction()) {
1057         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onCancel));
1058         cancelEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1059             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1060             ACE_SCORING_EVENT("TextPickerDialog.onCancel");
1061             PipelineContext::SetCallBackNode(node);
1062             func->Execute();
1063         };
1064     }
1065     auto onAccept = paramObject->GetProperty("onAccept");
1066     if (!onAccept->IsUndefined() && onAccept->IsFunction()) {
1067         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAccept));
1068         acceptEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1069                           const std::string& info) {
1070             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1071             std::vector<std::string> keys = { "value", "index" };
1072             ACE_SCORING_EVENT("TextPickerDialog.onAccept");
1073             PipelineContext::SetCallBackNode(node);
1074             func->Execute(keys, info);
1075         };
1076     }
1077     auto onChange = paramObject->GetProperty("onChange");
1078     if (!onChange->IsUndefined() && onChange->IsFunction()) {
1079         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onChange));
1080         changeEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1081                           const std::string& info) {
1082             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1083             std::vector<std::string> keys = { "value", "index" };
1084             ACE_SCORING_EVENT("TextPickerDialog.onChange");
1085             PipelineContext::SetCallBackNode(node);
1086             func->Execute(keys, info);
1087         };
1088     }
1089     NG::TextPickerSettingData settingData;
1090     TextPickerDialog textPickerDialog;
1091 
1092     auto pickerText = TextPickerDialogModel::GetInstance()->CreateObject();
1093     if (pickerText == nullptr) {
1094         // parse Multi column text
1095         if (!ParseShowData(paramObject, settingData)) {
1096             return;
1097         }
1098     } else {
1099         auto getSelected = paramObject->GetProperty("selected");
1100         auto defaultHeight = paramObject->GetProperty("defaultPickerItemHeight");
1101         auto canLoop = paramObject->GetProperty("canLoop");
1102         JSRef<JSArray> getRange = paramObject->GetProperty("range");
1103         std::vector<std::string> getRangeVector;
1104         if (!JSViewAbstract::ParseJsStrArray(getRange, getRangeVector)) {
1105             return;
1106         }
1107         std::string value = "";
1108         uint32_t selectedValue = 0;
1109         auto getValue = paramObject->GetProperty("value");
1110         if (!JSViewAbstract::ParseJsInteger(getSelected, selectedValue) &&
1111             JSViewAbstract::ParseJsString(getValue, value)) {
1112             auto valueIterator = std::find(getRangeVector.begin(), getRangeVector.end(), value);
1113             if (valueIterator != getRangeVector.end()) {
1114                 selectedValue = std::distance(getRangeVector.begin(), valueIterator);
1115             }
1116         }
1117         if (selectedValue >= getRangeVector.size()) {
1118             selectedValue = 0;
1119         }
1120         CalcDimension height;
1121         if (defaultHeight->IsNumber() || defaultHeight->IsString()) {
1122             if (!JSViewAbstract::ParseJsDimensionFp(defaultHeight, height)) {
1123                 return;
1124             }
1125         }
1126         if (!defaultHeight->IsEmpty()) {
1127             textPickerDialog.isDefaultHeight = true;
1128         }
1129         textPickerDialog.height = height;
1130         textPickerDialog.selectedValue = selectedValue;
1131         textPickerDialog.getRangeVector = getRangeVector;
1132     }
1133 
1134     // Parse alignment
1135     auto alignmentValue = paramObject->GetProperty("alignment");
1136     if (alignmentValue->IsNumber()) {
1137         auto alignment = alignmentValue->ToNumber<int32_t>();
1138         if (alignment >= 0 && alignment <= static_cast<int32_t>(DIALOG_ALIGNMENT.size())) {
1139             textPickerDialog.alignment = DIALOG_ALIGNMENT[alignment];
1140         }
1141         if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1142             if (alignment == static_cast<int32_t>(DialogAlignment::TOP) ||
1143                 alignment == static_cast<int32_t>(DialogAlignment::TOP_START) ||
1144                 alignment == static_cast<int32_t>(DialogAlignment::TOP_END)) {
1145                 textPickerDialog.offset = TEXT_PICKER_OFFSET_DEFAULT_TOP;
1146             }
1147         }
1148     }
1149 
1150     // Parse offset
1151     auto offsetValue = paramObject->GetProperty("offset");
1152     if (offsetValue->IsObject()) {
1153         auto offsetObj = JSRef<JSObject>::Cast(offsetValue);
1154         CalcDimension dx;
1155         auto dxValue = offsetObj->GetProperty("dx");
1156         JSAlertDialog::ParseJsDimensionVp(dxValue, dx);
1157         CalcDimension dy;
1158         auto dyValue = offsetObj->GetProperty("dy");
1159         JSAlertDialog::ParseJsDimensionVp(dyValue, dy);
1160         textPickerDialog.offset = DimensionOffset(dx, dy);
1161     }
1162 
1163     // Parse maskRect.
1164     auto maskRectValue = paramObject->GetProperty("maskRect");
1165     DimensionRect maskRect;
1166     if (JSViewAbstract::ParseJsDimensionRect(maskRectValue, maskRect)) {
1167         textPickerDialog.maskRect = maskRect;
1168     }
1169 
1170     auto backgroundColorValue = paramObject->GetProperty("backgroundColor");
1171     Color backgroundColor;
1172     if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor)) {
1173         textPickerDialog.backgroundColor = backgroundColor;
1174     }
1175 
1176     auto backgroundBlurStyle = paramObject->GetProperty("backgroundBlurStyle");
1177     BlurStyleOption styleOption;
1178     if (backgroundBlurStyle->IsNumber()) {
1179         auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>();
1180         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
1181             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
1182             textPickerDialog.backgroundBlurStyle = blurStyle;
1183         }
1184     }
1185 
1186     TextPickerDialogModel::GetInstance()->SetTextPickerDialogShow(pickerText, settingData, std::move(cancelEvent),
1187         std::move(acceptEvent), std::move(changeEvent), textPickerDialog);
1188 }
1189 
TextPickerDialogShow(const JSRef<JSObject> & paramObj,const std::map<std::string,NG::DialogTextEvent> & dialogEvent,const std::map<std::string,NG::DialogGestureEvent> & dialogCancelEvent)1190 void JSTextPickerDialog::TextPickerDialogShow(const JSRef<JSObject>& paramObj,
1191     const std::map<std::string, NG::DialogTextEvent>& dialogEvent,
1192     const std::map<std::string, NG::DialogGestureEvent>& dialogCancelEvent)
1193 {
1194     auto container = Container::CurrentSafely();
1195     if (!container) {
1196         return;
1197     }
1198     auto pipelineContext = AccessibilityManager::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
1199     if (!pipelineContext) {
1200         return;
1201     }
1202 
1203     auto executor = pipelineContext->GetTaskExecutor();
1204     if (!executor) {
1205         return;
1206     }
1207 
1208     auto theme = JSTextPicker::GetTheme<DialogTheme>();
1209     CHECK_NULL_VOID(theme);
1210 
1211     NG::TextPickerSettingData settingData;
1212     if (!ParseShowData(paramObj, settingData)) {
1213         return;
1214     }
1215 
1216     DialogProperties properties;
1217     ButtonInfo buttonInfo;
1218     if (SystemProperties::GetDeviceType() == DeviceType::PHONE) {
1219         properties.alignment = DialogAlignment::BOTTOM;
1220         if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1221             properties.offset = DimensionOffset(Offset(0, -theme->GetMarginBottom().ConvertToPx()));
1222         }
1223     } else {
1224         properties.alignment = DialogAlignment::CENTER;
1225     }
1226     properties.customStyle = false;
1227     if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1228         properties.offset = DimensionOffset(Offset(0, -theme->GetMarginBottom().ConvertToPx()));
1229     }
1230 
1231     auto context = AccessibilityManager::DynamicCast<NG::PipelineContext>(pipelineContext);
1232     auto overlayManager = context ? context->GetOverlayManager() : nullptr;
1233     executor->PostTask(
1234         [properties, settingData, dialogEvent, dialogCancelEvent, weak = WeakPtr<NG::OverlayManager>(overlayManager)] {
1235             auto overlayManager = weak.Upgrade();
1236             CHECK_NULL_VOID(overlayManager);
1237             overlayManager->ShowTextDialog(properties, settingData, dialogEvent, dialogCancelEvent);
1238         },
1239         TaskExecutor::TaskType::UI);
1240 }
1241 
ParseShowDataOptions(const JSRef<JSObject> & paramObject,ParseTextArrayParam & param,NG::TextCascadePickerOptionsAttr & attr)1242 bool JSTextPickerDialog::ParseShowDataOptions(
1243     const JSRef<JSObject>& paramObject, ParseTextArrayParam& param, NG::TextCascadePickerOptionsAttr& attr)
1244 {
1245     bool optionsMultiContentCheckErr = false;
1246     bool optionsCascadeContentCheckErr = false;
1247     if (!JSTextPickerParser::ParseMultiTextArray(paramObject, param)) {
1248         param.options.clear();
1249         optionsMultiContentCheckErr = true;
1250     }
1251 
1252     if (optionsMultiContentCheckErr) {
1253         if (!JSTextPickerParser::ParseCascadeTextArray(paramObject, param.selecteds, param.values, attr)) {
1254             param.options.clear();
1255             optionsCascadeContentCheckErr = true;
1256         } else {
1257             JSRef<JSArray> getRange = paramObject->GetProperty("range");
1258             JSTextPickerParser::GenerateCascadeOptions(getRange, param.options);
1259             attr.isCascade = true;
1260         }
1261     }
1262     if (optionsMultiContentCheckErr && optionsCascadeContentCheckErr) {
1263         param.options.clear();
1264         return false;
1265     }
1266     return true;
1267 }
1268 
ParseShowDataAttribute(const JSRef<JSObject> & paramObject,NG::TextPickerSettingData & settingData)1269 bool JSTextPickerDialog::ParseShowDataAttribute(
1270     const JSRef<JSObject>& paramObject, NG::TextPickerSettingData& settingData)
1271 {
1272     CalcDimension height;
1273     auto defaultHeight = paramObject->GetProperty("defaultPickerItemHeight");
1274     if (defaultHeight->IsNumber() || defaultHeight->IsString()) {
1275         if (!JSViewAbstract::ParseJsDimensionFp(defaultHeight, height)) {
1276             return false;
1277         }
1278     }
1279     settingData.height = height;
1280     ParseTextProperties(paramObject, settingData.properties);
1281     return true;
1282 }
ParseCanLoop(const JSRef<JSObject> & paramObject,bool & canLoop)1283 bool JSTextPickerDialog::ParseCanLoop(const JSRef<JSObject>& paramObject, bool& canLoop)
1284 {
1285     bool result = false;
1286     auto prop = paramObject->GetProperty("canLoop");
1287     bool value = false;
1288     if (prop->IsBoolean() && JSViewAbstract::ParseJsBool(prop, value)) {
1289         canLoop = value;
1290         result = true;
1291     } else {
1292         canLoop = true;
1293         result = false;
1294     }
1295     return result;
1296 }
1297 
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)1298 void JSTextPickerDialog::ParseShowDataMultiContent(const std::vector<NG::TextCascadePickerOptions>& options,
1299     const std::vector<uint32_t>& selectedValues, const std::vector<std::string>& values,
1300     NG::TextCascadePickerOptionsAttr& attr, NG::TextPickerSettingData& settingData)
1301 {
1302     settingData.columnKind = NG::TEXT;
1303     for (auto& item : selectedValues) {
1304         settingData.selectedValues.emplace_back(item);
1305     }
1306     for (auto& item : values) {
1307         settingData.values.emplace_back(item);
1308     }
1309     for (auto& item : options) {
1310         settingData.options.emplace_back(item);
1311     }
1312     settingData.attr.isCascade = attr.isCascade;
1313     settingData.attr.isHasSelectAttr = attr.isHasSelectAttr;
1314 }
1315 
ParseShowData(const JSRef<JSObject> & paramObject,NG::TextPickerSettingData & settingData)1316 bool JSTextPickerDialog::ParseShowData(const JSRef<JSObject>& paramObject, NG::TextPickerSettingData& settingData)
1317 {
1318     ParseTextArrayParam param;
1319     bool rangeContentCheckErr = false;
1320     bool optionsCascadeContentCheckErr = false;
1321     NG::TextCascadePickerOptionsAttr attr;
1322     auto getRange = paramObject->GetProperty("range");
1323     if (getRange->IsNull() || getRange->IsUndefined()) {
1324         return false;
1325     }
1326     if (!JSTextPickerParser::ParseTextArray(paramObject, param)) {
1327         if (!JSTextPickerParser::ParseIconTextArray(paramObject, param.result, param.kind, param.selected)) {
1328             rangeContentCheckErr = true;
1329             param.result.clear();
1330         }
1331     }
1332     if (rangeContentCheckErr) {
1333         optionsCascadeContentCheckErr = !ParseShowDataOptions(paramObject, param, attr);
1334     }
1335     if (rangeContentCheckErr && optionsCascadeContentCheckErr) {
1336         return false;
1337     }
1338     if (memset_s(&settingData, sizeof(NG::TextPickerSettingData), 0, sizeof(NG::TextPickerSettingData)) != EOK) {
1339         return false;
1340     }
1341     if (!ParseShowDataAttribute(paramObject, settingData)) {
1342         return false;
1343     }
1344     ParseCanLoop(paramObject, settingData.canLoop);
1345     if (param.result.size() > 0) {
1346         settingData.selected = param.selected;
1347         settingData.columnKind = param.kind;
1348         for (const auto& item : param.result) {
1349             settingData.rangeVector.emplace_back(item);
1350         }
1351     } else {
1352         ParseShowDataMultiContent(param.options, param.selecteds, param.values, attr, settingData);
1353     }
1354     return true;
1355 }
1356 
ParseTextProperties(const JSRef<JSObject> & paramObj,NG::PickerTextProperties & result)1357 void JSTextPickerDialog::ParseTextProperties(const JSRef<JSObject>& paramObj, NG::PickerTextProperties& result)
1358 {
1359     auto disappearProperty = paramObj->GetProperty("disappearTextStyle");
1360     auto normalProperty = paramObj->GetProperty("textStyle");
1361     auto selectedProperty = paramObj->GetProperty("selectedTextStyle");
1362 
1363     if (!disappearProperty->IsNull() && disappearProperty->IsObject()) {
1364         JSRef<JSObject> disappearObj = JSRef<JSObject>::Cast(disappearProperty);
1365         JSTextPickerParser::ParseTextStyle(disappearObj, result.disappearTextStyle_);
1366     }
1367 
1368     if (!normalProperty->IsNull() && normalProperty->IsObject()) {
1369         JSRef<JSObject> noramlObj = JSRef<JSObject>::Cast(normalProperty);
1370         JSTextPickerParser::ParseTextStyle(noramlObj, result.normalTextStyle_);
1371     }
1372 
1373     if (!selectedProperty->IsNull() && selectedProperty->IsObject()) {
1374         JSRef<JSObject> selectedObj = JSRef<JSObject>::Cast(selectedProperty);
1375         JSTextPickerParser::ParseTextStyle(selectedObj, result.selectedTextStyle_);
1376     }
1377 }
1378 
DialogEvent(const JSCallbackInfo & info)1379 std::map<std::string, NG::DialogTextEvent> JSTextPickerDialog::DialogEvent(const JSCallbackInfo& info)
1380 {
1381     std::map<std::string, NG::DialogTextEvent> dialogEvent;
1382     if (!info[0]->IsObject()) {
1383         return dialogEvent;
1384     }
1385     auto paramObject = JSRef<JSObject>::Cast(info[0]);
1386     auto onAccept = paramObject->GetProperty("onAccept");
1387         WeakPtr<NG::FrameNode> targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
1388     if (!onAccept->IsUndefined() && onAccept->IsFunction()) {
1389         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAccept));
1390         auto acceptId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1391                             const std::string& info) {
1392             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1393             std::vector<std::string> keys = { "value", "index" };
1394             ACE_SCORING_EVENT("TextPickerDialog.onAccept");
1395             PipelineContext::SetCallBackNode(node);
1396             func->Execute(keys, info);
1397         };
1398         dialogEvent["acceptId"] = acceptId;
1399     }
1400     auto onChange = paramObject->GetProperty("onChange");
1401     if (!onChange->IsUndefined() && onChange->IsFunction()) {
1402         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onChange));
1403         auto changeId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1404                             const std::string& info) {
1405             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1406             std::vector<std::string> keys = { "value", "index" };
1407             ACE_SCORING_EVENT("TextPickerDialog.onChange");
1408             PipelineContext::SetCallBackNode(node);
1409             func->Execute(keys, info);
1410         };
1411         dialogEvent["changeId"] = changeId;
1412     }
1413     return dialogEvent;
1414 }
1415 
DialogCancelEvent(const JSCallbackInfo & info)1416 std::map<std::string, NG::DialogGestureEvent> JSTextPickerDialog::DialogCancelEvent(const JSCallbackInfo& info)
1417 {
1418     std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent;
1419     if (!info[0]->IsObject()) {
1420         return dialogCancelEvent;
1421     }
1422     auto paramObject = JSRef<JSObject>::Cast(info[0]);
1423     auto onCancel = paramObject->GetProperty("onCancel");
1424     WeakPtr<NG::FrameNode> targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
1425     if (!onCancel->IsUndefined() && onCancel->IsFunction()) {
1426         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onCancel));
1427         auto cancelId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1428                             const GestureEvent& /* info */) {
1429             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1430             ACE_SCORING_EVENT("TextPickerDialog.onCancel");
1431             PipelineContext::SetCallBackNode(node);
1432             func->Execute();
1433         };
1434         dialogCancelEvent["cancelId"] = cancelId;
1435     }
1436     return dialogCancelEvent;
1437 }
1438 
AddEvent(RefPtr<PickerTextComponent> & picker,const JSCallbackInfo & info)1439 void JSTextPickerDialog::AddEvent(RefPtr<PickerTextComponent>& picker, const JSCallbackInfo& info)
1440 {
1441     if (!info[0]->IsObject()) {
1442         return;
1443     }
1444     auto paramObject = JSRef<JSObject>::Cast(info[0]);
1445     auto onAccept = paramObject->GetProperty("onAccept");
1446     WeakPtr<NG::FrameNode> targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
1447     if (!onAccept->IsUndefined() && onAccept->IsFunction()) {
1448         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAccept));
1449         auto acceptId = EventMarker([execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1450                                         const std::string& info) {
1451             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1452             std::vector<std::string> keys = { "value", "index" };
1453             ACE_SCORING_EVENT("TextPickerDialog.onAccept");
1454             PipelineContext::SetCallBackNode(node);
1455             func->Execute(keys, info);
1456         });
1457         picker->SetDialogAcceptEvent(acceptId);
1458     }
1459     auto onCancel = paramObject->GetProperty("onCancel");
1460     if (!onCancel->IsUndefined() && onCancel->IsFunction()) {
1461         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onCancel));
1462         auto cancelId =
1463             EventMarker([execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1464                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1465                 ACE_SCORING_EVENT("TextPickerDialog.onCancel");
1466                 PipelineContext::SetCallBackNode(node);
1467                 func->Execute();
1468             });
1469         picker->SetDialogCancelEvent(cancelId);
1470     }
1471     auto onChange = paramObject->GetProperty("onChange");
1472     if (!onChange->IsUndefined() && onChange->IsFunction()) {
1473         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onChange));
1474         auto changeId = EventMarker([execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1475                                         const std::string& info) {
1476             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1477             std::vector<std::string> keys = { "value", "index" };
1478             ACE_SCORING_EVENT("TextPickerDialog.onChange");
1479             PipelineContext::SetCallBackNode(node);
1480             func->Execute(keys, info);
1481         });
1482         picker->SetDialogChangeEvent(changeId);
1483     }
1484 }
1485 
ParseText(RefPtr<PickerTextComponent> & component,const JSRef<JSObject> & paramObj)1486 void JSTextPickerDialog::ParseText(RefPtr<PickerTextComponent>& component, const JSRef<JSObject>& paramObj)
1487 {
1488     auto getSelected = paramObj->GetProperty("selected");
1489     auto defaultHeight = paramObj->GetProperty("defaultPickerItemHeight");
1490     auto canLoop = paramObj->GetProperty("canLoop");
1491     JSRef<JSArray> getRange = paramObj->GetProperty("range");
1492     std::vector<std::string> getRangeVector;
1493     if (!JSViewAbstract::ParseJsStrArray(getRange, getRangeVector)) {
1494         return;
1495     }
1496 
1497     std::string value = "";
1498     uint32_t selectedValue = 0;
1499     auto getValue = paramObj->GetProperty("value");
1500     if (!JSViewAbstract::ParseJsInteger(getSelected, selectedValue) && JSViewAbstract::ParseJsString(getValue, value)) {
1501         auto valueIterator = std::find(getRangeVector.begin(), getRangeVector.end(), value);
1502         if (valueIterator != getRangeVector.end()) {
1503             selectedValue = std::distance(getRangeVector.begin(), valueIterator);
1504         }
1505     }
1506 
1507     if (selectedValue >= getRangeVector.size()) {
1508         selectedValue = 0;
1509     }
1510 
1511     CalcDimension height;
1512     if (defaultHeight->IsNumber() || defaultHeight->IsString()) {
1513         if (!JSViewAbstract::ParseJsDimensionFp(defaultHeight, height)) {
1514             return;
1515         }
1516     }
1517 
1518     component->SetIsDialog(true);
1519     component->SetIsCreateDialogComponent(true);
1520     if (!defaultHeight->IsEmpty()) {
1521         component->SetColumnHeight(height);
1522         component->SetDefaultHeight(true);
1523     }
1524     component->SetSelected(selectedValue);
1525     component->SetRange(getRangeVector);
1526 }
1527 } // namespace OHOS::Ace::Framework
1528