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