• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "bridge/declarative_frontend/jsview/js_datepicker.h"
17 
18 #include <utility>
19 
20 #include "base/log/ace_scoring_log.h"
21 #include "base/utils/utils.h"
22 #include "bridge/common/utils/engine_helper.h"
23 #include "bridge/declarative_frontend/engine/functions/js_event_function.h"
24 #include "bridge/declarative_frontend/jsview/js_interactable_view.h"
25 #include "bridge/declarative_frontend/jsview/js_utils.h"
26 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
27 #include "bridge/declarative_frontend/jsview/models/picker_model_impl.h"
28 #include "bridge/declarative_frontend/jsview/models/timepicker_model_impl.h"
29 #include "bridge/declarative_frontend/view_stack_processor.h"
30 #include "core/components/picker/picker_data.h"
31 #include "core/components/picker/picker_date_component.h"
32 #include "core/components/picker/picker_theme.h"
33 #include "core/components/picker/picker_time_component.h"
34 #include "core/components_ng/base/view_stack_processor.h"
35 #include "core/components_ng/pattern/picker/datepicker_model_ng.h"
36 #include "core/components_ng/pattern/time_picker/timepicker_model.h"
37 #include "core/components_ng/pattern/time_picker/timepicker_model_ng.h"
38 #include "core/components_v2/inspector/inspector_constants.h"
39 #include "core/event/ace_event_helper.h"
40 #include "core/pipeline_ng/pipeline_context.h"
41 #include "core/common/resource/resource_object.h"
42 #include "core/common/resource/resource_parse_utils.h"
43 
44 namespace OHOS::Ace {
45 namespace {
46 const DimensionOffset DATEPICKER_OFFSET_DEFAULT_TOP = DimensionOffset(0.0_vp, 40.0_vp);
47 const std::vector<DialogAlignment> DIALOG_ALIGNMENT = { DialogAlignment::TOP, DialogAlignment::CENTER,
48     DialogAlignment::BOTTOM, DialogAlignment::DEFAULT, DialogAlignment::TOP_START, DialogAlignment::TOP_END,
49     DialogAlignment::CENTER_START, DialogAlignment::CENTER_END, DialogAlignment::BOTTOM_START,
50     DialogAlignment::BOTTOM_END };
51 const std::vector<HoverModeAreaType> HOVER_MODE_AREA_TYPE = { HoverModeAreaType::TOP_SCREEN,
52     HoverModeAreaType::BOTTOM_SCREEN };
53 const char TIMEPICKER_OPTIONS_HOUR[] = "hour";
54 const char TIMEPICKER_OPTIONS_MINUTE[] = "minute";
55 const char TIMEPICKER_OPTIONS_SECOND[] = "second";
56 const std::string TIMEPICKER_OPTIONS_NUMERIC_VAL = "numeric";
57 const std::string TIMEPICKER_OPTIONS_TWO_DIGIT_VAL = "2-digit";
58 } // namespace
59 
60 std::unique_ptr<DatePickerModel> DatePickerModel::datePickerInstance_ = nullptr;
61 std::unique_ptr<DatePickerDialogModel> DatePickerDialogModel::datePickerDialogInstance_ = nullptr;
62 std::unique_ptr<TimePickerModel> TimePickerModel::timePickerInstance_ = nullptr;
63 std::unique_ptr<TimePickerDialogModel> TimePickerDialogModel::timePickerDialogInstance_ = nullptr;
64 std::once_flag DatePickerModel::onceFlag_;
65 std::once_flag DatePickerDialogModel::onceFlag_;
66 std::once_flag TimePickerModel::onceFlag_;
67 std::once_flag TimePickerDialogModel::onceFlag_;
68 
GetInstance()69 DatePickerModel* DatePickerModel::GetInstance()
70 {
71     std::call_once(onceFlag_, []() {
72 #ifdef NG_BUILD
73         datePickerInstance_.reset(new NG::DatePickerModelNG());
74 #else
75         if (Container::IsCurrentUseNewPipeline()) {
76             datePickerInstance_.reset(new NG::DatePickerModelNG());
77         } else {
78             datePickerInstance_.reset(new Framework::DatePickerModelImpl());
79         }
80 #endif
81     });
82 
83     return datePickerInstance_.get();
84 }
85 
GetInstance()86 DatePickerDialogModel* DatePickerDialogModel::GetInstance()
87 {
88     std::call_once(onceFlag_, []() {
89 #ifdef NG_BUILD
90         datePickerDialogInstance_.reset(new NG::DatePickerDialogModelNG());
91 #else
92         if (Container::IsCurrentUseNewPipeline()) {
93             datePickerDialogInstance_.reset(new NG::DatePickerDialogModelNG());
94         } else {
95             datePickerDialogInstance_.reset(new Framework::DatePickerDialogModelImpl());
96         }
97 #endif
98     });
99 
100     return datePickerDialogInstance_.get();
101 }
102 
GetInstance()103 TimePickerModel* TimePickerModel::GetInstance()
104 {
105     std::call_once(onceFlag_, []() {
106 #ifdef NG_BUILD
107         timePickerInstance_.reset(new NG::TimePickerModelNG());
108 #else
109         if (Container::IsCurrentUseNewPipeline()) {
110             timePickerInstance_.reset(new NG::TimePickerModelNG());
111         } else {
112             timePickerInstance_.reset(new Framework::TimePickerModelImpl());
113         }
114 #endif
115     });
116 
117     return timePickerInstance_.get();
118 }
119 
GetInstance()120 TimePickerDialogModel* TimePickerDialogModel::GetInstance()
121 {
122     std::call_once(onceFlag_, []() {
123 #ifdef NG_BUILD
124         timePickerDialogInstance_.reset(new NG::TimePickerDialogModelNG());
125 #else
126         if (Container::IsCurrentUseNewPipeline()) {
127             timePickerDialogInstance_.reset(new NG::TimePickerDialogModelNG());
128         } else {
129             timePickerDialogInstance_.reset(new Framework::TimePickerDialogModelImpl());
130         }
131 #endif
132     });
133 
134     return timePickerDialogInstance_.get();
135 }
136 } // namespace OHOS::Ace
137 
138 namespace OHOS::Ace::Framework {
139 namespace {
DatePickerChangeEventToJSValue(const DatePickerChangeEvent & eventInfo)140 JSRef<JSVal> DatePickerChangeEventToJSValue(const DatePickerChangeEvent& eventInfo)
141 {
142     JSRef<JSObject> obj = JSRef<JSObject>::New();
143     std::unique_ptr<JsonValue> argsPtr = JsonUtil::ParseJsonString(eventInfo.GetSelectedStr());
144     if (!argsPtr) {
145         return JSRef<JSVal>::Cast(obj);
146     }
147     std::vector<std::string> keys = { "year", "month", "day", "hour", "minute", "second" };
148     for (auto iter = keys.begin(); iter != keys.end(); iter++) {
149         const std::string key = *iter;
150         const auto value = argsPtr->GetValue(key);
151         if (!value || value->ToString().empty()) {
152             continue;
153         }
154         obj->SetProperty<int32_t>(key.c_str(), value->GetInt());
155     }
156     return JSRef<JSVal>::Cast(obj);
157 }
158 
DatePickerDateChangeEventToJSValue(const DatePickerChangeEvent & eventInfo)159 JSRef<JSVal> DatePickerDateChangeEventToJSValue(const DatePickerChangeEvent& eventInfo)
160 {
161     JSRef<JSObject> obj = JSRef<JSObject>::New();
162     std::unique_ptr<JsonValue> argsPtr = JsonUtil::ParseJsonString(eventInfo.GetSelectedStr());
163     if (!argsPtr) {
164         return JSRef<JSVal>::Cast(obj);
165     }
166     auto dateObj = JSDatePickerDialog::GetDateObj(argsPtr);
167     return JSRef<JSVal>::Cast(dateObj);
168 }
169 
ParseFontOfButtonStyle(const JSRef<JSObject> & pickerButtonParamObject,ButtonInfo & buttonInfo)170 void ParseFontOfButtonStyle(const JSRef<JSObject>& pickerButtonParamObject, ButtonInfo& buttonInfo)
171 {
172     CalcDimension fontSize;
173     JSRef<JSVal> sizeProperty = pickerButtonParamObject->GetProperty("fontSize");
174     if (JSViewAbstract::ParseJsDimensionVpNG(sizeProperty, fontSize) && fontSize.Unit() != DimensionUnit::PERCENT &&
175         GreatOrEqual(fontSize.Value(), 0.0)) {
176         if (JSViewAbstract::ParseJsDimensionFp(sizeProperty, fontSize)) {
177             buttonInfo.fontSize = fontSize;
178         }
179     }
180     Color fontColor;
181     if (JSViewAbstract::ParseJsColor(pickerButtonParamObject->GetProperty("fontColor"), fontColor)) {
182         buttonInfo.fontColor = fontColor;
183     }
184     auto fontWeight = pickerButtonParamObject->GetProperty("fontWeight");
185     if (fontWeight->IsString() || fontWeight->IsNumber()) {
186         buttonInfo.fontWeight = ConvertStrToFontWeight(fontWeight->ToString(), FontWeight::MEDIUM);
187     }
188     JSRef<JSVal> style = pickerButtonParamObject->GetProperty("fontStyle");
189     if (style->IsNumber()) {
190         auto value = style->ToNumber<int32_t>();
191         if (value >= 0 && value < static_cast<int32_t>(FontStyle::NONE)) {
192             buttonInfo.fontStyle = static_cast<FontStyle>(value);
193         }
194     }
195     JSRef<JSVal> family = pickerButtonParamObject->GetProperty("fontFamily");
196     std::vector<std::string> fontFamilies;
197     if (JSViewAbstract::ParseJsFontFamilies(family, fontFamilies)) {
198         buttonInfo.fontFamily = fontFamilies;
199     }
200 }
201 
ParseButtonStyle(const JSRef<JSObject> & pickerButtonParamObject)202 ButtonInfo ParseButtonStyle(const JSRef<JSObject>& pickerButtonParamObject)
203 {
204     ButtonInfo buttonInfo;
205     if (pickerButtonParamObject->GetProperty("type")->IsNumber()) {
206         auto buttonTypeIntValue = pickerButtonParamObject->GetProperty("type")->ToNumber<int32_t>();
207         if (buttonTypeIntValue == static_cast<int32_t>(ButtonType::CAPSULE) ||
208             buttonTypeIntValue == static_cast<int32_t>(ButtonType::CIRCLE) ||
209             buttonTypeIntValue == static_cast<int32_t>(ButtonType::ARC) ||
210             buttonTypeIntValue == static_cast<int32_t>(ButtonType::NORMAL) ||
211             buttonTypeIntValue == static_cast<int32_t>(ButtonType::ROUNDED_RECTANGLE)) {
212             buttonInfo.type = static_cast<ButtonType>(buttonTypeIntValue);
213         }
214     }
215     if (pickerButtonParamObject->GetProperty("style")->IsNumber()) {
216         auto styleModeIntValue = pickerButtonParamObject->GetProperty("style")->ToNumber<int32_t>();
217         if (styleModeIntValue >= static_cast<int32_t>(ButtonStyleMode::NORMAL) &&
218             styleModeIntValue <= static_cast<int32_t>(ButtonStyleMode::TEXT)) {
219             buttonInfo.buttonStyle = static_cast<ButtonStyleMode>(styleModeIntValue);
220         }
221     }
222     if (pickerButtonParamObject->GetProperty("role")->IsNumber()) {
223         auto buttonRoleIntValue = pickerButtonParamObject->GetProperty("role")->ToNumber<int32_t>();
224         if (buttonRoleIntValue >= static_cast<int32_t>(ButtonRole::NORMAL) &&
225             buttonRoleIntValue <= static_cast<int32_t>(ButtonRole::ERROR)) {
226             buttonInfo.role = static_cast<ButtonRole>(buttonRoleIntValue);
227         }
228     }
229     ParseFontOfButtonStyle(pickerButtonParamObject, buttonInfo);
230     Color backgroundColor;
231     if (JSViewAbstract::ParseJsColor(pickerButtonParamObject->GetProperty("backgroundColor"), backgroundColor)) {
232         buttonInfo.backgroundColor = backgroundColor;
233     }
234     auto radius = ParseBorderRadiusAttr(pickerButtonParamObject->GetProperty("borderRadius"));
235     if (radius.has_value()) {
236         buttonInfo.borderRadius = radius.value();
237     }
238 
239     auto primaryValue = pickerButtonParamObject->GetProperty("primary");
240     if (primaryValue->IsBoolean()) {
241         buttonInfo.isPrimary = primaryValue->ToBoolean();
242     }
243 
244     return buttonInfo;
245 }
246 
ParseButtonStyles(const JSRef<JSObject> & paramObject)247 std::vector<ButtonInfo> ParseButtonStyles(const JSRef<JSObject>& paramObject)
248 {
249     std::vector<ButtonInfo> buttonInfos;
250     auto acceptButtonStyle = paramObject->GetProperty("acceptButtonStyle");
251     if (acceptButtonStyle->IsObject()) {
252         auto acceptButtonStyleParamObject = JSRef<JSObject>::Cast(acceptButtonStyle);
253         buttonInfos.emplace_back(ParseButtonStyle(acceptButtonStyleParamObject));
254         buttonInfos[0].isAcceptButton = true;
255     } else {
256         ButtonInfo buttonInfo;
257         buttonInfos.emplace_back(buttonInfo);
258     }
259     auto cancelButtonStyle = paramObject->GetProperty("cancelButtonStyle");
260     if (cancelButtonStyle->IsObject()) {
261         auto cancelButtonStyleParamObject = JSRef<JSObject>::Cast(cancelButtonStyle);
262         buttonInfos.emplace_back(ParseButtonStyle(cancelButtonStyleParamObject));
263     }
264 
265     return buttonInfos;
266 }
267 
ParseDatePickerHoverMode(PickerDialogInfo & pickerDialog,const JSRef<JSObject> & paramObject)268 void ParseDatePickerHoverMode(PickerDialogInfo& pickerDialog, const JSRef<JSObject>& paramObject)
269 {
270     auto enableHoverModeValue = paramObject->GetProperty("enableHoverMode");
271     if (enableHoverModeValue->IsBoolean()) {
272         pickerDialog.enableHoverMode = enableHoverModeValue->ToBoolean();
273     }
274 
275     auto hoverModeAreaValue = paramObject->GetProperty("hoverModeArea");
276     pickerDialog.hoverModeArea = HoverModeAreaType::BOTTOM_SCREEN;
277     if (hoverModeAreaValue->IsNumber()) {
278         auto hoverModeArea = hoverModeAreaValue->ToNumber<int32_t>();
279         if (hoverModeArea >= 0 && hoverModeArea < static_cast<int32_t>(HOVER_MODE_AREA_TYPE.size())) {
280             pickerDialog.hoverModeArea = HOVER_MODE_AREA_TYPE[hoverModeArea];
281         }
282     }
283 }
284 
ParseDatePickerBlurStyleOption(PickerDialogInfo & pickerDialog,const JSRef<JSObject> & paramObject)285 void ParseDatePickerBlurStyleOption(PickerDialogInfo& pickerDialog, const JSRef<JSObject>& paramObject)
286 {
287     auto blurStyleValue = paramObject->GetProperty("backgroundBlurStyleOptions");
288     if (blurStyleValue->IsObject()) {
289         if (!pickerDialog.blurStyleOption.has_value()) {
290             pickerDialog.blurStyleOption.emplace();
291         }
292         JSViewAbstract::ParseBlurStyleOption(blurStyleValue, pickerDialog.blurStyleOption.value());
293     }
294 }
295 
ParseDatePickerEffectOption(PickerDialogInfo & pickerDialog,const JSRef<JSObject> & paramObject)296 void ParseDatePickerEffectOption(PickerDialogInfo& pickerDialog, const JSRef<JSObject>& paramObject)
297 {
298     auto effectOptionValue = paramObject->GetProperty("backgroundEffect");
299     if (effectOptionValue->IsObject()) {
300         if (!pickerDialog.effectOption.has_value()) {
301             pickerDialog.effectOption.emplace();
302         }
303         JSViewAbstract::ParseEffectOption(effectOptionValue, pickerDialog.effectOption.value());
304     }
305 }
306 } // namespace
307 
JSBind(BindingTarget globalObj)308 void JSDatePicker::JSBind(BindingTarget globalObj)
309 {
310     JSClass<JSDatePicker>::Declare("DatePicker");
311     MethodOptions opt = MethodOptions::NONE;
312     JSClass<JSDatePicker>::StaticMethod("create", &JSDatePicker::Create, opt);
313     JSClass<JSDatePicker>::StaticMethod("lunar", &JSDatePicker::SetLunar);
314     JSClass<JSDatePicker>::StaticMethod("canLoop", &JSDatePicker::SetCanLoop);
315     JSClass<JSDatePicker>::StaticMethod("onChange", &JSDatePicker::OnChange);
316     JSClass<JSDatePicker>::StaticMethod("onDateChange", &JSDatePicker::OnDateChange);
317     JSClass<JSDatePicker>::StaticMethod("backgroundColor", &JSDatePicker::PickerBackgroundColor);
318     JSClass<JSDatePicker>::StaticMethod("opacity", &JSDatePicker::JsOpacity);
319     // keep compatible, need remove after
320     JSClass<JSDatePicker>::StaticMethod("useMilitaryTime", &JSDatePicker::UseMilitaryTime);
321     JSClass<JSDatePicker>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
322     JSClass<JSDatePicker>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
323     JSClass<JSDatePicker>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
324     JSClass<JSDatePicker>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
325     JSClass<JSDatePicker>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
326     JSClass<JSDatePicker>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
327     JSClass<JSDatePicker>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
328     JSClass<JSDatePicker>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
329     JSClass<JSDatePicker>::StaticMethod("disappearTextStyle", &JSDatePicker::SetDisappearTextStyle);
330     JSClass<JSDatePicker>::StaticMethod("textStyle", &JSDatePicker::SetTextStyle);
331     JSClass<JSDatePicker>::StaticMethod("selectedTextStyle", &JSDatePicker::SetSelectedTextStyle);
332     JSClass<JSDatePicker>::StaticMethod("enableHapticFeedback", &JSDatePicker::SetEnableHapticFeedback);
333     JSClass<JSDatePicker>::StaticMethod("digitalCrownSensitivity", &JSDatePicker::SetDigitalCrownSensitivity);
334     JSClass<JSDatePicker>::InheritAndBind<JSViewAbstract>(globalObj);
335 }
336 
SetDigitalCrownSensitivity(const JSCallbackInfo & info)337 void JSDatePicker::SetDigitalCrownSensitivity(const JSCallbackInfo& info)
338 {
339     int32_t value = OHOS::Ace::NG::DEFAULT_CROWNSENSITIVITY;
340     if (info.Length() >= 1 && info[0]->IsNumber()) {
341         value = info[0]->ToNumber<int32_t>();
342     }
343     DatePickerModel::GetInstance()->SetDigitalCrownSensitivity(value);
344 }
345 
Create(const JSCallbackInfo & info)346 void JSDatePicker::Create(const JSCallbackInfo& info)
347 {
348     DatePickerType pickerType = DatePickerType::DATE;
349     JSRef<JSObject> paramObject;
350     if (info.Length() >= 1 && info[0]->IsObject()) {
351         paramObject = JSRef<JSObject>::Cast(info[0]);
352         auto type = paramObject->GetProperty("type");
353         if (type->IsNumber()) {
354             pickerType = static_cast<DatePickerType>(type->ToNumber<int32_t>());
355         }
356     }
357     switch (pickerType) {
358         case DatePickerType::TIME: {
359             CreateTimePicker(info, paramObject);
360             break;
361         }
362         case DatePickerType::DATE: {
363             CreateDatePicker(info, paramObject);
364             break;
365         }
366         default: {
367             break;
368         }
369     }
370 }
371 
SetLunar(bool isLunar)372 void JSDatePicker::SetLunar(bool isLunar)
373 {
374     DatePickerModel::GetInstance()->SetShowLunar(isLunar);
375 }
376 
SetCanLoop(const JSCallbackInfo & info)377 void JSDatePicker::SetCanLoop(const JSCallbackInfo& info)
378 {
379     bool value = true;
380     if (info.Length() >= 1 && info[0]->IsBoolean()) {
381         value = info[0]->ToBoolean();
382     }
383     DatePickerModel::GetInstance()->SetCanLoop(value);
384 }
385 
UseMilitaryTime(bool isUseMilitaryTime)386 void JSDatePicker::UseMilitaryTime(bool isUseMilitaryTime)
387 {
388     DatePickerModel::GetInstance()->SetHour24(isUseMilitaryTime);
389 }
390 
ParseTextProperties(const JSRef<JSObject> & paramObj,NG::PickerTextProperties & result)391 void JSDatePicker::ParseTextProperties(const JSRef<JSObject>& paramObj, NG::PickerTextProperties& result)
392 {
393     auto disappearProperty = paramObj->GetProperty("disappearTextStyle");
394     auto normalProperty = paramObj->GetProperty("textStyle");
395     auto selectedProperty = paramObj->GetProperty("selectedTextStyle");
396 
397     if (!disappearProperty->IsNull() && disappearProperty->IsObject()) {
398         JSRef<JSObject> disappearObj = JSRef<JSObject>::Cast(disappearProperty);
399         JSDatePicker::ParseTextStyle(disappearObj, result.disappearTextStyle_, "disappearTextStyle");
400     }
401 
402     if (!normalProperty->IsNull() && normalProperty->IsObject()) {
403         JSRef<JSObject> noramlObj = JSRef<JSObject>::Cast(normalProperty);
404         JSDatePicker::ParseTextStyle(noramlObj, result.normalTextStyle_, "textStyle");
405     }
406 
407     if (!selectedProperty->IsNull() && selectedProperty->IsObject()) {
408         JSRef<JSObject> selectedObj = JSRef<JSObject>::Cast(selectedProperty);
409         JSDatePicker::ParseTextStyle(selectedObj, result.selectedTextStyle_, "selectedTextStyle");
410     }
411 }
412 
IsUserDefinedFontFamily(const std::string & pos)413 void JSDatePicker::IsUserDefinedFontFamily(const std::string& pos)
414 {
415     if (pos == "disappearTextStyle") {
416         DatePickerModel::GetInstance()->HasUserDefinedDisappearFontFamily(true);
417     } else if (pos == "textStyle") {
418         DatePickerModel::GetInstance()->HasUserDefinedNormalFontFamily(true);
419     } else if (pos == "selectedTextStyle") {
420         DatePickerModel::GetInstance()->HasUserDefinedSelectedFontFamily(true);
421     } else if (pos == "disappearTextStyleTime") {
422         TimePickerModel::GetInstance()->HasUserDefinedDisappearFontFamily(true);
423     } else if (pos == "textStyleTime") {
424         TimePickerModel::GetInstance()->HasUserDefinedNormalFontFamily(true);
425     } else if (pos == "selectedTextStyleTime") {
426         TimePickerModel::GetInstance()->HasUserDefinedSelectedFontFamily(true);
427     }
428 }
429 
ParseTextStyleFontSize(const JSRef<JSVal> & fontSize,NG::PickerTextStyle & textStyle)430 void JSDatePicker::ParseTextStyleFontSize(const JSRef<JSVal>& fontSize, NG::PickerTextStyle& textStyle)
431 {
432     if (fontSize->IsNull() || fontSize->IsUndefined()) {
433         textStyle.fontSize = Dimension(-1);
434     } else {
435         CalcDimension size;
436         if (!ParseJsDimensionFp(fontSize, size, textStyle.fontSizeResObj) || size.Unit() == DimensionUnit::PERCENT) {
437             textStyle.fontSize = Dimension(-1);
438         } else {
439             textStyle.fontSize = size;
440         }
441     }
442 }
443 
ParseTextStyle(const JSRef<JSObject> & paramObj,NG::PickerTextStyle & textStyle,const std::string & pos)444 void JSDatePicker::ParseTextStyle(
445     const JSRef<JSObject>& paramObj, NG::PickerTextStyle& textStyle, const std::string& pos)
446 {
447     auto fontColor = paramObj->GetProperty("color");
448     auto fontOptions = paramObj->GetProperty("font");
449 
450     Color textColor;
451     if (JSViewAbstract::ParseJsColor(fontColor, textColor, textStyle.textColorResObj)) {
452         textStyle.textColor = textColor;
453         textStyle.textColorSetByUser = true;
454     }
455 
456     if (!fontOptions->IsObject()) {
457         return;
458     }
459     JSRef<JSObject> fontObj = JSRef<JSObject>::Cast(fontOptions);
460     auto fontSize = fontObj->GetProperty("size");
461     auto fontWeight = fontObj->GetProperty("weight");
462     auto fontFamily = fontObj->GetProperty("family");
463     auto fontStyle = fontObj->GetProperty("style");
464 
465     ParseTextStyleFontSize(fontSize, textStyle);
466 
467     if (!fontWeight->IsNull() && !fontWeight->IsUndefined()) {
468         std::string weight;
469         if (fontWeight->IsNumber()) {
470             weight = std::to_string(fontWeight->ToNumber<int32_t>());
471         } else {
472             ParseJsString(fontWeight, weight);
473         }
474         textStyle.fontWeight = ConvertStrToFontWeight(weight);
475     }
476 
477     if (!fontFamily->IsNull() && !fontFamily->IsUndefined()) {
478         std::vector<std::string> families;
479         if (ParseJsFontFamilies(fontFamily, families, textStyle.fontFamilyResObj)) {
480             textStyle.fontFamily = families;
481             IsUserDefinedFontFamily(pos);
482         }
483     }
484 
485     if (fontStyle->IsNumber()) {
486         auto style = fontStyle->ToNumber<int32_t>();
487         if (style < 0 || style > 1) {
488             return;
489         }
490         textStyle.fontStyle = static_cast<FontStyle>(style);
491     }
492 }
493 
SetDisappearTextStyle(const JSCallbackInfo & info)494 void JSDatePicker::SetDisappearTextStyle(const JSCallbackInfo& info)
495 {
496     auto theme = GetTheme<PickerTheme>();
497     CHECK_NULL_VOID(theme);
498     NG::PickerTextStyle textStyle;
499     if (info[0]->IsObject()) {
500         JSDatePicker::ParseTextStyle(info[0], textStyle, "disappearTextStyle");
501     }
502     DatePickerModel::GetInstance()->SetDisappearTextStyle(theme, textStyle);
503 }
504 
SetTextStyle(const JSCallbackInfo & info)505 void JSDatePicker::SetTextStyle(const JSCallbackInfo& info)
506 {
507     auto theme = GetTheme<PickerTheme>();
508     CHECK_NULL_VOID(theme);
509     NG::PickerTextStyle textStyle;
510     if (info[0]->IsObject()) {
511         JSDatePicker::ParseTextStyle(info[0], textStyle, "textStyle");
512     }
513     DatePickerModel::GetInstance()->SetNormalTextStyle(theme, textStyle);
514 }
515 
SetEnableHapticFeedback(const JSCallbackInfo & info)516 void JSDatePicker::SetEnableHapticFeedback(const JSCallbackInfo& info)
517 {
518     bool isEnableHapticFeedback = true;
519     if (info[0]->IsBoolean()) {
520         isEnableHapticFeedback = info[0]->ToBoolean();
521     }
522     DatePickerModel::GetInstance()->SetEnableHapticFeedback(isEnableHapticFeedback);
523 }
524 
SetSelectedTextStyle(const JSCallbackInfo & info)525 void JSDatePicker::SetSelectedTextStyle(const JSCallbackInfo& info)
526 {
527     auto theme = GetTheme<PickerTheme>();
528     CHECK_NULL_VOID(theme);
529     NG::PickerTextStyle textStyle;
530     if (info[0]->IsObject()) {
531         JSDatePicker::ParseTextStyle(info[0], textStyle, "selectedTextStyle");
532     }
533     DatePickerModel::GetInstance()->SetSelectedTextStyle(theme, textStyle);
534     if (textStyle.textColor.has_value() && theme->IsCircleDial()) {
535         DatePickerModel::GetInstance()->UpdateUserSetSelectColor();
536     }
537 }
538 
JsOpacity(const JSCallbackInfo & info)539 void JSDatePicker::JsOpacity(const JSCallbackInfo& info)
540 {
541     JSViewAbstract::JsOpacity(info);
542     DatePickerModel::GetInstance()->HasUserDefinedOpacity();
543 }
544 
OnChange(const JSCallbackInfo & info)545 void JSDatePicker::OnChange(const JSCallbackInfo& info)
546 {
547     if (!info[0]->IsFunction()) {
548         return;
549     }
550 
551     auto jsFunc = AceType::MakeRefPtr<JsEventFunction<DatePickerChangeEvent, 1>>(
552         JSRef<JSFunc>::Cast(info[0]), DatePickerChangeEventToJSValue);
553     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
554     auto onChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
555                         const BaseEventInfo* info) {
556         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
557         ACE_SCORING_EVENT("datePicker.onChange");
558         PipelineContext::SetCallBackNode(node);
559         const auto* eventInfo = TypeInfoHelper::DynamicCast<DatePickerChangeEvent>(info);
560         func->Execute(*eventInfo);
561     };
562     DatePickerModel::GetInstance()->SetOnChange(std::move(onChange));
563 }
564 
OnDateChange(const JSCallbackInfo & info)565 void JSDatePicker::OnDateChange(const JSCallbackInfo& info)
566 {
567     if (!info[0]->IsFunction()) {
568         return;
569     }
570     auto jsFunc = AceType::MakeRefPtr<JsEventFunction<DatePickerChangeEvent, 1>>(
571         JSRef<JSFunc>::Cast(info[0]), DatePickerDateChangeEventToJSValue);
572     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
573     auto onDateChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
574                             const BaseEventInfo* info) {
575         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
576         ACE_SCORING_EVENT("datePicker.onDateChange");
577         PipelineContext::SetCallBackNode(node);
578         const auto* eventInfo = TypeInfoHelper::DynamicCast<DatePickerChangeEvent>(info);
579         func->Execute(*eventInfo);
580     };
581     DatePickerModel::GetInstance()->SetOnDateChange(std::move(onDateChange));
582 }
583 
OnChange(const JSCallbackInfo & info)584 void JSTimePicker::OnChange(const JSCallbackInfo& info)
585 {
586     if (!info[0]->IsFunction()) {
587         return;
588     }
589 
590     auto jsFunc = AceType::MakeRefPtr<JsEventFunction<DatePickerChangeEvent, 1>>(
591         JSRef<JSFunc>::Cast(info[0]), DatePickerChangeEventToJSValue);
592     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
593     auto onChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
594                         const BaseEventInfo* index) {
595         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
596         ACE_SCORING_EVENT("datePicker.onChange");
597         PipelineContext::SetCallBackNode(node);
598         const auto* eventInfo = TypeInfoHelper::DynamicCast<DatePickerChangeEvent>(index);
599         func->Execute(*eventInfo);
600     };
601     TimePickerModel::GetInstance()->SetOnChange(std::move(onChange));
602 }
603 
OnEnterSelectedArea(const JSCallbackInfo & info)604 void JSTimePicker::OnEnterSelectedArea(const JSCallbackInfo& info)
605 {
606     if (!info[0]->IsFunction()) {
607         return;
608     }
609 
610     auto jsFunc = AceType::MakeRefPtr<JsEventFunction<DatePickerChangeEvent, 1>>(
611         JSRef<JSFunc>::Cast(info[0]), DatePickerChangeEventToJSValue);
612     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
613     auto onEnterSelectedArea = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
614                         const BaseEventInfo* index) {
615         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
616         ACE_SCORING_EVENT("datePicker.onEnterSelectedArea");
617         PipelineContext::SetCallBackNode(node);
618         const auto* eventInfo = TypeInfoHelper::DynamicCast<DatePickerChangeEvent>(index);
619         func->Execute(*eventInfo);
620     };
621     TimePickerModel::GetInstance()->SetOnEnterSelectedArea(std::move(onEnterSelectedArea));
622 }
623 
PickerBackgroundColor(const JSCallbackInfo & info)624 void JSDatePicker::PickerBackgroundColor(const JSCallbackInfo& info)
625 {
626     JSViewAbstract::JsBackgroundColor(info);
627 
628     if (info.Length() < 1) {
629         return;
630     }
631     Color backgroundColor;
632     if (!ParseJsColor(info[0], backgroundColor)) {
633         return;
634     }
635     DatePickerModel::GetInstance()->SetBackgroundColor(backgroundColor);
636 }
637 
ParseDate(const JSRef<JSVal> & dateVal)638 PickerDate JSDatePicker::ParseDate(const JSRef<JSVal>& dateVal)
639 {
640     auto pickerDate = PickerDate();
641     if (!dateVal->IsObject()) {
642         return pickerDate;
643     }
644     auto dateObj = JSRef<JSObject>::Cast(dateVal);
645     auto yearFuncJsVal = dateObj->GetProperty("getFullYear");
646     auto monthFuncJsVal = dateObj->GetProperty("getMonth");
647     auto dateFuncJsVal = dateObj->GetProperty("getDate");
648     if (!(yearFuncJsVal->IsFunction() && monthFuncJsVal->IsFunction() && dateFuncJsVal->IsFunction())) {
649         return pickerDate;
650     }
651     auto yearFunc = JSRef<JSFunc>::Cast(yearFuncJsVal);
652     auto monthFunc = JSRef<JSFunc>::Cast(monthFuncJsVal);
653     auto dateFunc = JSRef<JSFunc>::Cast(dateFuncJsVal);
654     JSRef<JSVal> year = yearFunc->Call(dateObj);
655     JSRef<JSVal> month = monthFunc->Call(dateObj);
656     JSRef<JSVal> date = dateFunc->Call(dateObj);
657 
658     if (year->IsNumber() && month->IsNumber() && date->IsNumber()) {
659         pickerDate.SetYear(year->ToNumber<int32_t>());
660         pickerDate.SetMonth(month->ToNumber<int32_t>() + 1); // 0-11 means 1 to 12 months
661         pickerDate.SetDay(date->ToNumber<int32_t>());
662     }
663     return pickerDate;
664 }
665 
ParseTime(const JSRef<JSVal> & timeVal)666 PickerTime JSDatePicker::ParseTime(const JSRef<JSVal>& timeVal)
667 {
668     auto pickerTime = PickerTime();
669     if (!timeVal->IsObject()) {
670         return pickerTime;
671     }
672     auto timeObj = JSRef<JSObject>::Cast(timeVal);
673     auto hourFuncJsVal = timeObj->GetProperty("getHours");
674     auto minuteFuncJsVal = timeObj->GetProperty("getMinutes");
675     auto secondFuncJsVal = timeObj->GetProperty("getSeconds");
676     if (!(hourFuncJsVal->IsFunction() && minuteFuncJsVal->IsFunction() && secondFuncJsVal->IsFunction())) {
677         return pickerTime;
678     }
679     auto hourFunc = JSRef<JSFunc>::Cast(hourFuncJsVal);
680     auto minuteFunc = JSRef<JSFunc>::Cast(minuteFuncJsVal);
681     auto secondFunc = JSRef<JSFunc>::Cast(secondFuncJsVal);
682     JSRef<JSVal> hour = hourFunc->Call(timeObj);
683     JSRef<JSVal> minute = minuteFunc->Call(timeObj);
684     JSRef<JSVal> second = secondFunc->Call(timeObj);
685 
686     if (hour->IsNumber() && minute->IsNumber() && second->IsNumber()) {
687         pickerTime.SetHour(hour->ToNumber<int32_t>());
688         pickerTime.SetMinute(minute->ToNumber<int32_t>());
689         pickerTime.SetSecond(second->ToNumber<int32_t>());
690     }
691     return pickerTime;
692 }
693 
ParseSelectedDateTimeObject(const JSCallbackInfo & info,const JSRef<JSObject> & selectedObject,bool isDatePicker)694 void ParseSelectedDateTimeObject(const JSCallbackInfo& info, const JSRef<JSObject>& selectedObject, bool isDatePicker)
695 {
696     JSRef<JSVal> changeEventVal = selectedObject->GetProperty("changeEvent");
697     if (changeEventVal->IsUndefined() || !changeEventVal->IsFunction()) {
698         return;
699     }
700     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
701     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
702     auto changeEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
703                            node = targetNode, isDatePicker](const BaseEventInfo* info) {
704         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
705         ACE_SCORING_EVENT("DatePicker.SelectedDateTimeChangeEvent");
706         const auto* eventInfo = TypeInfoHelper::DynamicCast<DatePickerChangeEvent>(info);
707         CHECK_NULL_VOID(eventInfo);
708         auto selectedStr = eventInfo->GetSelectedStr();
709         auto sourceJson = JsonUtil::ParseJsonString(selectedStr);
710         if (!sourceJson || sourceJson->IsNull()) {
711             return;
712         }
713 
714         auto dateObj = JSDatePickerDialog::GetDateObj(sourceJson, isDatePicker);
715         PipelineContext::SetCallBackNode(node);
716         func->ExecuteJS(1, &dateObj);
717     };
718     if (isDatePicker) {
719         DatePickerModel::GetInstance()->SetChangeEvent(std::move(changeEvent));
720     } else {
721         TimePickerModel::GetInstance()->SetChangeEvent(std::move(changeEvent));
722     }
723 }
724 
CreateDatePicker(const JSCallbackInfo & info,const JSRef<JSObject> & paramObj)725 void JSDatePicker::CreateDatePicker(const JSCallbackInfo& info, const JSRef<JSObject>& paramObj)
726 {
727     JSRef<JSVal> startDate;
728     JSRef<JSVal> endDate;
729     JSRef<JSVal> selectedDate;
730     JSRef<JSVal> mode;
731     if (!paramObj->IsUndefined()) {
732         startDate = paramObj->GetProperty("start");
733         endDate = paramObj->GetProperty("end");
734         selectedDate = paramObj->GetProperty("selected");
735         mode = paramObj->GetProperty("mode");
736     }
737     ParseStartEndDate(startDate, endDate);
738 
739     PickerDate parseSelectedDate = PickerDate::Current();
740     if (selectedDate->IsObject()) {
741         JSRef<JSObject> selectedDateObj = JSRef<JSObject>::Cast(selectedDate);
742         JSRef<JSVal> changeEventVal = selectedDateObj->GetProperty("changeEvent");
743         if (!changeEventVal->IsUndefined() && changeEventVal->IsFunction()) {
744             ParseSelectedDateTimeObject(info, selectedDateObj, true);
745             parseSelectedDate = ParseDate(selectedDateObj->GetProperty("value"));
746         } else {
747             parseSelectedDate = ParseDate(selectedDate);
748         }
749     }
750     DatePickerModel::GetInstance()->SetSelectedDate(parseSelectedDate);
751 
752     ParseDatePickerMode(mode);
753     SetDefaultAttributes();
754 }
755 
SetDefaultAttributes()756 void JSDatePicker::SetDefaultAttributes()
757 {
758     auto theme = GetTheme<PickerTheme>();
759     CHECK_NULL_VOID(theme);
760     NG::PickerTextStyle textStyle;
761     auto selectedStyle = theme->GetOptionStyle(true, false);
762     textStyle.fontSize = selectedStyle.GetFontSize();
763     textStyle.fontWeight = selectedStyle.GetFontWeight();
764     DatePickerModel::GetInstance()->SetSelectedTextStyle(theme, textStyle);
765 
766     auto disappearStyle = theme->GetDisappearOptionStyle();
767     textStyle.fontSize = disappearStyle.GetFontSize();
768     textStyle.fontWeight = disappearStyle.GetFontWeight();
769     DatePickerModel::GetInstance()->SetDisappearTextStyle(theme, textStyle);
770 
771     auto normalStyle = theme->GetOptionStyle(false, false);
772     textStyle.fontSize = normalStyle.GetFontSize();
773     textStyle.fontWeight = normalStyle.GetFontWeight();
774     DatePickerModel::GetInstance()->SetNormalTextStyle(theme, textStyle);
775 }
776 
ParseDatePickerMode(JSRef<JSVal> mode)777 void JSDatePicker::ParseDatePickerMode(JSRef<JSVal> mode)
778 {
779     auto datePickerMode = DatePickerMode::DATE;
780     if (!mode->IsNull() && mode->IsNumber()) {
781         auto parseMode = mode->ToNumber<int32_t>();
782         if (parseMode >= static_cast<int32_t>(DatePickerMode::DATE) &&
783             parseMode <= static_cast<int32_t>(DatePickerMode::MONTH_AND_DAY)) {
784             datePickerMode = static_cast<DatePickerMode>(parseMode);
785         }
786     }
787     DatePickerModel::GetInstance()->SetMode(datePickerMode);
788 }
789 
ParseStartEndDate(JSRef<JSVal> startDate,JSRef<JSVal> endDate)790 void JSDatePicker::ParseStartEndDate(JSRef<JSVal> startDate, JSRef<JSVal> endDate)
791 {
792     auto theme = GetTheme<PickerTheme>();
793     CHECK_NULL_VOID(theme);
794     auto parseStartDate = ParseDate(startDate);
795     auto parseEndDate = ParseDate(endDate);
796     if (parseStartDate.GetYear() <= 0) {
797         parseStartDate = theme->GetDefaultStartDate();
798     }
799     if (parseEndDate.GetYear() <= 0) {
800         parseEndDate = theme->GetDefaultEndDate();
801     }
802     auto startDays = parseStartDate.ToDays();
803     auto endDays = parseEndDate.ToDays();
804     if (startDays > endDays) {
805         parseStartDate = theme->GetDefaultStartDate();
806         parseEndDate = theme->GetDefaultEndDate();
807     }
808     DatePickerModel::GetInstance()->CreateDatePicker(theme);
809     if (startDate->IsObject()) {
810         DatePickerModel::GetInstance()->SetStartDate(parseStartDate);
811     }
812     if (endDate->IsObject()) {
813         DatePickerModel::GetInstance()->SetEndDate(parseEndDate);
814     }
815 }
816 
CreateTimePicker(const JSCallbackInfo & info,const JSRef<JSObject> & paramObj)817 void JSDatePicker::CreateTimePicker(const JSCallbackInfo& info, const JSRef<JSObject>& paramObj)
818 {
819     auto theme = GetTheme<PickerTheme>();
820     CHECK_NULL_VOID(theme);
821     DatePickerModel::GetInstance()->CreateTimePicker(theme);
822     auto selectedTime = paramObj->GetProperty("selected");
823     if (selectedTime->IsObject()) {
824         JSRef<JSObject> selectedTimeObj = JSRef<JSObject>::Cast(selectedTime);
825         JSRef<JSVal> changeEventVal = selectedTimeObj->GetProperty("changeEvent");
826         if (!changeEventVal->IsUndefined() && changeEventVal->IsFunction()) {
827             ParseSelectedDateTimeObject(info, selectedTimeObj, true);
828             auto parseSelectedTime = ParseTime(selectedTimeObj->GetProperty("value"));
829             DatePickerModel::GetInstance()->SetSelectedTime(parseSelectedTime);
830         } else {
831             DatePickerModel::GetInstance()->SetSelectedTime(ParseTime(selectedTime));
832         }
833     }
834 }
835 
JSBind(BindingTarget globalObj)836 void JSDatePickerDialog::JSBind(BindingTarget globalObj)
837 {
838     JSClass<JSDatePickerDialog>::Declare("DatePickerDialog");
839     JSClass<JSDatePickerDialog>::StaticMethod("show", &JSDatePickerDialog::Show);
840 
841     JSClass<JSDatePickerDialog>::Bind<>(globalObj);
842 }
843 
DatePickerDialogAppearEvent(const JSCallbackInfo & info,PickerDialogEvent & pickerDialogEvent)844 void DatePickerDialogAppearEvent(const JSCallbackInfo& info, PickerDialogEvent& pickerDialogEvent)
845 {
846     std::function<void()> didAppearEvent;
847     std::function<void()> willAppearEvent;
848     if (info.Length() == 0 || !info[0]->IsObject()) {
849         return;
850     }
851     auto paramObject = JSRef<JSObject>::Cast(info[0]);
852     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
853     auto onDidAppear = paramObject->GetProperty("onDidAppear");
854     if (!onDidAppear->IsUndefined() && onDidAppear->IsFunction()) {
855         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidAppear));
856         didAppearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode]() {
857             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
858             ACE_SCORING_EVENT("DatePickerDialog.onDidAppear");
859             PipelineContext::SetCallBackNode(node);
860             func->Execute();
861         };
862     }
863     auto onWillAppear = paramObject->GetProperty("onWillAppear");
864     if (!onWillAppear->IsUndefined() && onWillAppear->IsFunction()) {
865         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillAppear));
866         willAppearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode]() {
867             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
868             ACE_SCORING_EVENT("DatePickerDialog.onWillAppear");
869             PipelineContext::SetCallBackNode(node);
870             func->Execute();
871         };
872     }
873     pickerDialogEvent.onDidAppear = std::move(didAppearEvent);
874     pickerDialogEvent.onWillAppear = std::move(willAppearEvent);
875 }
876 
DatePickerDialogDisappearEvent(const JSCallbackInfo & info,PickerDialogEvent & pickerDialogEvent)877 void DatePickerDialogDisappearEvent(const JSCallbackInfo& info, PickerDialogEvent& pickerDialogEvent)
878 {
879     std::function<void()> didDisappearEvent;
880     std::function<void()> willDisappearEvent;
881     if (info.Length() == 0 || !info[0]->IsObject()) {
882         return;
883     }
884     auto paramObject = JSRef<JSObject>::Cast(info[0]);
885     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
886     auto onDidDisappear = paramObject->GetProperty("onDidDisappear");
887     if (!onDidDisappear->IsUndefined() && onDidDisappear->IsFunction()) {
888         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidDisappear));
889         didDisappearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode]() {
890             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
891             ACE_SCORING_EVENT("DatePickerDialog.onDidDisappear");
892             PipelineContext::SetCallBackNode(node);
893             func->Execute();
894         };
895     }
896     auto onWillDisappear = paramObject->GetProperty("onWillDisappear");
897     if (!onWillDisappear->IsUndefined() && onWillDisappear->IsFunction()) {
898         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDisappear));
899         willDisappearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode]() {
900             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
901             ACE_SCORING_EVENT("DatePickerDialog.onWillDisappear");
902             PipelineContext::SetCallBackNode(node);
903             func->Execute();
904         };
905     }
906     pickerDialogEvent.onDidDisappear = std::move(didDisappearEvent);
907     pickerDialogEvent.onWillDisappear = std::move(willDisappearEvent);
908 }
909 
GetDateChangeEvent(const JSRef<JSObject> & paramObject,const JSCallbackInfo & info,const DatePickerType & pickerType,const WeakPtr<NG::FrameNode> & frameNode)910 std::function<void(const std::string&)> JSDatePickerDialog::GetDateChangeEvent(const JSRef<JSObject>& paramObject,
911     const JSCallbackInfo& info, const DatePickerType& pickerType, const WeakPtr<NG::FrameNode>& frameNode)
912 {
913     std::function<void(const std::string&)> dateChangeEvent;
914     auto onDateChange = paramObject->GetProperty("onDateChange");
915     if (!onDateChange->IsUndefined() && onDateChange->IsFunction()) {
916         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDateChange));
917         dateChangeEvent = [execCtx = info.GetExecutionContext(), type = pickerType, func = std::move(jsFunc),
918                               node = frameNode](const std::string& info) {
919             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
920             ACE_SCORING_EVENT("DatePickerDialog.onDateChange");
921             auto selectedJson = JsonUtil::ParseJsonString(info);
922             if (!selectedJson || selectedJson->IsNull()) {
923                 return;
924             }
925             auto dateObj = GetDateObj(selectedJson);
926             PipelineContext::SetCallBackNode(node);
927             func->ExecuteJS(1, &dateObj);
928         };
929     }
930     return dateChangeEvent;
931 }
932 
GetDateAcceptEvent(const JSRef<JSObject> & paramObject,const JSCallbackInfo & info,const DatePickerType & pickerType,const WeakPtr<NG::FrameNode> & frameNode)933 std::function<void(const std::string&)> JSDatePickerDialog::GetDateAcceptEvent(const JSRef<JSObject>& paramObject,
934     const JSCallbackInfo& info, const DatePickerType& pickerType, const WeakPtr<NG::FrameNode>& frameNode)
935 {
936     std::function<void(const std::string&)> dateAcceptEvent;
937     auto onDateAccept = paramObject->GetProperty("onDateAccept");
938     if (!onDateAccept->IsUndefined() && onDateAccept->IsFunction()) {
939         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDateAccept));
940         dateAcceptEvent = [execCtx = info.GetExecutionContext(), type = pickerType, func = std::move(jsFunc),
941                               node = frameNode](const std::string& info) {
942             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
943             ACE_SCORING_EVENT("DatePickerDialog.onDateAccept");
944             auto selectedJson = JsonUtil::ParseJsonString(info);
945             if (!selectedJson || selectedJson->IsNull()) {
946                 return;
947             }
948             auto dateObj = GetDateObj(selectedJson);
949             PipelineContext::SetCallBackNode(node);
950             func->ExecuteJS(1, &dateObj);
951         };
952     }
953     return dateAcceptEvent;
954 }
955 
GetDateObj(const std::unique_ptr<JsonValue> & selectedJson,bool isDatePicker)956 JsiRef<JsiValue> JSDatePickerDialog::GetDateObj(const std::unique_ptr<JsonValue>& selectedJson, bool isDatePicker)
957 {
958     std::tm dateTime {};
959     auto year = selectedJson->GetValue("year");
960     if (year && year->IsNumber()) {
961         dateTime.tm_year = year->GetInt() - 1900; // local date start from 1900
962     }
963     auto month = selectedJson->GetValue("month");
964     if (month && month->IsNumber()) {
965         dateTime.tm_mon = month->GetInt();
966     }
967     auto day = selectedJson->GetValue("day");
968     if (day && day->IsNumber()) {
969         dateTime.tm_mday = day->GetInt();
970     }
971     auto hour = selectedJson->GetValue("hour");
972     if (hour && hour->IsNumber()) {
973         dateTime.tm_hour = hour->GetInt();
974     }
975     auto minute = selectedJson->GetValue("minute");
976     if (minute && minute->IsNumber()) {
977         dateTime.tm_min = minute->GetInt();
978     }
979     auto second = selectedJson->GetValue("second");
980     if (second && second->IsNumber()) {
981         dateTime.tm_sec = second->GetInt();
982     }
983 
984     dateTime.tm_isdst = -1; // Auto considering daylight saving time
985     if (!isDatePicker) {
986         auto milliseconds = Date::GetMilliSecondsByDateTime(dateTime);
987         auto dateObj = JSDate::New(milliseconds);
988         return dateObj;
989     }
990 
991     auto timestamp = std::chrono::system_clock::from_time_t(std::mktime(&dateTime));
992     auto duration = timestamp.time_since_epoch();
993     auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
994     auto dateObj = JSDate::New(milliseconds);
995     return dateObj;
996 }
997 
GetChangeEvent(const JSRef<JSObject> & paramObject,const JSCallbackInfo & info,const DatePickerType & pickerType,const WeakPtr<NG::FrameNode> & frameNode)998 std::function<void(const std::string&)> JSDatePickerDialog::GetChangeEvent(const JSRef<JSObject>& paramObject,
999     const JSCallbackInfo& info, const DatePickerType& pickerType, const WeakPtr<NG::FrameNode>& frameNode)
1000 {
1001     std::function<void(const std::string&)> changeEvent;
1002     auto onChange = paramObject->GetProperty("onChange");
1003     if (!onChange->IsUndefined() && onChange->IsFunction()) {
1004         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onChange));
1005         changeEvent = [execCtx = info.GetExecutionContext(), type = pickerType, func = std::move(jsFunc),
1006                           node = frameNode](const std::string& info) {
1007             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1008             std::vector<std::string> keys;
1009             keys = { "year", "month", "day" };
1010             ACE_SCORING_EVENT("DatePickerDialog.onChange");
1011             PipelineContext::SetCallBackNode(node);
1012             func->Execute(keys, info);
1013         };
1014     }
1015     return changeEvent;
1016 }
1017 
GetAcceptEvent(const JSRef<JSObject> & paramObject,const JSCallbackInfo & info,const WeakPtr<NG::FrameNode> & frameNode)1018 std::function<void(const std::string&)> JSDatePickerDialog::GetAcceptEvent(
1019     const JSRef<JSObject>& paramObject, const JSCallbackInfo& info, const WeakPtr<NG::FrameNode>& frameNode)
1020 {
1021     std::function<void(const std::string&)> acceptEvent;
1022     auto onAccept = paramObject->GetProperty("onAccept");
1023     if (!onAccept->IsUndefined() && onAccept->IsFunction()) {
1024         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAccept));
1025         acceptEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
1026                           const std::string& info) {
1027             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1028             std::vector<std::string> keys = { "year", "month", "day", "hour", "minute", "second" };
1029             ACE_SCORING_EVENT("DatePickerDialog.onAccept");
1030             PipelineContext::SetCallBackNode(node);
1031             func->Execute(keys, info);
1032         };
1033     }
1034     return acceptEvent;
1035 }
1036 
GetCancelEvent(const JSRef<JSObject> & paramObject,const JSCallbackInfo & info,const WeakPtr<NG::FrameNode> & frameNode)1037 std::function<void()> JSDatePickerDialog::GetCancelEvent(
1038     const JSRef<JSObject>& paramObject, const JSCallbackInfo& info, const WeakPtr<NG::FrameNode>& frameNode)
1039 {
1040     std::function<void()> cancelEvent;
1041     auto onCancel = paramObject->GetProperty("onCancel");
1042     if (!onCancel->IsUndefined() && onCancel->IsFunction()) {
1043         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onCancel));
1044         cancelEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode]() {
1045             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1046             ACE_SCORING_EVENT("DatePickerDialog.onCancel");
1047             PipelineContext::SetCallBackNode(node);
1048             func->Execute();
1049         };
1050     }
1051     return cancelEvent;
1052 }
1053 
UpdateLunarSwitchSettingData(const JSRef<JSObject> & paramObject,NG::DatePickerSettingData & settingData)1054 void JSDatePickerDialog::UpdateLunarSwitchSettingData(
1055     const JSRef<JSObject>& paramObject, NG::DatePickerSettingData& settingData)
1056 {
1057     auto selectedColorValue = paramObject->GetProperty("selectedColor");
1058     auto unselectedColorValue = paramObject->GetProperty("unselectedColor");
1059     auto strokeColorValue = paramObject->GetProperty("strokeColor");
1060     Color selectedColor;
1061     if (JSViewAbstract::ParseJsColor(selectedColorValue, selectedColor)) {
1062         settingData.checkboxSettingData.selectedColor = selectedColor;
1063     }
1064     Color unselectedColor;
1065     if (JSViewAbstract::ParseJsColor(unselectedColorValue, unselectedColor)) {
1066         settingData.checkboxSettingData.unselectedColor = unselectedColor;
1067     }
1068     Color strokeColor;
1069     if (JSViewAbstract::ParseJsColor(strokeColorValue, strokeColor)) {
1070         settingData.checkboxSettingData.strokeColor = strokeColor;
1071     }
1072 }
1073 
UpdateDatePickerSettingData(const JSRef<JSObject> & paramObject,NG::DatePickerSettingData & settingData)1074 void JSDatePickerDialog::UpdateDatePickerSettingData(
1075     const JSRef<JSObject>& paramObject, NG::DatePickerSettingData& settingData)
1076 {
1077     auto lunar = paramObject->GetProperty("lunar");
1078     auto lunarSwitch = paramObject->GetProperty("lunarSwitch");
1079     auto sTime = paramObject->GetProperty("showTime");
1080     auto useMilitary = paramObject->GetProperty("useMilitaryTime");
1081     settingData.isLunar = lunar->ToBoolean();
1082     settingData.lunarswitch = lunarSwitch->ToBoolean();
1083     if (settingData.lunarswitch) {
1084         auto lunarSwitchStyle = paramObject->GetProperty("lunarSwitchStyle");
1085         if ((!lunarSwitchStyle->IsUndefined()) && lunarSwitchStyle->IsObject()) {
1086             auto style = JSRef<JSObject>::Cast(lunarSwitchStyle);
1087             UpdateLunarSwitchSettingData(style, settingData);
1088         }
1089     }
1090     auto enableHapticFeedbackValue = paramObject->GetProperty("enableHapticFeedback");
1091     if (enableHapticFeedbackValue->IsBoolean()) {
1092         settingData.isEnableHapticFeedback = enableHapticFeedbackValue->ToBoolean();
1093     }
1094     settingData.showTime = sTime->ToBoolean();
1095     settingData.useMilitary = useMilitary->ToBoolean();
1096 
1097     auto mode = paramObject->GetProperty("mode");
1098     auto datePickerMode = DatePickerMode::DATE;
1099     if (!mode->IsNull() && mode->IsNumber()) {
1100         auto parseMode = mode->ToNumber<int32_t>();
1101         if (parseMode >= static_cast<int32_t>(DatePickerMode::DATE) &&
1102             parseMode <= static_cast<int32_t>(DatePickerMode::MONTH_AND_DAY)) {
1103             datePickerMode = static_cast<DatePickerMode>(parseMode);
1104         }
1105     }
1106     settingData.mode = datePickerMode;
1107     auto isLoop = paramObject->GetProperty("canLoop");
1108     if (isLoop->IsBoolean()) {
1109         settingData.canLoop = isLoop->ToBoolean();
1110     } else {
1111         settingData.canLoop = true;
1112     }
1113 
1114     auto dateTimeOptionsValue = paramObject->GetProperty("dateTimeOptions");
1115     if (dateTimeOptionsValue->IsObject()) {
1116         auto dateTimeOptionsObj = JSRef<JSObject>::Cast(dateTimeOptionsValue);
1117         JSDatePickerDialog::ParseDateTimeOptions(dateTimeOptionsObj, settingData.dateTimeOptions);
1118     }
1119     JSDatePicker::ParseTextProperties(paramObject, settingData.properties);
1120 }
1121 
UpdatePickerDialogTimeInfo(const JSRef<JSObject> & paramObject,PickerDialogInfo & pickerDialog)1122 void JSDatePickerDialog::UpdatePickerDialogTimeInfo(const JSRef<JSObject>& paramObject, PickerDialogInfo& pickerDialog)
1123 {
1124     auto theme = GetTheme<PickerTheme>();
1125     CHECK_NULL_VOID(theme);
1126 
1127     auto startDate = paramObject->GetProperty("start");
1128     if (startDate->IsObject()) {
1129         pickerDialog.isStartDate = true;
1130     }
1131     auto endDate = paramObject->GetProperty("end");
1132     if (endDate->IsObject()) {
1133         pickerDialog.isEndDate = true;
1134     }
1135     auto selectedDate = paramObject->GetProperty("selected");
1136     if (selectedDate->IsObject()) {
1137         pickerDialog.isSelectedDate = true;
1138     }
1139     auto parseStartDate = ParseDate(startDate);
1140     auto parseEndDate = ParseDate(endDate);
1141     if (parseStartDate.GetYear() <= 0) {
1142         parseStartDate = theme->GetDefaultStartDate();
1143     }
1144     if (parseEndDate.GetYear() <= 0) {
1145         parseEndDate = theme->GetDefaultEndDate();
1146     }
1147     auto startDays = parseStartDate.ToDays();
1148     auto endDays = parseEndDate.ToDays();
1149     if (startDays > endDays) {
1150         parseStartDate = theme->GetDefaultStartDate();
1151         parseEndDate = theme->GetDefaultEndDate();
1152     }
1153     pickerDialog.parseStartDate = parseStartDate;
1154     pickerDialog.parseEndDate = parseEndDate;
1155     pickerDialog.parseSelectedDate = ParseDate(selectedDate);
1156     pickerDialog.pickerTime = ParseTime(selectedDate);
1157 }
1158 
UpdatePickerDialogPositionInfo(const JSRef<JSObject> & paramObject,PickerDialogInfo & pickerDialog)1159 void JSDatePickerDialog::UpdatePickerDialogPositionInfo(
1160     const JSRef<JSObject>& paramObject, PickerDialogInfo& pickerDialog)
1161 {
1162     // Parse alignment
1163     auto alignmentValue = paramObject->GetProperty("alignment");
1164     if (alignmentValue->IsNumber()) {
1165         auto alignment = alignmentValue->ToNumber<int32_t>();
1166         if (alignment >= 0 && alignment < static_cast<int32_t>(DIALOG_ALIGNMENT.size())) {
1167             pickerDialog.alignment = DIALOG_ALIGNMENT[alignment];
1168         }
1169         if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1170             if (alignment == static_cast<int32_t>(DialogAlignment::TOP) ||
1171                 alignment == static_cast<int32_t>(DialogAlignment::TOP_START) ||
1172                 alignment == static_cast<int32_t>(DialogAlignment::TOP_END)) {
1173                 pickerDialog.offset = DATEPICKER_OFFSET_DEFAULT_TOP;
1174             }
1175         }
1176     }
1177 
1178     // Parse offset
1179     auto offsetValue = paramObject->GetProperty("offset");
1180     if (offsetValue->IsObject()) {
1181         auto offsetObj = JSRef<JSObject>::Cast(offsetValue);
1182         CalcDimension dx;
1183         auto dxValue = offsetObj->GetProperty("dx");
1184         ParseJsDimensionVp(dxValue, dx);
1185         CalcDimension dy;
1186         auto dyValue = offsetObj->GetProperty("dy");
1187         ParseJsDimensionVp(dyValue, dy);
1188         pickerDialog.offset = DimensionOffset(dx, dy);
1189     }
1190 }
1191 
UpdatePickerDialogInfo(const JSRef<JSObject> & paramObject,PickerDialogInfo & pickerDialog)1192 void JSDatePickerDialog::UpdatePickerDialogInfo(const JSRef<JSObject>& paramObject, PickerDialogInfo& pickerDialog)
1193 {
1194     UpdatePickerDialogTimeInfo(paramObject, pickerDialog);
1195     UpdatePickerDialogPositionInfo(paramObject, pickerDialog);
1196     // Parse maskRect.
1197     auto maskRectValue = paramObject->GetProperty("maskRect");
1198     DimensionRect maskRect;
1199     if (JSViewAbstract::ParseJsDimensionRect(maskRectValue, maskRect)) {
1200         pickerDialog.maskRect = maskRect;
1201     }
1202 
1203     auto backgroundColorValue = paramObject->GetProperty("backgroundColor");
1204     Color backgroundColor;
1205     if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor)) {
1206         pickerDialog.backgroundColor = backgroundColor;
1207     }
1208 
1209     auto backgroundBlurStyle = paramObject->GetProperty("backgroundBlurStyle");
1210     if (backgroundBlurStyle->IsNumber()) {
1211         auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>();
1212         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
1213             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
1214             pickerDialog.backgroundBlurStyle = blurStyle;
1215         }
1216     }
1217 
1218     auto shadowValue = paramObject->GetProperty("shadow");
1219     Shadow shadow;
1220     if ((shadowValue->IsObject() || shadowValue->IsNumber()) && JSViewAbstract::ParseShadowProps(shadowValue, shadow)) {
1221         pickerDialog.shadow = shadow;
1222     }
1223 
1224     ParseDatePickerHoverMode(pickerDialog, paramObject);
1225     ParseDatePickerBlurStyleOption(pickerDialog, paramObject);
1226     ParseDatePickerEffectOption(pickerDialog, paramObject);
1227 }
1228 
Show(const JSCallbackInfo & info)1229 void JSDatePickerDialog::Show(const JSCallbackInfo& info)
1230 {
1231     auto scopedDelegate = EngineHelper::GetCurrentDelegateSafely();
1232     CHECK_NULL_VOID(scopedDelegate);
1233     if (!info[0]->IsObject()) {
1234         return;
1235     }
1236 
1237     auto paramObject = info[0]->IsEmpty() ? (JSRef<JSObject>::New()) : JSRef<JSObject>::Cast(info[0]);
1238     DatePickerType pickerType = DatePickerType::DATE;
1239     auto type = paramObject->GetProperty("type");
1240     if (type->IsNumber()) {
1241         pickerType = static_cast<DatePickerType>(type->ToNumber<int32_t>());
1242     }
1243     std::function<void()> cancelEvent;
1244     std::function<void(const std::string&)> acceptEvent;
1245     std::function<void(const std::string&)> changeEvent;
1246     std::function<void(const std::string&)> dateChangeEvent;
1247     std::function<void(const std::string&)> dateAcceptEvent;
1248     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1249     changeEvent = GetChangeEvent(paramObject, info, pickerType, frameNode);
1250     acceptEvent = GetAcceptEvent(paramObject, info, frameNode);
1251     cancelEvent = GetCancelEvent(paramObject, info, frameNode);
1252     dateChangeEvent = GetDateChangeEvent(paramObject, info, pickerType, frameNode);
1253     dateAcceptEvent = GetDateAcceptEvent(paramObject, info, pickerType, frameNode);
1254     NG::DatePickerSettingData settingData;
1255     UpdateDatePickerSettingData(paramObject, settingData);
1256     PickerDialogInfo pickerDialog;
1257     UpdatePickerDialogInfo(paramObject, pickerDialog);
1258 
1259     auto buttonInfos = ParseButtonStyles(paramObject);
1260     PickerDialogEvent pickerDialogEvent { nullptr, nullptr, nullptr, nullptr };
1261     DatePickerDialogAppearEvent(info, pickerDialogEvent);
1262     DatePickerDialogDisappearEvent(info, pickerDialogEvent);
1263     DatePickerDialogModel::GetInstance()->SetDatePickerDialogShow(pickerDialog, settingData, std::move(cancelEvent),
1264         std::move(acceptEvent), std::move(changeEvent), std::move(dateAcceptEvent), std::move(dateChangeEvent),
1265         pickerType, pickerDialogEvent, buttonInfos);
1266 }
1267 
DatePickerDialogShow(const JSRef<JSObject> & paramObj,const std::map<std::string,NG::DialogEvent> & dialogEvent,const std::map<std::string,NG::DialogGestureEvent> & dialogCancelEvent)1268 void JSDatePickerDialog::DatePickerDialogShow(const JSRef<JSObject>& paramObj,
1269     const std::map<std::string, NG::DialogEvent>& dialogEvent,
1270     const std::map<std::string, NG::DialogGestureEvent>& dialogCancelEvent)
1271 {
1272     auto container = Container::CurrentSafely();
1273     if (!container) {
1274         return;
1275     }
1276     auto pipelineContext = AccessibilityManager::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
1277     if (!pipelineContext) {
1278         return;
1279     }
1280 
1281     auto executor = pipelineContext->GetTaskExecutor();
1282     if (!executor) {
1283         return;
1284     }
1285 
1286     NG::DatePickerSettingData settingData;
1287     auto startDate = paramObj->GetProperty("start");
1288     auto endDate = paramObj->GetProperty("end");
1289     auto selectedDate = paramObj->GetProperty("selected");
1290     auto lunar = paramObj->GetProperty("lunar");
1291     auto sTime = paramObj->GetProperty("showTime");
1292     auto useMilitary = paramObj->GetProperty("useMilitaryTime");
1293     settingData.isLunar = lunar->ToBoolean();
1294     settingData.showTime = sTime->ToBoolean();
1295     settingData.useMilitary = useMilitary->ToBoolean();
1296     auto parseStartDate = ParseDate(startDate);
1297     auto parseEndDate = ParseDate(endDate);
1298     auto parseSelectedDate = ParseDate(selectedDate);
1299 
1300     auto theme = GetTheme<DialogTheme>();
1301     CHECK_NULL_VOID(theme);
1302 
1303     DialogProperties properties;
1304     properties.alignment = theme->GetAlignment();
1305     if (properties.alignment == DialogAlignment::BOTTOM &&
1306         Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_ELEVEN)) {
1307         properties.offset = DimensionOffset(Offset(0, -theme->GetMarginBottom().ConvertToPx()));
1308     }
1309     properties.customStyle = false;
1310     if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1311         properties.offset = DimensionOffset(Offset(0, -theme->GetMarginBottom().ConvertToPx()));
1312     }
1313 
1314     std::map<std::string, PickerDate> datePickerProperty;
1315     std::map<std::string, PickerTime> timePickerProperty;
1316     if (startDate->IsObject()) {
1317         settingData.datePickerProperty["start"] = parseStartDate;
1318     }
1319     if (endDate->IsObject()) {
1320         settingData.datePickerProperty["end"] = parseEndDate;
1321     }
1322     if (selectedDate->IsObject()) {
1323         settingData.datePickerProperty["selected"] = parseSelectedDate;
1324         settingData.timePickerProperty["selected"] = ParseTime(selectedDate);
1325     }
1326     auto enableHapticFeedbackValue = paramObj->GetProperty("enableHapticFeedback");
1327     if (enableHapticFeedbackValue->IsBoolean()) {
1328         settingData.isEnableHapticFeedback = enableHapticFeedbackValue->ToBoolean();
1329     }
1330 
1331     JSDatePicker::ParseTextProperties(paramObj, settingData.properties);
1332     auto context = AccessibilityManager::DynamicCast<NG::PipelineContext>(pipelineContext);
1333     auto overlayManager = context ? context->GetOverlayManager() : nullptr;
1334     executor->PostTask(
1335         [properties, settingData, dialogEvent, dialogCancelEvent, weak = WeakPtr<NG::OverlayManager>(overlayManager)] {
1336             auto overlayManager = weak.Upgrade();
1337             CHECK_NULL_VOID(overlayManager);
1338             overlayManager->ShowDateDialog(properties, settingData, dialogEvent, dialogCancelEvent);
1339         },
1340         TaskExecutor::TaskType::UI, "ArkUIDialogShowDatePicker",
1341         TaskExecutor::GetPriorityTypeWithCheck(PriorityType::VIP));
1342 }
1343 
CreateDatePicker(RefPtr<Component> & component,const JSRef<JSObject> & paramObj)1344 void JSDatePickerDialog::CreateDatePicker(RefPtr<Component>& component, const JSRef<JSObject>& paramObj)
1345 {
1346     auto datePicker = AceType::MakeRefPtr<PickerDateComponent>();
1347     auto startDate = paramObj->GetProperty("start");
1348     auto endDate = paramObj->GetProperty("end");
1349     auto selectedDate = paramObj->GetProperty("selected");
1350     auto lunar = paramObj->GetProperty("lunar");
1351     bool isLunar = lunar->ToBoolean();
1352     auto parseStartDate = ParseDate(startDate);
1353     auto parseEndDate = ParseDate(endDate);
1354     auto parseSelectedDate = ParseDate(selectedDate);
1355     auto startDays = parseStartDate.ToDays();
1356     auto endDays = parseEndDate.ToDays();
1357     if (startDays > endDays) {
1358         parseStartDate.SetYear(0);
1359         parseEndDate.SetYear(0);
1360     }
1361     if (startDate->IsObject()) {
1362         datePicker->SetStartDate(parseStartDate);
1363     }
1364     if (endDate->IsObject()) {
1365         datePicker->SetEndDate(parseEndDate);
1366     }
1367     if (selectedDate->IsObject()) {
1368         datePicker->SetSelectedDate(parseSelectedDate);
1369     }
1370     datePicker->SetIsDialog(true);
1371     datePicker->SetIsCreateDialogComponent(true);
1372     datePicker->SetShowLunar(isLunar);
1373 
1374     component = datePicker;
1375 }
1376 
CreateTimePicker(RefPtr<Component> & component,const JSRef<JSObject> & paramObj)1377 void JSDatePickerDialog::CreateTimePicker(RefPtr<Component>& component, const JSRef<JSObject>& paramObj)
1378 {
1379     auto timePicker = AceType::MakeRefPtr<PickerTimeComponent>();
1380     auto selectedTime = paramObj->GetProperty("selected");
1381     auto useMilitaryTime = paramObj->GetProperty("useMilitaryTime");
1382     bool isUseMilitaryTime = useMilitaryTime->ToBoolean();
1383     if (selectedTime->IsObject()) {
1384         timePicker->SetSelectedTime(ParseTime(selectedTime));
1385     }
1386     timePicker->SetIsDialog(true);
1387     timePicker->SetIsCreateDialogComponent(true);
1388     timePicker->SetHour24(isUseMilitaryTime);
1389     component = timePicker;
1390 }
1391 
ParseDate(const JSRef<JSVal> & dateVal)1392 PickerDate JSDatePickerDialog::ParseDate(const JSRef<JSVal>& dateVal)
1393 {
1394     auto pickerDate = PickerDate();
1395     if (!dateVal->IsObject()) {
1396         return pickerDate;
1397     }
1398     auto dateObj = JSRef<JSObject>::Cast(dateVal);
1399     auto yearFuncJsVal = dateObj->GetProperty("getFullYear");
1400     auto monthFuncJsVal = dateObj->GetProperty("getMonth");
1401     auto dateFuncJsVal = dateObj->GetProperty("getDate");
1402     if (!(yearFuncJsVal->IsFunction() && monthFuncJsVal->IsFunction() && dateFuncJsVal->IsFunction())) {
1403         return pickerDate;
1404     }
1405     auto yearFunc = JSRef<JSFunc>::Cast(yearFuncJsVal);
1406     auto monthFunc = JSRef<JSFunc>::Cast(monthFuncJsVal);
1407     auto dateFunc = JSRef<JSFunc>::Cast(dateFuncJsVal);
1408     JSRef<JSVal> year = yearFunc->Call(dateObj);
1409     JSRef<JSVal> month = monthFunc->Call(dateObj);
1410     JSRef<JSVal> date = dateFunc->Call(dateObj);
1411 
1412     if (year->IsNumber() && month->IsNumber() && date->IsNumber()) {
1413         pickerDate.SetYear(year->ToNumber<int32_t>());
1414         pickerDate.SetMonth(month->ToNumber<int32_t>() + 1); // 0-11 means 1 to 12 months
1415         pickerDate.SetDay(date->ToNumber<int32_t>());
1416     }
1417     return pickerDate;
1418 }
1419 
ParseTime(const JSRef<JSVal> & timeVal)1420 PickerTime JSDatePickerDialog::ParseTime(const JSRef<JSVal>& timeVal)
1421 {
1422     auto pickerTime = PickerTime();
1423     if (!timeVal->IsObject()) {
1424         return pickerTime;
1425     }
1426     auto timeObj = JSRef<JSObject>::Cast(timeVal);
1427     auto hourFuncJsVal = timeObj->GetProperty("getHours");
1428     auto minuteFuncJsVal = timeObj->GetProperty("getMinutes");
1429     auto secondFuncJsVal = timeObj->GetProperty("getSeconds");
1430     if (!(hourFuncJsVal->IsFunction() && minuteFuncJsVal->IsFunction() && secondFuncJsVal->IsFunction())) {
1431         return pickerTime;
1432     }
1433     auto hourFunc = JSRef<JSFunc>::Cast(hourFuncJsVal);
1434     auto minuteFunc = JSRef<JSFunc>::Cast(minuteFuncJsVal);
1435     auto secondFunc = JSRef<JSFunc>::Cast(secondFuncJsVal);
1436     JSRef<JSVal> hour = hourFunc->Call(timeObj);
1437     JSRef<JSVal> minute = minuteFunc->Call(timeObj);
1438     JSRef<JSVal> second = secondFunc->Call(timeObj);
1439 
1440     if (hour->IsNumber() && minute->IsNumber() && second->IsNumber()) {
1441         pickerTime.SetHour(hour->ToNumber<int32_t>());
1442         pickerTime.SetMinute(minute->ToNumber<int32_t>());
1443         pickerTime.SetSecond(second->ToNumber<int32_t>());
1444     }
1445     return pickerTime;
1446 }
1447 
ParseDateTimeOptions(const JSRef<JSObject> & paramObj,DateTimeType & dateTimeOptions)1448 void JSDatePickerDialog::ParseDateTimeOptions(const JSRef<JSObject>& paramObj, DateTimeType& dateTimeOptions)
1449 {
1450     dateTimeOptions.hourType = ZeroPrefixType::AUTO;
1451     dateTimeOptions.minuteType = ZeroPrefixType::AUTO;
1452     dateTimeOptions.secondType = ZeroPrefixType::AUTO;
1453 
1454     auto hourValue = paramObj->GetProperty(TIMEPICKER_OPTIONS_HOUR);
1455     if (hourValue->IsString()) {
1456         std::string hour = hourValue->ToString();
1457         if (hour == TIMEPICKER_OPTIONS_TWO_DIGIT_VAL) {
1458             dateTimeOptions.hourType = ZeroPrefixType::SHOW;
1459         } else if (hour == TIMEPICKER_OPTIONS_NUMERIC_VAL) {
1460             dateTimeOptions.hourType = ZeroPrefixType::HIDE;
1461         }
1462     }
1463     auto minuteValue = paramObj->GetProperty(TIMEPICKER_OPTIONS_MINUTE);
1464     if (minuteValue->IsString()) {
1465         dateTimeOptions.minuteType = ZeroPrefixType::SHOW;
1466         std::string minute = minuteValue->ToString();
1467         if (minute == TIMEPICKER_OPTIONS_NUMERIC_VAL) {
1468             dateTimeOptions.minuteType = ZeroPrefixType::HIDE;
1469         }
1470     }
1471 }
1472 
JSBind(BindingTarget globalObj)1473 void JSTimePicker::JSBind(BindingTarget globalObj)
1474 {
1475     JSClass<JSTimePicker>::Declare("TimePicker");
1476     MethodOptions opt = MethodOptions::NONE;
1477     JSClass<JSTimePicker>::StaticMethod("create", &JSTimePicker::Create, opt);
1478     JSClass<JSTimePicker>::StaticMethod("onChange", &JSTimePicker::OnChange);
1479     JSClass<JSTimePicker>::StaticMethod("backgroundColor", &JSTimePicker::PickerBackgroundColor);
1480     JSClass<JSTimePicker>::StaticMethod("loop", &JSTimePicker::Loop);
1481     JSClass<JSTimePicker>::StaticMethod("useMilitaryTime", &JSTimePicker::UseMilitaryTime);
1482     JSClass<JSTimePicker>::StaticMethod("enableHapticFeedback", &JSTimePicker::EnableHapticFeedback);
1483     JSClass<JSTimePicker>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
1484     JSClass<JSTimePicker>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
1485     JSClass<JSTimePicker>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
1486     JSClass<JSTimePicker>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
1487     JSClass<JSTimePicker>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
1488     JSClass<JSTimePicker>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
1489     JSClass<JSTimePicker>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
1490     JSClass<JSTimePicker>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
1491     JSClass<JSTimePicker>::StaticMethod("disappearTextStyle", &JSTimePicker::SetDisappearTextStyle);
1492     JSClass<JSTimePicker>::StaticMethod("textStyle", &JSTimePicker::SetTextStyle);
1493     JSClass<JSTimePicker>::StaticMethod("selectedTextStyle", &JSTimePicker::SetSelectedTextStyle);
1494     JSClass<JSTimePicker>::StaticMethod("dateTimeOptions", &JSTimePicker::DateTimeOptions);
1495     JSClass<JSTimePicker>::StaticMethod("opacity", &JSTimePicker::JsOpacity);
1496     JSClass<JSTimePicker>::StaticMethod("enableCascade", &JSTimePicker::EnableCascade);
1497     JSClass<JSTimePicker>::StaticMethod("onEnterSelectedArea", &JSTimePicker::OnEnterSelectedArea);
1498     JSClass<JSTimePicker>::StaticMethod("digitalCrownSensitivity", &JSTimePicker::SetDigitalCrownSensitivity);
1499     JSClass<JSTimePicker>::InheritAndBind<JSViewAbstract>(globalObj);
1500 }
1501 
SetDigitalCrownSensitivity(const JSCallbackInfo & info)1502 void JSTimePicker::SetDigitalCrownSensitivity(const JSCallbackInfo& info)
1503 {
1504     int32_t value = OHOS::Ace::NG::DEFAULT_CROWNSENSITIVITY;
1505     if (info[0]->IsNumber()) {
1506         value = info[0]->ToNumber<int32_t>();
1507     }
1508     TimePickerModel::GetInstance()->SetDigitalCrownSensitivity(value);
1509 }
1510 
Create(const JSCallbackInfo & info)1511 void JSTimePicker::Create(const JSCallbackInfo& info)
1512 {
1513     JSRef<JSObject> paramObject = JSRef<JSObject>::New();
1514     if (info.Length() >= 1 && info[0]->IsObject()) {
1515         paramObject = JSRef<JSObject>::Cast(info[0]);
1516     }
1517     CreateTimePicker(info, paramObject);
1518 }
1519 
JsOpacity(const JSCallbackInfo & info)1520 void JSTimePicker::JsOpacity(const JSCallbackInfo& info)
1521 {
1522     JSViewAbstract::JsOpacity(info);
1523     TimePickerModel::GetInstance()->HasUserDefinedOpacity();
1524 }
1525 
Loop(const JSCallbackInfo & info)1526 void JSTimePicker::Loop(const JSCallbackInfo& info)
1527 {
1528     bool isLoop = true;
1529     if (info[0]->IsBoolean()) {
1530         isLoop = info[0]->ToBoolean();
1531     }
1532     TimePickerModel::GetInstance()->SetWheelModeEnabled(isLoop);
1533 }
1534 
EnableHapticFeedback(const JSCallbackInfo & info)1535 void JSTimePicker::EnableHapticFeedback(const JSCallbackInfo& info)
1536 {
1537     bool isEnableHapticFeedback = true;
1538     if (info[0]->IsBoolean()) {
1539         isEnableHapticFeedback = info[0]->ToBoolean();
1540     }
1541     TimePickerModel::GetInstance()->SetIsEnableHapticFeedback(isEnableHapticFeedback);
1542 }
1543 
UseMilitaryTime(bool isUseMilitaryTime)1544 void JSTimePicker::UseMilitaryTime(bool isUseMilitaryTime)
1545 {
1546     TimePickerModel::GetInstance()->SetHour24(isUseMilitaryTime);
1547 }
1548 
EnableCascade(const JSCallbackInfo & info)1549 void JSTimePicker::EnableCascade(const JSCallbackInfo& info)
1550 {
1551     bool isEnableCascade = false;
1552     if (info[0]->IsBoolean()) {
1553         isEnableCascade = info[0]->ToBoolean();
1554     }
1555     TimePickerModel::GetInstance()->SetEnableCascade(isEnableCascade);
1556 }
1557 
DateTimeOptions(const JSCallbackInfo & info)1558 void JSTimePicker::DateTimeOptions(const JSCallbackInfo& info)
1559 {
1560     JSRef<JSObject> paramObject;
1561     ZeroPrefixType hourType = ZeroPrefixType::AUTO;
1562     ZeroPrefixType minuteType = ZeroPrefixType::AUTO;
1563     ZeroPrefixType secondType = ZeroPrefixType::AUTO;
1564     if (info.Length() >= 1 && info[0]->IsObject()) {
1565         paramObject = JSRef<JSObject>::Cast(info[0]);
1566         auto hourValue = paramObject->GetProperty(TIMEPICKER_OPTIONS_HOUR);
1567         if (hourValue->IsString()) {
1568             std::string hour = hourValue->ToString();
1569             if (hour == TIMEPICKER_OPTIONS_TWO_DIGIT_VAL) {
1570                 hourType = ZeroPrefixType::SHOW;
1571             } else if (hour == TIMEPICKER_OPTIONS_NUMERIC_VAL) {
1572                 hourType = ZeroPrefixType::HIDE;
1573             }
1574         }
1575         auto minuteValue = paramObject->GetProperty(TIMEPICKER_OPTIONS_MINUTE);
1576         if (minuteValue->IsString()) {
1577             minuteType = ZeroPrefixType::SHOW;
1578             std::string minute = minuteValue->ToString();
1579             if (minute == TIMEPICKER_OPTIONS_NUMERIC_VAL) {
1580                 minuteType = ZeroPrefixType::HIDE;
1581             }
1582         }
1583         auto secondValue = paramObject->GetProperty(TIMEPICKER_OPTIONS_SECOND);
1584         if (secondValue->IsString()) {
1585             secondType = ZeroPrefixType::SHOW;
1586             std::string second = secondValue->ToString();
1587             if (second == TIMEPICKER_OPTIONS_NUMERIC_VAL) {
1588                 secondType = ZeroPrefixType::HIDE;
1589             }
1590         }
1591     }
1592     TimePickerModel::GetInstance()->SetDateTimeOptions(hourType, minuteType, secondType);
1593 }
1594 
PickerBackgroundColor(const JSCallbackInfo & info)1595 void JSTimePicker::PickerBackgroundColor(const JSCallbackInfo& info)
1596 {
1597     JSViewAbstract::JsBackgroundColor(info);
1598 
1599     if (info.Length() < 1) {
1600         return;
1601     }
1602     Color backgroundColor;
1603     if (!ParseJsColor(info[0], backgroundColor)) {
1604         return;
1605     }
1606     TimePickerModel::GetInstance()->SetBackgroundColor(backgroundColor);
1607 }
1608 
SetDisappearTextStyle(const JSCallbackInfo & info)1609 void JSTimePicker::SetDisappearTextStyle(const JSCallbackInfo& info)
1610 {
1611     auto theme = GetTheme<PickerTheme>();
1612     CHECK_NULL_VOID(theme);
1613     NG::PickerTextStyle textStyle;
1614     if (info[0]->IsObject()) {
1615         JSDatePicker::ParseTextStyle(info[0], textStyle, "disappearTextStyleTime");
1616     }
1617     TimePickerModel::GetInstance()->SetDisappearTextStyle(theme, textStyle);
1618 }
1619 
SetTextStyle(const JSCallbackInfo & info)1620 void JSTimePicker::SetTextStyle(const JSCallbackInfo& info)
1621 {
1622     auto theme = GetTheme<PickerTheme>();
1623     CHECK_NULL_VOID(theme);
1624     NG::PickerTextStyle textStyle;
1625     if (info[0]->IsObject()) {
1626         JSDatePicker::ParseTextStyle(info[0], textStyle, "textStyleTime");
1627     }
1628     TimePickerModel::GetInstance()->SetNormalTextStyle(theme, textStyle);
1629 }
1630 
SetSelectedTextStyle(const JSCallbackInfo & info)1631 void JSTimePicker::SetSelectedTextStyle(const JSCallbackInfo& info)
1632 {
1633     auto theme = GetTheme<PickerTheme>();
1634     CHECK_NULL_VOID(theme);
1635     NG::PickerTextStyle textStyle;
1636     if (info[0]->IsObject()) {
1637         JSDatePicker::ParseTextStyle(info[0], textStyle, "selectedTextStyleTime");
1638     }
1639     TimePickerModel::GetInstance()->SetSelectedTextStyle(theme, textStyle);
1640     if (textStyle.textColor.has_value() && theme->IsCircleDial()) {
1641         TimePickerModel::GetInstance()->UpdateUserSetSelectColor();
1642     }
1643 }
1644 
CreateTimePicker(const JSCallbackInfo & info,const JSRef<JSObject> & paramObj)1645 void JSTimePicker::CreateTimePicker(const JSCallbackInfo& info, const JSRef<JSObject>& paramObj)
1646 {
1647     auto startTime = paramObj->GetProperty("start");
1648     auto endTime = paramObj->GetProperty("end");
1649     auto selectedTime = paramObj->GetProperty("selected");
1650     auto theme = GetTheme<PickerTheme>();
1651     CHECK_NULL_VOID(theme);
1652     auto parseStartTime = ParseTime(startTime, theme->GetDefaultStartTime(), true);
1653     auto parseEndTime = ParseTime(endTime, theme->GetDefaultEndTime(), true);
1654     if (parseStartTime.ToMinutes() > parseEndTime.ToMinutes()) {
1655         parseStartTime = theme->GetDefaultStartTime();
1656         parseEndTime = theme->GetDefaultEndTime();
1657     }
1658     auto formatValue = paramObj->GetProperty("format");
1659     bool showSecond = false;
1660     if (formatValue->IsNumber()) {
1661         auto displayedFormat = static_cast<TimePickerFormat>(formatValue->ToNumber<int32_t>());
1662         if (displayedFormat == TimePickerFormat::HOUR_MINUTE_SECOND) {
1663             showSecond = true;
1664         }
1665     }
1666     TimePickerModel::GetInstance()->CreateTimePicker(theme, showSecond);
1667     TimePickerModel::GetInstance()->SetStartTime(parseStartTime);
1668     TimePickerModel::GetInstance()->SetEndTime(parseEndTime);
1669     if (selectedTime->IsObject()) {
1670         JSRef<JSObject> selectedTimeObj = JSRef<JSObject>::Cast(selectedTime);
1671         JSRef<JSVal> changeEventVal = selectedTimeObj->GetProperty("changeEvent");
1672         if (!changeEventVal->IsUndefined() && changeEventVal->IsFunction()) {
1673             ParseSelectedDateTimeObject(info, selectedTimeObj, false);
1674             auto parseSelectedTime = ParseTime(selectedTimeObj->GetProperty("value"));
1675             TimePickerModel::GetInstance()->SetSelectedTime(parseSelectedTime);
1676         } else {
1677             TimePickerModel::GetInstance()->SetSelectedTime(ParseTime(selectedTime));
1678         }
1679     }
1680     SetDefaultAttributes();
1681 }
1682 
SetDefaultAttributes()1683 void JSTimePicker::SetDefaultAttributes()
1684 {
1685     auto theme = GetTheme<PickerTheme>();
1686     CHECK_NULL_VOID(theme);
1687     NG::PickerTextStyle textStyle;
1688     auto selectedStyle = theme->GetOptionStyle(true, false);
1689     textStyle.fontSize = selectedStyle.GetFontSize();
1690     textStyle.fontWeight = selectedStyle.GetFontWeight();
1691     TimePickerModel::GetInstance()->SetSelectedTextStyle(theme, textStyle);
1692 
1693     auto disappearStyle = theme->GetDisappearOptionStyle();
1694     textStyle.fontSize = disappearStyle.GetFontSize();
1695     textStyle.fontWeight = disappearStyle.GetFontWeight();
1696     TimePickerModel::GetInstance()->SetDisappearTextStyle(theme, textStyle);
1697 
1698     auto normalStyle = theme->GetOptionStyle(false, false);
1699     textStyle.fontSize = normalStyle.GetFontSize();
1700     textStyle.fontWeight = normalStyle.GetFontWeight();
1701     TimePickerModel::GetInstance()->SetNormalTextStyle(theme, textStyle);
1702 }
1703 
ParseTime(const JSRef<JSVal> & timeVal,PickerTime defaultTime,bool startEndCheckValue)1704 PickerTime JSTimePicker::ParseTime(const JSRef<JSVal>& timeVal, PickerTime defaultTime, bool startEndCheckValue)
1705 {
1706     auto pickerTime = startEndCheckValue ? defaultTime : PickerTime::Current();
1707     if (!timeVal->IsObject()) {
1708         return pickerTime;
1709     }
1710     auto timeObj = JSRef<JSObject>::Cast(timeVal);
1711     auto yearFuncJsVal = timeObj->GetProperty("getFullYear");
1712     if (yearFuncJsVal->IsFunction()) {
1713         auto yearFunc = JSRef<JSFunc>::Cast(yearFuncJsVal);
1714         JSRef<JSVal> year = yearFunc->Call(timeObj);
1715         if (year->IsNumber() && LessOrEqual(year->ToNumber<int32_t>(), 0)) {
1716             return pickerTime;
1717         }
1718     }
1719 
1720     auto hourFuncJsVal = timeObj->GetProperty("getHours");
1721     auto minuteFuncJsVal = timeObj->GetProperty("getMinutes");
1722     auto secondFuncJsVal = timeObj->GetProperty("getSeconds");
1723     if (!(hourFuncJsVal->IsFunction() && minuteFuncJsVal->IsFunction() && secondFuncJsVal->IsFunction())) {
1724         return pickerTime;
1725     }
1726     auto hourFunc = JSRef<JSFunc>::Cast(hourFuncJsVal);
1727     auto minuteFunc = JSRef<JSFunc>::Cast(minuteFuncJsVal);
1728     auto secondFunc = JSRef<JSFunc>::Cast(secondFuncJsVal);
1729     JSRef<JSVal> hour = hourFunc->Call(timeObj);
1730     JSRef<JSVal> minute = minuteFunc->Call(timeObj);
1731     JSRef<JSVal> second = secondFunc->Call(timeObj);
1732 
1733     if (hour->IsNumber() && minute->IsNumber() && second->IsNumber()) {
1734         pickerTime.SetHour(hour->ToNumber<int32_t>());
1735         pickerTime.SetMinute(minute->ToNumber<int32_t>());
1736         pickerTime.SetSecond(second->ToNumber<int32_t>());
1737     }
1738     return pickerTime;
1739 }
1740 
JSBind(BindingTarget globalObj)1741 void JSTimePickerDialog::JSBind(BindingTarget globalObj)
1742 {
1743     JSClass<JSTimePickerDialog>::Declare("TimePickerDialog");
1744     JSClass<JSTimePickerDialog>::StaticMethod("show", &JSTimePickerDialog::Show);
1745 
1746     JSClass<JSTimePickerDialog>::Bind<>(globalObj);
1747 }
1748 
TimePickerDialogAppearEvent(const JSCallbackInfo & info,TimePickerDialogEvent & timePickerDialogEvent)1749 void TimePickerDialogAppearEvent(const JSCallbackInfo& info, TimePickerDialogEvent& timePickerDialogEvent)
1750 {
1751     std::function<void()> didAppearEvent;
1752     std::function<void()> willAppearEvent;
1753     if (info.Length() == 0 || !info[0]->IsObject()) {
1754         return;
1755     }
1756     auto paramObject = JSRef<JSObject>::Cast(info[0]);
1757     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1758     auto onDidAppear = paramObject->GetProperty("onDidAppear");
1759     if (!onDidAppear->IsUndefined() && onDidAppear->IsFunction()) {
1760         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidAppear));
1761         didAppearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1762             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1763             ACE_SCORING_EVENT("DatePickerDialog.onDidAppear");
1764             PipelineContext::SetCallBackNode(node);
1765             func->Execute();
1766         };
1767     }
1768     auto onWillAppear = paramObject->GetProperty("onWillAppear");
1769     if (!onWillAppear->IsUndefined() && onWillAppear->IsFunction()) {
1770         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillAppear));
1771         willAppearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1772             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1773             ACE_SCORING_EVENT("DatePickerDialog.onWillAppear");
1774             PipelineContext::SetCallBackNode(node);
1775             func->Execute();
1776         };
1777     }
1778     timePickerDialogEvent.onDidAppear = std::move(didAppearEvent);
1779     timePickerDialogEvent.onWillAppear = std::move(willAppearEvent);
1780 }
1781 
TimePickerDialogDisappearEvent(const JSCallbackInfo & info,TimePickerDialogEvent & timePickerDialogEvent)1782 void TimePickerDialogDisappearEvent(const JSCallbackInfo& info, TimePickerDialogEvent& timePickerDialogEvent)
1783 {
1784     std::function<void()> didDisappearEvent;
1785     std::function<void()> willDisappearEvent;
1786     if (info.Length() == 0 || !info[0]->IsObject()) {
1787         return;
1788     }
1789     auto paramObject = JSRef<JSObject>::Cast(info[0]);
1790     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1791     auto onDidDisappear = paramObject->GetProperty("onDidDisappear");
1792     if (!onDidDisappear->IsUndefined() && onDidDisappear->IsFunction()) {
1793         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidDisappear));
1794         didDisappearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1795             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1796             ACE_SCORING_EVENT("DatePickerDialog.onDidDisappear");
1797             PipelineContext::SetCallBackNode(node);
1798             func->Execute();
1799         };
1800     }
1801     auto onWillDisappear = paramObject->GetProperty("onWillDisappear");
1802     if (!onWillDisappear->IsUndefined() && onWillDisappear->IsFunction()) {
1803         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDisappear));
1804         willDisappearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1805             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1806             ACE_SCORING_EVENT("DatePickerDialog.onWillDisappear");
1807             PipelineContext::SetCallBackNode(node);
1808             func->Execute();
1809         };
1810     }
1811     timePickerDialogEvent.onDidDisappear = std::move(didDisappearEvent);
1812     timePickerDialogEvent.onWillDisappear = std::move(willDisappearEvent);
1813 }
1814 
Show(const JSCallbackInfo & info)1815 void JSTimePickerDialog::Show(const JSCallbackInfo& info)
1816 {
1817     auto scopedDelegate = EngineHelper::GetCurrentDelegateSafely();
1818     CHECK_NULL_VOID(scopedDelegate);
1819     if (!info[0]->IsObject()) {
1820         return;
1821     }
1822     auto paramObject = info[0]->IsEmpty() ? (JSRef<JSObject>::New()) : JSRef<JSObject>::Cast(info[0]);
1823     std::function<void()> cancelEvent;
1824     std::function<void(const std::string&)> acceptEvent;
1825     std::function<void(const std::string&)> changeEvent;
1826     std::function<void(const std::string&)> enterEvent;
1827     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1828     auto onChange = paramObject->GetProperty("onChange");
1829     if (!onChange->IsUndefined() && onChange->IsFunction()) {
1830         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onChange));
1831         changeEvent = [execCtx = info.GetExecutionContext(), type = DatePickerType::TIME, func = std::move(jsFunc),
1832                           node = targetNode](const std::string& info) {
1833             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1834             std::vector<std::string> keys;
1835             keys = { "year", "month", "day", "hour", "minute", "second" };
1836             ACE_SCORING_EVENT("DatePickerDialog.onChange");
1837             PipelineContext::SetCallBackNode(node);
1838             func->Execute(keys, info);
1839         };
1840     }
1841     auto onEnterSelectedArea = paramObject->GetProperty("onEnterSelectedArea");
1842     if (!onEnterSelectedArea->IsUndefined() && onEnterSelectedArea->IsFunction()) {
1843         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onEnterSelectedArea));
1844         enterEvent = [execCtx = info.GetExecutionContext(), type = DatePickerType::TIME, func = std::move(jsFunc),
1845                           node = targetNode](const std::string& info) {
1846             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1847             std::vector<std::string> keys;
1848             keys = { "year", "month", "day", "hour", "minute", "second" };
1849             ACE_SCORING_EVENT("DatePickerDialog.onEnterSelectedArea");
1850             PipelineContext::SetCallBackNode(node);
1851             func->Execute(keys, info);
1852         };
1853     }
1854     auto onAccept = paramObject->GetProperty("onAccept");
1855     if (!onAccept->IsUndefined() && onAccept->IsFunction()) {
1856         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAccept));
1857         acceptEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1858                           const std::string& info) {
1859             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1860             std::vector<std::string> keys = { "year", "month", "day", "hour", "minute", "second" };
1861             ACE_SCORING_EVENT("DatePickerDialog.onAccept");
1862             PipelineContext::SetCallBackNode(node);
1863             func->Execute(keys, info);
1864         };
1865     }
1866     auto onCancel = paramObject->GetProperty("onCancel");
1867     if (!onCancel->IsUndefined() && onCancel->IsFunction()) {
1868         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onCancel));
1869         cancelEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1870             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1871             ACE_SCORING_EVENT("DatePickerDialog.onCancel");
1872             PipelineContext::SetCallBackNode(node);
1873             func->Execute();
1874         };
1875     }
1876     auto startTime = paramObject->GetProperty("start");
1877     auto endTime = paramObject->GetProperty("end");
1878     auto selectedTime = paramObject->GetProperty("selected");
1879     auto useMilitaryTime = paramObject->GetProperty("useMilitaryTime");
1880     auto enableCascade = paramObject->GetProperty("enableCascade");
1881     NG::TimePickerSettingData settingData;
1882     PickerDialogInfo pickerDialog;
1883     settingData.isUseMilitaryTime = useMilitaryTime->ToBoolean();
1884     settingData.isEnableCascade = enableCascade->ToBoolean();
1885     pickerDialog.isUseMilitaryTime = useMilitaryTime->ToBoolean();
1886     pickerDialog.isEnableCascade = enableCascade->ToBoolean();
1887     auto theme = GetTheme<PickerTheme>();
1888     CHECK_NULL_VOID(theme);
1889     auto parseStartTime = ParseTime(startTime, theme->GetDefaultStartTime(), true);
1890     auto parseEndTime = ParseTime(endTime, theme->GetDefaultEndTime(), true);
1891     if (parseStartTime.ToMinutes() > parseEndTime.ToMinutes()) {
1892         parseStartTime = theme->GetDefaultStartTime();
1893         parseEndTime = theme->GetDefaultEndTime();
1894     }
1895     pickerDialog.parseStartTime = parseStartTime;
1896     pickerDialog.parseEndTime = parseEndTime;
1897 
1898     if (selectedTime->IsObject()) {
1899         PickerDate dialogTitleDate = ParseDate(selectedTime);
1900         if (dialogTitleDate.GetYear() != 0) {
1901             settingData.dialogTitleDate = dialogTitleDate;
1902             pickerDialog.isSelectedTime = true;
1903             pickerDialog.pickerTime = ParseTime(selectedTime);
1904         }
1905     }
1906     JSDatePicker::ParseTextProperties(paramObject, settingData.properties);
1907     auto dateTimeOptionsValue = paramObject->GetProperty("dateTimeOptions");
1908     if (dateTimeOptionsValue->IsObject()) {
1909         auto dateTimeOptionsObj = JSRef<JSObject>::Cast(dateTimeOptionsValue);
1910         JSDatePickerDialog::ParseDateTimeOptions(dateTimeOptionsObj, settingData.dateTimeOptions);
1911     }
1912 
1913     // Parse alignment
1914     auto alignmentValue = paramObject->GetProperty("alignment");
1915     if (alignmentValue->IsNumber()) {
1916         auto alignment = alignmentValue->ToNumber<int32_t>();
1917         if (alignment >= 0 && alignment < static_cast<int32_t>(DIALOG_ALIGNMENT.size())) {
1918             pickerDialog.alignment = DIALOG_ALIGNMENT[alignment];
1919         }
1920         if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1921             if (alignment == static_cast<int32_t>(DialogAlignment::TOP) ||
1922                 alignment == static_cast<int32_t>(DialogAlignment::TOP_START) ||
1923                 alignment == static_cast<int32_t>(DialogAlignment::TOP_END)) {
1924                 pickerDialog.offset = DATEPICKER_OFFSET_DEFAULT_TOP;
1925             }
1926         }
1927     }
1928 
1929     // Parse offset
1930     auto offsetValue = paramObject->GetProperty("offset");
1931     if (offsetValue->IsObject()) {
1932         auto offsetObj = JSRef<JSObject>::Cast(offsetValue);
1933         CalcDimension dx;
1934         auto dxValue = offsetObj->GetProperty("dx");
1935         JSAlertDialog::ParseJsDimensionVp(dxValue, dx);
1936         CalcDimension dy;
1937         auto dyValue = offsetObj->GetProperty("dy");
1938         JSAlertDialog::ParseJsDimensionVp(dyValue, dy);
1939         pickerDialog.offset = DimensionOffset(dx, dy);
1940     }
1941 
1942     // Parse maskRect.
1943     auto maskRectValue = paramObject->GetProperty("maskRect");
1944     DimensionRect maskRect;
1945     if (JSViewAbstract::ParseJsDimensionRect(maskRectValue, maskRect)) {
1946         pickerDialog.maskRect = maskRect;
1947     }
1948 
1949     auto backgroundColorValue = paramObject->GetProperty("backgroundColor");
1950     Color backgroundColor;
1951     if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor)) {
1952         pickerDialog.backgroundColor = backgroundColor;
1953     }
1954 
1955     auto backgroundBlurStyle = paramObject->GetProperty("backgroundBlurStyle");
1956     if (backgroundBlurStyle->IsNumber()) {
1957         auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>();
1958         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
1959             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
1960             pickerDialog.backgroundBlurStyle = blurStyle;
1961         }
1962     }
1963 
1964     ParseDatePickerHoverMode(pickerDialog, paramObject);
1965     ParseDatePickerBlurStyleOption(pickerDialog, paramObject);
1966     ParseDatePickerEffectOption(pickerDialog, paramObject);
1967 
1968     auto buttonInfos = ParseButtonStyles(paramObject);
1969 
1970     auto shadowValue = paramObject->GetProperty("shadow");
1971     Shadow shadow;
1972     if ((shadowValue->IsObject() || shadowValue->IsNumber()) && JSViewAbstract::ParseShadowProps(shadowValue, shadow)) {
1973         pickerDialog.shadow = shadow;
1974     }
1975     auto formatValue = paramObject->GetProperty("format");
1976     bool showSecond = false;
1977     if (formatValue->IsNumber()) {
1978         auto displayedFormat = static_cast<TimePickerFormat>(formatValue->ToNumber<int32_t>());
1979         if (displayedFormat == TimePickerFormat::HOUR_MINUTE_SECOND) {
1980             showSecond = true;
1981         }
1982     }
1983     settingData.showSecond = showSecond;
1984     auto enableHapticFeedbackValue = paramObject->GetProperty("enableHapticFeedback");
1985     bool isEnableHapticFeedback = true;
1986     if (enableHapticFeedbackValue->IsBoolean()) {
1987         isEnableHapticFeedback = enableHapticFeedbackValue->ToBoolean();
1988     }
1989     settingData.isEnableHapticFeedback = isEnableHapticFeedback;
1990     TimePickerDialogEvent timePickerDialogEvent { nullptr, nullptr, nullptr, nullptr };
1991     TimePickerDialogAppearEvent(info, timePickerDialogEvent);
1992     TimePickerDialogDisappearEvent(info, timePickerDialogEvent);
1993     TimePickerDialogModel::GetInstance()->SetTimePickerDialogShow(pickerDialog, settingData, std::move(cancelEvent),
1994         std::move(acceptEvent), std::move(changeEvent), std::move(enterEvent), timePickerDialogEvent, buttonInfos);
1995 }
1996 
TimePickerDialogShow(const JSRef<JSObject> & paramObj,const std::map<std::string,NG::DialogEvent> & dialogEvent,const std::map<std::string,NG::DialogGestureEvent> & dialogCancelEvent)1997 void JSTimePickerDialog::TimePickerDialogShow(const JSRef<JSObject>& paramObj,
1998     const std::map<std::string, NG::DialogEvent>& dialogEvent,
1999     const std::map<std::string, NG::DialogGestureEvent>& dialogCancelEvent)
2000 {
2001     auto container = Container::CurrentSafely();
2002     CHECK_NULL_VOID(container);
2003 
2004     auto pipelineContext = AccessibilityManager::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
2005     CHECK_NULL_VOID(pipelineContext);
2006 
2007     auto executor = pipelineContext->GetTaskExecutor();
2008     CHECK_NULL_VOID(executor);
2009 
2010     auto theme = JSAlertDialog::GetTheme<DialogTheme>();
2011     CHECK_NULL_VOID(theme);
2012 
2013     auto selectedTime = paramObj->GetProperty("selected");
2014     auto useMilitaryTime = paramObj->GetProperty("useMilitaryTime");
2015     auto enableCascade = paramObj->GetProperty("enableCascade");
2016     NG::TimePickerSettingData settingData;
2017     settingData.isUseMilitaryTime = useMilitaryTime->ToBoolean();
2018     settingData.isEnableCascade = enableCascade->ToBoolean();
2019 
2020     DialogProperties properties;
2021     properties.alignment = theme->GetAlignment();
2022     if (properties.alignment == DialogAlignment::BOTTOM &&
2023         Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
2024         properties.offset = DimensionOffset(Offset(0, -theme->GetMarginBottom().ConvertToPx()));
2025     }
2026 
2027     auto enableHapticFeedbackValue = paramObj->GetProperty("enableHapticFeedback");
2028     bool isEnableHapticFeedback = true;
2029     if (enableHapticFeedbackValue->IsBoolean()) {
2030         isEnableHapticFeedback = enableHapticFeedbackValue->ToBoolean();
2031     }
2032     settingData.isEnableHapticFeedback = isEnableHapticFeedback;
2033 
2034     properties.customStyle = false;
2035     if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
2036         properties.offset = DimensionOffset(Offset(0, -theme->GetMarginBottom().ConvertToPx()));
2037     }
2038 
2039     std::map<std::string, PickerTime> timePickerProperty;
2040     if (selectedTime->IsObject()) {
2041         settingData.dialogTitleDate = ParseDate(selectedTime);
2042         timePickerProperty["selected"] = ParseTime(selectedTime);
2043     }
2044     JSDatePicker::ParseTextProperties(paramObj, settingData.properties);
2045 
2046     auto context = AccessibilityManager::DynamicCast<NG::PipelineContext>(pipelineContext);
2047     auto overlayManager = context ? context->GetOverlayManager() : nullptr;
2048     executor->PostTask(
2049         [properties, settingData, timePickerProperty, dialogEvent, dialogCancelEvent,
2050             weak = WeakPtr<NG::OverlayManager>(overlayManager)] {
2051             auto overlayManager = weak.Upgrade();
2052             CHECK_NULL_VOID(overlayManager);
2053             overlayManager->ShowTimeDialog(properties, settingData, timePickerProperty, dialogEvent, dialogCancelEvent);
2054         },
2055         TaskExecutor::TaskType::UI, "ArkUIDialogShowTimePicker",
2056         TaskExecutor::GetPriorityTypeWithCheck(PriorityType::VIP));
2057 }
2058 
CreateTimePicker(RefPtr<Component> & component,const JSRef<JSObject> & paramObj)2059 void JSTimePickerDialog::CreateTimePicker(RefPtr<Component>& component, const JSRef<JSObject>& paramObj)
2060 {
2061     auto timePicker = AceType::MakeRefPtr<PickerTimeComponent>();
2062     auto selectedTime = paramObj->GetProperty("selected");
2063     auto useMilitaryTime = paramObj->GetProperty("useMilitaryTime");
2064     auto enableCascade = paramObj->GetProperty("enableCascade");
2065     bool isUseMilitaryTime = useMilitaryTime->ToBoolean();
2066     bool isEnableCascade = enableCascade->ToBoolean();
2067     if (selectedTime->IsObject()) {
2068         timePicker->SetSelectedTime(ParseTime(selectedTime));
2069     }
2070     timePicker->SetIsDialog(true);
2071     timePicker->SetIsCreateDialogComponent(true);
2072     timePicker->SetHour24(isUseMilitaryTime);
2073     timePicker->SetEnableCascade(isEnableCascade);
2074     component = timePicker;
2075 }
2076 
ParseTime(const JSRef<JSVal> & timeVal,PickerTime defaultTime,bool startEndCheckValue)2077 PickerTime JSTimePickerDialog::ParseTime(const JSRef<JSVal>& timeVal, PickerTime defaultTime, bool startEndCheckValue)
2078 {
2079     auto pickerTime = startEndCheckValue ? defaultTime : PickerTime();
2080     if (!timeVal->IsObject()) {
2081         return pickerTime;
2082     }
2083     auto timeObj = JSRef<JSObject>::Cast(timeVal);
2084     auto yearFuncJsVal = timeObj->GetProperty("getFullYear");
2085     if (yearFuncJsVal->IsFunction()) {
2086         auto yearFunc = JSRef<JSFunc>::Cast(yearFuncJsVal);
2087         JSRef<JSVal> year = yearFunc->Call(timeObj);
2088         if (year->IsNumber() && LessOrEqual(year->ToNumber<int32_t>(), 0)) {
2089             return pickerTime;
2090         }
2091     }
2092     auto hourFuncJsVal = timeObj->GetProperty("getHours");
2093     auto minuteFuncJsVal = timeObj->GetProperty("getMinutes");
2094     auto secondFuncJsVal = timeObj->GetProperty("getSeconds");
2095     if (!(hourFuncJsVal->IsFunction() && minuteFuncJsVal->IsFunction() && secondFuncJsVal->IsFunction())) {
2096         return pickerTime;
2097     }
2098     auto hourFunc = JSRef<JSFunc>::Cast(hourFuncJsVal);
2099     auto minuteFunc = JSRef<JSFunc>::Cast(minuteFuncJsVal);
2100     auto secondFunc = JSRef<JSFunc>::Cast(secondFuncJsVal);
2101     JSRef<JSVal> hour = hourFunc->Call(timeObj);
2102     JSRef<JSVal> minute = minuteFunc->Call(timeObj);
2103     JSRef<JSVal> second = secondFunc->Call(timeObj);
2104 
2105     if (hour->IsNumber() && minute->IsNumber() && second->IsNumber()) {
2106         pickerTime.SetHour(hour->ToNumber<int32_t>());
2107         pickerTime.SetMinute(minute->ToNumber<int32_t>());
2108         pickerTime.SetSecond(second->ToNumber<int32_t>());
2109     }
2110     return pickerTime;
2111 }
2112 
ParseDate(const JSRef<JSVal> & dateVal)2113 PickerDate JSTimePickerDialog::ParseDate(const JSRef<JSVal>& dateVal)
2114 {
2115     auto pickerDate = PickerDate();
2116     if (!dateVal->IsObject()) {
2117         return pickerDate;
2118     }
2119     auto dateObj = JSRef<JSObject>::Cast(dateVal);
2120     auto yearFuncJsVal = dateObj->GetProperty("getFullYear");
2121     auto monthFuncJsVal = dateObj->GetProperty("getMonth");
2122     auto dateFuncJsVal = dateObj->GetProperty("getDate");
2123     if (!(yearFuncJsVal->IsFunction() && monthFuncJsVal->IsFunction() && dateFuncJsVal->IsFunction())) {
2124         return pickerDate;
2125     }
2126     auto yearFunc = JSRef<JSFunc>::Cast(yearFuncJsVal);
2127     auto monthFunc = JSRef<JSFunc>::Cast(monthFuncJsVal);
2128     auto dateFunc = JSRef<JSFunc>::Cast(dateFuncJsVal);
2129     JSRef<JSVal> year = yearFunc->Call(dateObj);
2130     JSRef<JSVal> month = monthFunc->Call(dateObj);
2131     JSRef<JSVal> date = dateFunc->Call(dateObj);
2132 
2133     if (year->IsNumber() && month->IsNumber() && date->IsNumber()) {
2134         pickerDate.SetYear(year->ToNumber<int32_t>());
2135         pickerDate.SetMonth(month->ToNumber<int32_t>() + 1); // 0-11 means 1 to 12 months
2136         pickerDate.SetDay(date->ToNumber<int32_t>());
2137     }
2138     return pickerDate;
2139 }
2140 } // namespace OHOS::Ace::Framework
2141