• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "frameworks/bridge/declarative_frontend/jsview/js_calendar_picker.h"
17 
18 #include "base/log/ace_scoring_log.h"
19 #include "base/utils/date_util.h"
20 #include "bridge/common/utils/engine_helper.h"
21 #include "bridge/declarative_frontend/engine/functions/js_function.h"
22 #include "bridge/declarative_frontend/jsview/js_interactable_view.h"
23 #include "bridge/declarative_frontend/jsview/js_utils.h"
24 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
25 #include "bridge/declarative_frontend/jsview/models/calendar_picker_model_impl.h"
26 #include "core/components/calendar/calendar_theme.h"
27 #include "core/components/dialog/dialog_theme.h"
28 #include "core/components_ng/base/view_abstract_model.h"
29 #include "core/components_ng/base/view_stack_processor.h"
30 #include "core/components_ng/pattern/calendar_picker/calendar_picker_model_ng.h"
31 #include "core/pipeline_ng/pipeline_context.h"
32 #include "core/common/resource/resource_object.h"
33 #include "core/common/resource/resource_parse_utils.h"
34 
35 namespace OHOS::Ace {
36 std::unique_ptr<CalendarPickerModel> CalendarPickerModel::instance_ = nullptr;
37 std::once_flag CalendarPickerModel::onceFlag_;
38 
GetInstance()39 CalendarPickerModel* CalendarPickerModel::GetInstance()
40 {
41     std::call_once(onceFlag_, []() {
42 #ifdef NG_BUILD
43         instance_.reset(new NG::CalendarPickerModelNG());
44 #else
45         if (Container::IsCurrentUseNewPipeline()) {
46             instance_.reset(new NG::CalendarPickerModelNG());
47         } else {
48             instance_.reset(new Framework::CalendarPickerModelImpl());
49         }
50 #endif
51     });
52 
53     return instance_.get();
54 }
55 } // namespace OHOS::Ace
56 
57 namespace OHOS::Ace::Framework {
58 namespace {
ParseFontOfButtonStyle(const JSRef<JSObject> & pickerButtonParamObject,ButtonInfo & buttonInfo)59 void ParseFontOfButtonStyle(const JSRef<JSObject>& pickerButtonParamObject, ButtonInfo& buttonInfo)
60 {
61     CalcDimension fontSize;
62     JSRef<JSVal> sizeProperty = pickerButtonParamObject->GetProperty("fontSize");
63     if (JSViewAbstract::ParseJsDimensionVpNG(sizeProperty, fontSize) && fontSize.Unit() != DimensionUnit::PERCENT &&
64         GreatOrEqual(fontSize.Value(), 0.0)) {
65         if (JSViewAbstract::ParseJsDimensionFp(sizeProperty, fontSize)) {
66             buttonInfo.fontSize = fontSize;
67         }
68     }
69     Color fontColor;
70     if (JSViewAbstract::ParseJsColor(pickerButtonParamObject->GetProperty("fontColor"), fontColor)) {
71         buttonInfo.fontColor = fontColor;
72     }
73     auto fontWeight = pickerButtonParamObject->GetProperty("fontWeight");
74     if (fontWeight->IsString() || fontWeight->IsNumber()) {
75         buttonInfo.fontWeight = ConvertStrToFontWeight(fontWeight->ToString(), FontWeight::MEDIUM);
76     }
77     JSRef<JSVal> style = pickerButtonParamObject->GetProperty("fontStyle");
78     if (style->IsNumber()) {
79         auto value = style->ToNumber<int32_t>();
80         if (value >= 0 && value < static_cast<int32_t>(FontStyle::NONE)) {
81             buttonInfo.fontStyle = static_cast<FontStyle>(value);
82         }
83     }
84     JSRef<JSVal> family = pickerButtonParamObject->GetProperty("fontFamily");
85     std::vector<std::string> fontFamilies;
86     if (JSViewAbstract::ParseJsFontFamilies(family, fontFamilies)) {
87         buttonInfo.fontFamily = fontFamilies;
88     }
89 }
90 
ParseButtonStyle(const JSRef<JSObject> & pickerButtonParamObject)91 ButtonInfo ParseButtonStyle(const JSRef<JSObject>& pickerButtonParamObject)
92 {
93     ButtonInfo buttonInfo;
94     if (pickerButtonParamObject->GetProperty("type")->IsNumber()) {
95         auto buttonTypeIntValue = pickerButtonParamObject->GetProperty("type")->ToNumber<int32_t>();
96         if (buttonTypeIntValue == static_cast<int32_t>(ButtonType::CAPSULE) ||
97             buttonTypeIntValue == static_cast<int32_t>(ButtonType::CIRCLE) ||
98             buttonTypeIntValue == static_cast<int32_t>(ButtonType::ARC) ||
99             buttonTypeIntValue == static_cast<int32_t>(ButtonType::NORMAL) ||
100             buttonTypeIntValue == static_cast<int32_t>(ButtonType::ROUNDED_RECTANGLE)) {
101             buttonInfo.type = static_cast<ButtonType>(buttonTypeIntValue);
102         }
103     }
104     if (pickerButtonParamObject->GetProperty("style")->IsNumber()) {
105         auto styleModeIntValue = pickerButtonParamObject->GetProperty("style")->ToNumber<int32_t>();
106         if (styleModeIntValue >= static_cast<int32_t>(ButtonStyleMode::NORMAL) &&
107             styleModeIntValue <= static_cast<int32_t>(ButtonStyleMode::TEXT)) {
108             buttonInfo.buttonStyle = static_cast<ButtonStyleMode>(styleModeIntValue);
109         }
110     }
111     if (pickerButtonParamObject->GetProperty("role")->IsNumber()) {
112         auto buttonRoleIntValue = pickerButtonParamObject->GetProperty("role")->ToNumber<int32_t>();
113         if (buttonRoleIntValue >= static_cast<int32_t>(ButtonRole::NORMAL) &&
114             buttonRoleIntValue <= static_cast<int32_t>(ButtonRole::ERROR)) {
115             buttonInfo.role = static_cast<ButtonRole>(buttonRoleIntValue);
116         }
117     }
118     ParseFontOfButtonStyle(pickerButtonParamObject, buttonInfo);
119     Color backgroundColor;
120     if (JSViewAbstract::ParseJsColor(pickerButtonParamObject->GetProperty("backgroundColor"), backgroundColor)) {
121         buttonInfo.backgroundColor = backgroundColor;
122     }
123     auto radius = ParseBorderRadiusAttr(pickerButtonParamObject->GetProperty("borderRadius"));
124     if (radius.has_value()) {
125         buttonInfo.borderRadius = radius.value();
126     }
127 
128     auto primaryValue = pickerButtonParamObject->GetProperty("primary");
129     if (primaryValue->IsBoolean()) {
130         buttonInfo.isPrimary = primaryValue->ToBoolean();
131     }
132 
133     return buttonInfo;
134 }
135 
ParseButtonStyles(const JSRef<JSObject> & paramObject)136 std::vector<ButtonInfo> ParseButtonStyles(const JSRef<JSObject>& paramObject)
137 {
138     std::vector<ButtonInfo> buttonInfos;
139     auto acceptButtonStyle = paramObject->GetProperty("acceptButtonStyle");
140     if (acceptButtonStyle->IsObject()) {
141         auto acceptButtonStyleParamObject = JSRef<JSObject>::Cast(acceptButtonStyle);
142         buttonInfos.emplace_back(ParseButtonStyle(acceptButtonStyleParamObject));
143         buttonInfos[0].isAcceptButton = true;
144     } else {
145         ButtonInfo buttonInfo;
146         buttonInfos.emplace_back(buttonInfo);
147     }
148     auto cancelButtonStyle = paramObject->GetProperty("cancelButtonStyle");
149     if (cancelButtonStyle->IsObject()) {
150         auto cancelButtonStyleParamObject = JSRef<JSObject>::Cast(cancelButtonStyle);
151         buttonInfos.emplace_back(ParseButtonStyle(cancelButtonStyleParamObject));
152     }
153 
154     return buttonInfos;
155 }
156 } // namespace
157 
GetMSByDate(const std::string & date)158 double GetMSByDate(const std::string& date)
159 {
160     auto json = JsonUtil::ParseJsonString(date);
161     if (!json || json->IsNull()) {
162         return 0.0f;
163     }
164 
165     std::tm dateTime {};
166     auto year = json->GetValue("year");
167     if (year && year->IsNumber()) {
168         dateTime.tm_year = year->GetInt() - 1900; // local date start from 1900
169     }
170     auto month = json->GetValue("month");
171     if (month && month->IsNumber()) {
172         dateTime.tm_mon = month->GetInt() - 1;
173     }
174     auto day = json->GetValue("day");
175     if (day && day->IsNumber()) {
176         dateTime.tm_mday = day->GetInt();
177     }
178     auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
179     auto local = std::localtime(&now);
180     CHECK_NULL_RETURN(local, 0.0f);
181     dateTime.tm_hour = local->tm_hour;
182     dateTime.tm_min = local->tm_min;
183     dateTime.tm_sec = local->tm_sec;
184     return Date::GetMilliSecondsByDateTime(dateTime);
185 }
186 
JSBind(BindingTarget globalObj)187 void JSCalendarPicker::JSBind(BindingTarget globalObj)
188 {
189     JSClass<JSCalendarPicker>::Declare("CalendarPicker");
190     JSClass<JSCalendarPicker>::StaticMethod("create", &JSCalendarPicker::Create, MethodOptions::NONE);
191     JSClass<JSCalendarPicker>::StaticMethod("edgeAlign", &JSCalendarPicker::SetEdgeAlign);
192     JSClass<JSCalendarPicker>::StaticMethod("textStyle", &JSCalendarPicker::SetTextStyle);
193     JSClass<JSCalendarPicker>::StaticMethod("onChange", &JSCalendarPicker::SetOnChange);
194     JSClass<JSCalendarPicker>::StaticMethod("border", &JSCalendarPicker::SetBorder);
195     JSClass<JSCalendarPicker>::StaticMethod("padding", &JSCalendarPicker::JsPadding);
196     JSClass<JSCalendarPicker>::StaticMethod("height", &JSCalendarPicker::JsHeight);
197     JSClass<JSCalendarPicker>::StaticMethod("borderColor", &JSCalendarPicker::JsBorderColor);
198     JSClass<JSCalendarPicker>::StaticMethod("borderRadius", &JSCalendarPicker::JsBorderRadius);
199     JSClass<JSCalendarPicker>::StaticMethod("markToday", &JSCalendarPicker::JsMarkToday);
200     JSClass<JSCalendarPicker>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
201     JSClass<JSCalendarPicker>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
202     JSClass<JSCalendarPicker>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
203     JSClass<JSCalendarPicker>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
204     JSClass<JSCalendarPicker>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
205     JSClass<JSCalendarPicker>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
206     JSClass<JSCalendarPicker>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
207     JSClass<JSCalendarPicker>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
208     JSClass<JSCalendarPicker>::InheritAndBind<JSViewAbstract>(globalObj);
209 }
210 
SetBorder(const JSCallbackInfo & info)211 void JSCalendarPicker::SetBorder(const JSCallbackInfo& info)
212 {
213     if (!info[0]->IsObject()) {
214         CalendarPickerModel::GetInstance()->ClearBorder();
215         return;
216     }
217     JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
218     auto valueWidth = object->GetProperty("width");
219     CalcDimension value;
220     if (ParseJsDimensionVpNG(valueWidth, value) || valueWidth->IsObject()) {
221         ParseBorderWidth(valueWidth);
222     } else {
223         CalendarPickerModel::GetInstance()->ClearBorderWidth();
224     }
225 
226     // use default value when undefined.
227     ParseCalendarPickerBorderColor(object->GetProperty("color"));
228 
229     auto valueRadius = object->GetProperty("radius");
230     if (!valueRadius->IsUndefined()) {
231         ParseBorderRadius(valueRadius);
232     }
233     // use default value when undefined.
234     ParseBorderStyle(object->GetProperty("style"));
235 
236     info.ReturnSelf();
237 }
238 
ParseCalendarPickerBorderColor(const JSRef<JSVal> & args)239 void JSCalendarPicker::ParseCalendarPickerBorderColor(const JSRef<JSVal>& args)
240 {
241     auto pipelineContext = PipelineContext::GetCurrentContext();
242     CHECK_NULL_VOID(pipelineContext);
243     RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
244     CHECK_NULL_VOID(theme);
245     if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
246         ViewAbstractModel::GetInstance()->SetBorderColor(theme->GetEntryBorderColor());
247     } else {
248         JSViewAbstract::ParseBorderColor(args);
249     }
250 }
251 
SetEdgeAlign(const JSCallbackInfo & info)252 void JSCalendarPicker::SetEdgeAlign(const JSCallbackInfo& info)
253 {
254     NG::CalendarEdgeAlign alignType = NG::CalendarEdgeAlign::EDGE_ALIGN_END;
255     DimensionOffset offset;
256     if (info[0]->IsNumber()) {
257         alignType = static_cast<NG::CalendarEdgeAlign>(info[0]->ToNumber<int32_t>());
258     }
259 
260     if (!info[1]->IsObject()) {
261         CalendarPickerModel::GetInstance()->SetEdgeAlign(alignType, offset);
262         return;
263     }
264     auto offsetObj = JSRef<JSObject>::Cast(info[1]);
265     auto dxValue = offsetObj->GetProperty("dx");
266     auto dyValue = offsetObj->GetProperty("dy");
267 
268     CalcDimension dx;
269     CalcDimension dy;
270 
271     if (SystemProperties::ConfigChangePerform()) {
272         RefPtr<ResourceObject> dxResObj;
273         RefPtr<ResourceObject> dyResObj;
274         ParseJsDimensionVp(dxValue, dx, dxResObj);
275         ParseJsDimensionVp(dyValue, dy, dyResObj);
276         offset = DimensionOffset(dx, dy);
277 
278         if (dxResObj || dyResObj) {
279             std::vector<RefPtr<ResourceObject>> resArray = { dxResObj, dyResObj };
280             CalendarPickerModel::GetInstance()->ParseEdgeAlignResObj(resArray);
281         } else {
282             CalendarPickerModel::GetInstance()->CalendarPickerRemoveResObj("CalendarPicker.EdgeAlign");
283         }
284     } else {
285         ParseJsDimensionVp(dxValue, dx);
286         ParseJsDimensionVp(dyValue, dy);
287         offset = DimensionOffset(dx, dy);
288     }
289 
290     CalendarPickerModel::GetInstance()->SetEdgeAlign(alignType, offset);
291 }
292 
SetTextStyle(const JSCallbackInfo & info)293 void JSCalendarPicker::SetTextStyle(const JSCallbackInfo& info)
294 {
295     auto pipeline = PipelineBase::GetCurrentContext();
296     CHECK_NULL_VOID(pipeline);
297     RefPtr<CalendarTheme> calendarTheme = pipeline->GetTheme<CalendarTheme>();
298     CHECK_NULL_VOID(calendarTheme);
299     NG::PickerTextStyle textStyle;
300     textStyle.fontSize = calendarTheme->GetEntryFontSize();
301     textStyle.textColor = calendarTheme->GetEntryFontColor();
302     textStyle.fontWeight = FontWeight::NORMAL;
303     if (info[0]->IsObject()) {
304         JSCalendarPicker::ParseTextStyle(info[0], textStyle);
305     }
306     CalendarPickerModel::GetInstance()->SetTextStyle(textStyle);
307 }
308 
SetOnChange(const JSCallbackInfo & info)309 void JSCalendarPicker::SetOnChange(const JSCallbackInfo& info)
310 {
311     if (!info[0]->IsFunction()) {
312         return;
313     }
314 
315     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
316     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
317     auto onChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
318                         const std::string& info) {
319         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
320         ACE_SCORING_EVENT("CalendarPicker.onChange");
321         PipelineContext::SetCallBackNode(node);
322         auto dateObj = JSDate::New(GetMSByDate(info));
323         func->ExecuteJS(1, &dateObj);
324     };
325     CalendarPickerModel::GetInstance()->SetOnChange(std::move(onChange));
326 }
327 
JsPadding(const JSCallbackInfo & info)328 void JSCalendarPicker::JsPadding(const JSCallbackInfo& info)
329 {
330     NG::PaddingProperty padding;
331     if (info[0]->IsObject()) {
332         CommonCalcDimension commonCalcDimension;
333         JSRef<JSObject> paddingObj = JSRef<JSObject>::Cast(info[0]);
334         JSViewAbstract::ParseCommonMarginOrPaddingCorner(paddingObj, commonCalcDimension);
335         if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() ||
336             commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) {
337             padding = SetPaddings(commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left,
338                 commonCalcDimension.right);
339             CalendarPickerModel::GetInstance()->SetPadding(padding);
340             return;
341         }
342     }
343 
344     CalcDimension length(-1);
345     if (ParseJsDimensionVpNG(info[0], length) && length.IsNonNegative()) {
346         padding.SetEdges(NG::CalcLength(length));
347         CalendarPickerModel::GetInstance()->SetPadding(padding);
348     } else {
349         CalendarPickerModel::GetInstance()->ClearPadding();
350     }
351 }
352 
JsHeight(const JSCallbackInfo & info)353 void JSCalendarPicker::JsHeight(const JSCallbackInfo& info)
354 {
355     auto jsValue = info[0];
356     CalcDimension value;
357     if (ParseJsDimensionVpNG(jsValue, value) && value.IsValid()) {
358         JSViewAbstract::JsHeight(info);
359         return;
360     }
361 
362     LayoutCalPolicy policy = LayoutCalPolicy::NO_MATCH;
363     if (jsValue->IsObject()) {
364         JSRef<JSObject> object = JSRef<JSObject>::Cast(jsValue);
365         CHECK_NULL_VOID(!object->IsEmpty());
366         JSRef<JSVal> layoutPolicy = object->GetProperty("id_");
367         CHECK_NULL_VOID(!layoutPolicy->IsEmpty());
368         if (layoutPolicy->IsString()) {
369             policy = ParseLayoutPolicy(layoutPolicy->ToString());
370         }
371     }
372     ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(policy, false);
373     CalendarPickerModel::GetInstance()->ClearHeight();
374 }
375 
JsBorderColor(const JSCallbackInfo & info)376 void JSCalendarPicker::JsBorderColor(const JSCallbackInfo& info)
377 {
378     Color borderColor;
379     auto jsValue = info[0];
380     if (ParseJsColor(jsValue, borderColor) || jsValue->IsObject()) {
381         JSViewAbstract::JsBorderColor(info);
382     } else {
383         CalendarPickerModel::GetInstance()->ClearBorderColor();
384     }
385 }
386 
JsBorderRadius(const JSCallbackInfo & info)387 void JSCalendarPicker::JsBorderRadius(const JSCallbackInfo& info)
388 {
389     auto jsValue = info[0];
390     CalcDimension value;
391     if (ParseJsDimensionVpNG(jsValue, value) || jsValue->IsObject()) {
392         JSViewAbstract::JsBorderRadius(info);
393     } else {
394         CalendarPickerModel::GetInstance()->ClearBorderRadius();
395     }
396 }
397 
SetPaddings(const std::optional<CalcDimension> & top,const std::optional<CalcDimension> & bottom,const std::optional<CalcDimension> & left,const std::optional<CalcDimension> & right)398 NG::PaddingProperty JSCalendarPicker::SetPaddings(const std::optional<CalcDimension>& top,
399     const std::optional<CalcDimension>& bottom, const std::optional<CalcDimension>& left,
400     const std::optional<CalcDimension>& right)
401 {
402     NG::PaddingProperty paddings;
403     if (top.has_value()) {
404         if (top.value().Unit() == DimensionUnit::CALC) {
405             paddings.top =
406                 NG::CalcLength(top.value().IsNonNegative() ? top.value().CalcValue() : CalcDimension().CalcValue());
407         } else {
408             paddings.top = NG::CalcLength(top.value().IsNonNegative() ? top.value() : CalcDimension());
409         }
410     }
411     if (bottom.has_value()) {
412         if (bottom.value().Unit() == DimensionUnit::CALC) {
413             paddings.bottom = NG::CalcLength(
414                 bottom.value().IsNonNegative() ? bottom.value().CalcValue() : CalcDimension().CalcValue());
415         } else {
416             paddings.bottom = NG::CalcLength(bottom.value().IsNonNegative() ? bottom.value() : CalcDimension());
417         }
418     }
419     if (left.has_value()) {
420         if (left.value().Unit() == DimensionUnit::CALC) {
421             paddings.left =
422                 NG::CalcLength(left.value().IsNonNegative() ? left.value().CalcValue() : CalcDimension().CalcValue());
423         } else {
424             paddings.left = NG::CalcLength(left.value().IsNonNegative() ? left.value() : CalcDimension());
425         }
426     }
427     if (right.has_value()) {
428         if (right.value().Unit() == DimensionUnit::CALC) {
429             paddings.right =
430                 NG::CalcLength(right.value().IsNonNegative() ? right.value().CalcValue() : CalcDimension().CalcValue());
431         } else {
432             paddings.right = NG::CalcLength(right.value().IsNonNegative() ? right.value() : CalcDimension());
433         }
434     }
435 
436     return paddings;
437 }
438 
ParseSelectedDateObject(const JSCallbackInfo & info,const JSRef<JSObject> & selectedObject)439 void JSCalendarPicker::ParseSelectedDateObject(const JSCallbackInfo& info, const JSRef<JSObject>& selectedObject)
440 {
441     JSRef<JSVal> changeEventVal = selectedObject->GetProperty("changeEvent");
442     if (!changeEventVal->IsFunction()) {
443         return;
444     }
445     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
446     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
447     auto changeEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
448                            const std::string& info) {
449         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
450         ACE_SCORING_EVENT("DatePicker.SelectedDateTimeChangeEvent");
451         PipelineContext::SetCallBackNode(node);
452         auto dateObj = JSDate::New(GetMSByDate(info));
453         func->ExecuteJS(1, &dateObj);
454     };
455     CalendarPickerModel::GetInstance()->SetChangeEvent(std::move(changeEvent));
456 }
457 
ParseDisabledDateRange(const JSRef<JSVal> & disabledDateRangeVal,NG::CalendarSettingData & settingData)458 void JSCalendarPicker::ParseDisabledDateRange(
459     const JSRef<JSVal>& disabledDateRangeVal, NG::CalendarSettingData& settingData)
460 {
461     if (disabledDateRangeVal->IsUndefined() || disabledDateRangeVal->IsNull() || !disabledDateRangeVal->IsArray()) {
462         return;
463     }
464 
465     JSRef<JSArray> array = JSRef<JSArray>::Cast(disabledDateRangeVal);
466     for (size_t i = 0; i < array->Length(); i++) {
467         JSRef<JSVal> dateRangeValue = array->GetValueAt(i);
468         if (!dateRangeValue->IsObject()) {
469             continue;
470         }
471         auto dateRangeObj = JSRef<JSObject>::Cast(dateRangeValue);
472         auto startValue = dateRangeObj->GetProperty("start");
473         auto endValue = dateRangeObj->GetProperty("end");
474         if (startValue->IsObject() && endValue->IsObject()) {
475             auto startDate = ParseDate(startValue, false);
476             auto endDate = ParseDate(endValue, false);
477             if (startDate.GetYear() == 0 || endDate.GetYear() == 0 || endDate < startDate) {
478                 continue;
479             }
480             std::pair<PickerDate, PickerDate> pickerDateRange;
481             pickerDateRange.first = startDate;
482             pickerDateRange.second = endDate;
483             settingData.disabledDateRange.emplace_back(pickerDateRange);
484         }
485     }
486 }
487 
ParseHintRadius(JSRef<JSObject> & obj,NG::CalendarSettingData & settingData,CalcDimension & dayRadius)488 void JSCalendarPicker::ParseHintRadius(JSRef<JSObject>& obj, NG::CalendarSettingData& settingData,
489     CalcDimension& dayRadius)
490 {
491     RefPtr<CalendarTheme> calendarTheme = GetTheme<CalendarTheme>();
492     CHECK_NULL_VOID(calendarTheme);
493     if (SystemProperties::ConfigChangePerform()) {
494         RefPtr<ResourceObject> hintRadiusResObj;
495         if (!ParseJsDimensionVpNG(obj->GetProperty("hintRadius"), dayRadius, hintRadiusResObj)) {
496             dayRadius = calendarTheme->GetCalendarDayRadius();
497         }
498 
499         if (hintRadiusResObj) {
500             settingData.dayRadiusResObj = hintRadiusResObj;
501         }
502     } else {
503         if (!ParseJsDimensionVpNG(obj->GetProperty("hintRadius"), dayRadius)) {
504             dayRadius = calendarTheme->GetCalendarDayRadius();
505         }
506     }
507 }
508 
Create(const JSCallbackInfo & info)509 void JSCalendarPicker::Create(const JSCallbackInfo& info)
510 {
511     NG::CalendarSettingData settingData;
512     RefPtr<CalendarTheme> calendarTheme = GetTheme<CalendarTheme>();
513     CHECK_NULL_VOID(calendarTheme);
514     CalcDimension dayRadius;
515     if (info[0]->IsObject()) {
516         auto obj = JSRef<JSObject>::Cast(info[0]);
517         ParseHintRadius(obj, settingData, dayRadius);
518 
519         auto selected = obj->GetProperty("selected");
520         auto parseSelectedDate = ParseDate(selected);
521         if (selected->IsObject() && parseSelectedDate.GetYear() != 0) {
522             JSRef<JSObject> selectedDateObj = JSRef<JSObject>::Cast(selected);
523             JSRef<JSVal> changeEventVal = selectedDateObj->GetProperty("changeEvent");
524             if (!changeEventVal->IsUndefined() && changeEventVal->IsFunction()) {
525                 ParseSelectedDateObject(info, selectedDateObj);
526                 settingData.selectedDate = ParseDate(selectedDateObj->GetProperty("value"));
527             } else {
528                 settingData.selectedDate = parseSelectedDate;
529             }
530         }
531         auto disabledDateRange = obj->GetProperty("disabledDateRange");
532         ParseDisabledDateRange(disabledDateRange, settingData);
533         PickerDate::SortAndMergeDisabledDateRange(settingData.disabledDateRange);
534         auto startDate = obj->GetProperty("start");
535         auto endDate = obj->GetProperty("end");
536         auto parseStartDate = ParseDate(startDate, false);
537         auto parseEndDate = ParseDate(endDate, false);
538         if (parseEndDate.GetYear() > 0 && parseStartDate.ToDays() > parseEndDate.ToDays()) {
539             parseStartDate = PickerDate();
540             parseEndDate = PickerDate();
541         }
542         settingData.startDate = parseStartDate;
543         settingData.endDate = parseEndDate;
544     } else {
545         dayRadius = calendarTheme->GetCalendarDayRadius();
546     }
547     settingData.dayRadius = dayRadius;
548     CalendarPickerModel::GetInstance()->Create(settingData);
549 }
550 
ParseTextStyle(const JSRef<JSObject> & paramObj,NG::PickerTextStyle & textStyle)551 void JSCalendarPicker::ParseTextStyle(const JSRef<JSObject>& paramObj, NG::PickerTextStyle& textStyle)
552 {
553     auto fontColor = paramObj->GetProperty("color");
554     auto fontStyle = paramObj->GetProperty("font");
555 
556     Color color;
557     if (ParseJsColor(fontColor, color, textStyle.textColorResObj)) {
558         textStyle.textColor = color;
559         textStyle.textColorSetByUser = true;
560     }
561 
562     if (!fontStyle->IsObject()) {
563         return;
564     }
565     JSRef<JSObject> fontObj = JSRef<JSObject>::Cast(fontStyle);
566     auto fontSize = fontObj->GetProperty("size");
567     auto fontWeight = fontObj->GetProperty("weight");
568     if (fontSize->IsNull() || fontSize->IsUndefined()) {
569         textStyle.fontSize = Dimension(-1);
570     } else {
571         CalcDimension size;
572         if (!ParseJsDimensionFpNG(fontSize, size, textStyle.fontSizeResObj) || size.Unit() == DimensionUnit::PERCENT) {
573             textStyle.fontSize = Dimension(-1);
574         } else {
575             textStyle.fontSize = size;
576         }
577     }
578 
579     if (!fontWeight->IsNull() && !fontWeight->IsUndefined()) {
580         std::string weight;
581         if (fontWeight->IsNumber()) {
582             weight = std::to_string(fontWeight->ToNumber<int32_t>());
583         } else {
584             ParseJsString(fontWeight, weight);
585         }
586         textStyle.fontWeight = ConvertStrToFontWeight(weight);
587     }
588 }
589 
ParseDate(const JSRef<JSVal> & dateVal,bool useCurrentDate)590 PickerDate JSCalendarPicker::ParseDate(const JSRef<JSVal>& dateVal, bool useCurrentDate)
591 {
592     auto pickerDate = useCurrentDate ? PickerDate::Current() : PickerDate();
593     if (!dateVal->IsObject()) {
594         return pickerDate;
595     }
596     auto dateObj = JSRef<JSObject>::Cast(dateVal);
597     auto yearFuncJsVal = dateObj->GetProperty("getFullYear");
598     auto monthFuncJsVal = dateObj->GetProperty("getMonth");
599     auto dateFuncJsVal = dateObj->GetProperty("getDate");
600     if (!(yearFuncJsVal->IsFunction() && monthFuncJsVal->IsFunction() && dateFuncJsVal->IsFunction())) {
601         return pickerDate;
602     }
603     auto yearFunc = JSRef<JSFunc>::Cast(yearFuncJsVal);
604     auto monthFunc = JSRef<JSFunc>::Cast(monthFuncJsVal);
605     auto dateFunc = JSRef<JSFunc>::Cast(dateFuncJsVal);
606     JSRef<JSVal> year = yearFunc->Call(dateObj);
607     JSRef<JSVal> month = monthFunc->Call(dateObj);
608     JSRef<JSVal> date = dateFunc->Call(dateObj);
609 
610     if (year->IsNumber() && month->IsNumber() && date->IsNumber()) {
611         pickerDate.SetYear(year->ToNumber<int32_t>());
612         pickerDate.SetMonth(month->ToNumber<int32_t>() + 1); // 0-11 means 1 to 12 months
613         pickerDate.SetDay(date->ToNumber<int32_t>());
614     }
615     return pickerDate;
616 }
617 
JsMarkToday(const JSCallbackInfo & info)618 void JSCalendarPicker::JsMarkToday(const JSCallbackInfo& info)
619 {
620     bool isMarkToday = false;
621     if (info[0]->IsBoolean()) {
622         isMarkToday = info[0]->ToBoolean();
623     }
624     CalendarPickerModel::GetInstance()->SetMarkToday(isMarkToday);
625 }
626 
JSBind(BindingTarget globalObj)627 void JSCalendarPickerDialog::JSBind(BindingTarget globalObj)
628 {
629     JSClass<JSCalendarPickerDialog>::Declare("CalendarPickerDialog");
630     JSClass<JSCalendarPickerDialog>::StaticMethod("show", &JSCalendarPickerDialog::Show);
631     JSClass<JSCalendarPickerDialog>::Bind<>(globalObj);
632 }
633 
Show(const JSCallbackInfo & info)634 void JSCalendarPickerDialog::Show(const JSCallbackInfo& info)
635 {
636     auto scopedDelegate = EngineHelper::GetCurrentDelegateSafely();
637     CHECK_NULL_VOID(scopedDelegate);
638     if (!info[0]->IsObject()) {
639         return;
640     }
641 
642     if (Container::IsCurrentUseNewPipeline()) {
643         auto paramObject = JSRef<JSObject>::Cast(info[0]);
644         auto buttonInfos = ParseButtonStyles(paramObject);
645         auto dialogEvent = ChangeDialogEvent(info);
646         auto dialogCancelEvent = DialogCancelEvent(info);
647         auto dialogLifeCycleEvent = LifeCycleDialogEvent(info);
648         CalendarPickerDialogShow(paramObject, dialogEvent, dialogCancelEvent, dialogLifeCycleEvent, buttonInfos);
649     }
650 }
651 
ChangeDialogEvent(const JSCallbackInfo & info)652 std::map<std::string, NG::DialogEvent> JSCalendarPickerDialog::ChangeDialogEvent(const JSCallbackInfo& info)
653 {
654     std::map<std::string, NG::DialogEvent> dialogEvent;
655     if (!info[0]->IsObject()) {
656         return dialogEvent;
657     }
658     auto paramObject = JSRef<JSObject>::Cast(info[0]);
659     auto onChange = paramObject->GetProperty("onChange");
660     if (!onChange->IsUndefined() && onChange->IsFunction()) {
661         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onChange));
662         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
663         auto changeId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
664                             const std::string& info) {
665             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
666             ACE_SCORING_EVENT("CalendarDialog.onChange");
667             PipelineContext::SetCallBackNode(node);
668             auto dateObj = JSDate::New(GetMSByDate(info));
669             func->ExecuteJS(1, &dateObj);
670         };
671         dialogEvent["changeId"] = changeId;
672     }
673     auto onAccept = paramObject->GetProperty("onAccept");
674     if (!onAccept->IsUndefined() && onAccept->IsFunction()) {
675         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAccept));
676         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
677         auto acceptId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
678                             const std::string& info) {
679             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
680             ACE_SCORING_EVENT("CalendarDialog.onAccept");
681             PipelineContext::SetCallBackNode(node);
682             auto dateObj = JSDate::New(GetMSByDate(info));
683             func->ExecuteJS(1, &dateObj);
684         };
685         dialogEvent["acceptId"] = acceptId;
686     }
687     return dialogEvent;
688 }
689 
DialogCancelEvent(const JSCallbackInfo & info)690 std::map<std::string, NG::DialogGestureEvent> JSCalendarPickerDialog::DialogCancelEvent(const JSCallbackInfo& info)
691 {
692     std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent;
693     if (!info[0]->IsObject()) {
694         return dialogCancelEvent;
695     }
696     auto paramObject = JSRef<JSObject>::Cast(info[0]);
697     auto onCancel = paramObject->GetProperty("onCancel");
698     if (!onCancel->IsUndefined() && onCancel->IsFunction()) {
699         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onCancel));
700         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
701         auto cancelId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
702                             const GestureEvent& /* info */) {
703             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
704             ACE_SCORING_EVENT("CalendarDialog.onCancel");
705             PipelineContext::SetCallBackNode(node);
706             func->Execute();
707         };
708         dialogCancelEvent["cancelId"] = cancelId;
709     }
710     return dialogCancelEvent;
711 }
712 
AppearDialogEvent(const JSCallbackInfo & info,std::map<std::string,NG::DialogCancelEvent> & dialogLifeCycleEvent)713 void AppearDialogEvent(const JSCallbackInfo& info, std::map<std::string, NG::DialogCancelEvent>& dialogLifeCycleEvent)
714 {
715     if (!info[0]->IsObject()) {
716         return;
717     }
718     auto paramObject = JSRef<JSObject>::Cast(info[0]);
719     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
720     auto onDidAppear = paramObject->GetProperty("onDidAppear");
721     if (!onDidAppear->IsUndefined() && onDidAppear->IsFunction()) {
722         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidAppear));
723         auto didAppearId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
724             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
725             ACE_SCORING_EVENT("CalendarDialog.onDidAppear");
726             PipelineContext::SetCallBackNode(node);
727             func->Execute();
728         };
729         dialogLifeCycleEvent["didAppearId"] = didAppearId;
730     }
731     auto onWillAppear = paramObject->GetProperty("onWillAppear");
732     if (!onWillAppear->IsUndefined() && onWillAppear->IsFunction()) {
733         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillAppear));
734         auto willAppearId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
735             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
736             ACE_SCORING_EVENT("CalendarDialog.onWillAppear");
737             PipelineContext::SetCallBackNode(node);
738             func->Execute();
739         };
740         dialogLifeCycleEvent["willAppearId"] = willAppearId;
741     }
742 }
743 
DisappearDialogEvent(const JSCallbackInfo & info,std::map<std::string,NG::DialogCancelEvent> & dialogLifeCycleEvent)744 void DisappearDialogEvent(
745     const JSCallbackInfo& info, std::map<std::string, NG::DialogCancelEvent>& dialogLifeCycleEvent)
746 {
747     if (!info[0]->IsObject()) {
748         return;
749     }
750     auto paramObject = JSRef<JSObject>::Cast(info[0]);
751     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
752     auto onDidDisappear = paramObject->GetProperty("onDidDisappear");
753     if (!onDidDisappear->IsUndefined() && onDidDisappear->IsFunction()) {
754         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidDisappear));
755         auto didDisappearId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
756             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
757             ACE_SCORING_EVENT("CalendarDialog.onDidDisappear");
758             PipelineContext::SetCallBackNode(node);
759             func->Execute();
760         };
761         dialogLifeCycleEvent["didDisappearId"] = didDisappearId;
762     }
763     auto onWillDisappear = paramObject->GetProperty("onWillDisappear");
764     if (!onWillDisappear->IsUndefined() && onWillDisappear->IsFunction()) {
765         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDisappear));
766         auto willDisappearId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
767                                       node = targetNode]() {
768             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
769             ACE_SCORING_EVENT("CalendarDialog.onWillDisappear");
770             PipelineContext::SetCallBackNode(node);
771             func->Execute();
772         };
773         dialogLifeCycleEvent["willDisappearId"] = willDisappearId;
774     }
775 }
776 
LifeCycleDialogEvent(const JSCallbackInfo & info)777 std::map<std::string, NG::DialogCancelEvent> JSCalendarPickerDialog::LifeCycleDialogEvent(const JSCallbackInfo& info)
778 {
779     std::map<std::string, NG::DialogCancelEvent> dialogLifeCycleEvent;
780     if (!info[0]->IsObject()) {
781         return dialogLifeCycleEvent;
782     }
783     AppearDialogEvent(info, dialogLifeCycleEvent);
784     DisappearDialogEvent(info, dialogLifeCycleEvent);
785     return dialogLifeCycleEvent;
786 }
787 
ParseDate(const JSRef<JSVal> & dateVal,bool useCurrentDate)788 PickerDate JSCalendarPickerDialog::ParseDate(const JSRef<JSVal>& dateVal, bool useCurrentDate)
789 {
790     auto pickerDate = useCurrentDate ? PickerDate::Current() : PickerDate();
791     if (!dateVal->IsObject()) {
792         return pickerDate;
793     }
794     auto dateObj = JSRef<JSObject>::Cast(dateVal);
795 
796     auto yearFuncJsVal = dateObj->GetProperty("getFullYear");
797     auto monthFuncJsVal = dateObj->GetProperty("getMonth");
798     auto dateFuncJsVal = dateObj->GetProperty("getDate");
799     if (!(yearFuncJsVal->IsFunction() && monthFuncJsVal->IsFunction() && dateFuncJsVal->IsFunction())) {
800         return pickerDate;
801     }
802     auto yearFunc = JSRef<JSFunc>::Cast(yearFuncJsVal);
803     auto monthFunc = JSRef<JSFunc>::Cast(monthFuncJsVal);
804     auto dateFunc = JSRef<JSFunc>::Cast(dateFuncJsVal);
805     JSRef<JSVal> year = yearFunc->Call(dateObj);
806     JSRef<JSVal> month = monthFunc->Call(dateObj);
807     JSRef<JSVal> date = dateFunc->Call(dateObj);
808 
809     if (year->IsNumber() && month->IsNumber() && date->IsNumber()) {
810         pickerDate.SetYear(year->ToNumber<int32_t>());
811         pickerDate.SetMonth(month->ToNumber<int32_t>() + 1); // 0-11 means 1 to 12 months
812         pickerDate.SetDay(date->ToNumber<int32_t>());
813     }
814     return pickerDate;
815 }
816 
ParseDisabledDateRange(const JSRef<JSVal> & disabledDateRangeVal,NG::CalendarSettingData & settingData)817 void JSCalendarPickerDialog::ParseDisabledDateRange(
818     const JSRef<JSVal>& disabledDateRangeVal, NG::CalendarSettingData& settingData)
819 {
820     if (disabledDateRangeVal->IsUndefined() || disabledDateRangeVal->IsNull() || !disabledDateRangeVal->IsArray()) {
821         return;
822     }
823 
824     JSRef<JSArray> array = JSRef<JSArray>::Cast(disabledDateRangeVal);
825     for (size_t i = 0; i < array->Length(); i++) {
826         JSRef<JSVal> dateRangeValue = array->GetValueAt(i);
827         auto dateRangeObj = JSRef<JSObject>::Cast(dateRangeValue);
828         auto startValue = dateRangeObj->GetProperty("start");
829         auto endValue = dateRangeObj->GetProperty("end");
830         if (startValue->IsObject() && endValue->IsObject()) {
831             auto startDate = ParseDate(startValue);
832             auto endDate = ParseDate(endValue);
833             if (startDate.GetYear() == 0 || endDate.GetYear() == 0 || endDate < startDate)
834                 continue;
835             std::pair<PickerDate, PickerDate> pickerDateRange;
836             pickerDateRange.first = startDate;
837             pickerDateRange.second = endDate;
838             settingData.disabledDateRange.emplace_back(pickerDateRange);
839         }
840     }
841 }
842 
CalendarPickerDialogShow(const JSRef<JSObject> & paramObj,const std::map<std::string,NG::DialogEvent> & dialogEvent,const std::map<std::string,NG::DialogGestureEvent> & dialogCancelEvent,const std::map<std::string,NG::DialogCancelEvent> & dialogLifeCycleEvent,const std::vector<ButtonInfo> & buttonInfos)843 void JSCalendarPickerDialog::CalendarPickerDialogShow(const JSRef<JSObject>& paramObj,
844     const std::map<std::string, NG::DialogEvent>& dialogEvent,
845     const std::map<std::string, NG::DialogGestureEvent>& dialogCancelEvent,
846     const std::map<std::string, NG::DialogCancelEvent>& dialogLifeCycleEvent,
847     const std::vector<ButtonInfo>& buttonInfos)
848 {
849     auto container = Container::CurrentSafely();
850     CHECK_NULL_VOID(container);
851     auto pipelineContext = AccessibilityManager::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
852     CHECK_NULL_VOID(pipelineContext);
853     auto executor = pipelineContext->GetTaskExecutor();
854     CHECK_NULL_VOID(executor);
855 
856     auto theme = GetTheme<DialogTheme>();
857     CHECK_NULL_VOID(theme);
858     auto calendarTheme = pipelineContext->GetTheme<CalendarTheme>();
859     NG::CalendarSettingData settingData;
860     auto markToday = paramObj->GetProperty("markToday");
861     bool isMarkToday = false;
862     if (markToday->IsBoolean()) {
863         isMarkToday = markToday->ToBoolean();
864     }
865     settingData.markToday = isMarkToday;
866     auto disabledDateRange = paramObj->GetProperty("disabledDateRange");
867     ParseDisabledDateRange(disabledDateRange, settingData);
868     PickerDate::SortAndMergeDisabledDateRange(settingData.disabledDateRange);
869     auto selectedDate = paramObj->GetProperty("selected");
870     auto parseSelectedDate = ParseDate(selectedDate, true);
871 
872     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
873         auto startDate = paramObj->GetProperty("start");
874         auto endDate = paramObj->GetProperty("end");
875         auto parseStartDate = ParseDate(startDate);
876         auto parseEndDate = ParseDate(endDate);
877         if (parseEndDate.GetYear() > 0 && parseStartDate.ToDays() > parseEndDate.ToDays()) {
878             parseStartDate = PickerDate();
879             parseEndDate = PickerDate();
880         }
881         settingData.startDate = parseStartDate;
882         settingData.endDate = parseEndDate;
883         parseSelectedDate = PickerDate::AdjustDateToRange(parseSelectedDate, parseStartDate, parseEndDate);
884     }
885 
886     if (parseSelectedDate.GetYear() != 0) {
887         settingData.selectedDate = parseSelectedDate;
888     }
889 
890     CalcDimension radius;
891     if (ParseJsDimensionVpNG(paramObj->GetProperty("hintRadius"), radius)) {
892         settingData.dayRadius = radius;
893     }
894 
895     DialogProperties properties;
896     properties.alignment = theme->GetAlignment();
897     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
898         properties.alignment = DialogAlignment::CENTER;
899     }
900 
901     auto backgroundColorValue = paramObj->GetProperty("backgroundColor");
902     Color backgroundColor;
903     if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor)) {
904         properties.backgroundColor = backgroundColor;
905     }
906 
907     auto backgroundBlurStyle = paramObj->GetProperty("backgroundBlurStyle");
908     if (backgroundBlurStyle->IsNumber()) {
909         auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>();
910         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
911             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
912             properties.backgroundBlurStyle = blurStyle;
913         }
914     }
915 
916     auto shadowValue = paramObj->GetProperty("shadow");
917     Shadow shadow;
918     if ((shadowValue->IsObject() || shadowValue->IsNumber()) && JSViewAbstract::ParseShadowProps(shadowValue, shadow)) {
919         properties.shadow = shadow;
920     }
921 
922     properties.customStyle = false;
923     if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TWELVE)) {
924         properties.offset = DimensionOffset(Offset(0, -theme->GetMarginBottom().ConvertToPx()));
925         NG::BorderRadiusProperty dialogRadius;
926         dialogRadius.SetRadius(calendarTheme->GetDialogBorderRadius());
927         properties.borderRadius = dialogRadius;
928     }
929 
930     properties.hoverModeArea = HoverModeAreaType::BOTTOM_SCREEN;
931     JSViewAbstract::SetDialogHoverModeProperties(paramObj, properties);
932     JSViewAbstract::SetDialogBlurStyleOption(paramObj, properties);
933     JSViewAbstract::SetDialogEffectOption(paramObj, properties);
934 
935     auto context = AccessibilityManager::DynamicCast<NG::PipelineContext>(pipelineContext);
936     auto overlayManager = context ? context->GetOverlayManager() : nullptr;
937     executor->PostTask(
938         [properties, settingData, dialogEvent, dialogCancelEvent, dialogLifeCycleEvent, buttonInfos,
939             weak = WeakPtr<NG::OverlayManager>(overlayManager)] {
940             auto overlayManager = weak.Upgrade();
941             CHECK_NULL_VOID(overlayManager);
942             overlayManager->ShowCalendarDialog(
943                 properties, settingData, dialogEvent, dialogCancelEvent, dialogLifeCycleEvent, buttonInfos);
944         },
945         TaskExecutor::TaskType::UI, "ArkUIDialogShowCalendarPicker",
946         TaskExecutor::GetPriorityTypeWithCheck(PriorityType::VIP));
947 }
948 } // namespace OHOS::Ace::Framework
949