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