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