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