• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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/common/dom/dom_calendar.h"
17 
18 #include "base/utils/string_utils.h"
19 #include "frameworks/bridge/common/utils/utils.h"
20 
21 namespace OHOS::Ace::Framework {
22 namespace {
23 
24 constexpr uint32_t METHOD_GO_TO_ARGS_SIZE = 1;
25 const char GO_TO_ARG_KEY_YEAR[] = "year";
26 const char GO_TO_ARG_KEY_MONTH[] = "month";
27 const char GO_TO_ARG_KEY_DAY[] = "day";
28 
29 } // namespace
30 
DomCalendar(NodeId nodeId,const std::string & nodeName)31 DomCalendar::DomCalendar(NodeId nodeId, const std::string& nodeName)
32     : DOMNode(nodeId, nodeName),
33       calendarComponent_(AceType::MakeRefPtr<CalendarComponent>(std::to_string(nodeId), nodeName))
34 {
35     if (IsRightToLeft()) {
36         calendarComponent_->SetTextDirection(TextDirection::RTL);
37     }
38 }
39 
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)40 bool DomCalendar::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
41 {
42     static const LinearMapNode<bool (*)(const std::string&, DomCalendar&)> calendarAttrOperators[] = {
43         { DOM_CALENDAR_DATA,
44             [](const std::string& value, DomCalendar& calendar) {
45                 calendar.calendarComponent_->SetCalendarData(value);
46                 return true;
47             } },
48         { DOM_CALENDAR_CARD_CALENDAR,
49             [](const std::string& value, DomCalendar& calendar) {
50                 calendar.calendarComponent_->SetCardCalendar(StringToBool(value));
51                 return true;
52             } },
53         { DOM_CALENDAR_DATE,
54             [](const std::string& value, DomCalendar& calendar) {
55                 CalendarDay day;
56                 auto isLegal = StringUtils::StringToCalendarDay(value, day);
57                 if (isLegal) {
58                     calendar.calendarComponent_->SetCalendarDate(day);
59                     return true;
60                 }
61                 return false;
62             } },
63         { DOM_CALENDAR_DATE_ADAPTER,
64             [](const std::string& value, DomCalendar& calendar) { return calendar.ParseDataAdapter(value); } },
65         { DOM_CALENDAR_DIRECTION,
66             [](const std::string& value, DomCalendar& calendar) {
67               if (value == "vertical") {
68                   calendar.calendarComponent_->SetAxis(Axis::VERTICAL);
69               } else if (value == "horizontal") {
70                   calendar.calendarComponent_->SetAxis(Axis::HORIZONTAL);
71               } else {
72                   LOGE("input do not match any direction");
73               }
74               return true;
75             } },
76         { DOM_CALENDAR_HOLIDAYS,
77             [](const std::string& value, DomCalendar& calendar) {
78                 calendar.calendarComponent_->SetHolidays(value);
79                 return true;
80             } },
81         { DOM_CALENDAR_OFF_DAYS,
82             [](const std::string& value, DomCalendar& calendar) {
83                 calendar.calendarComponent_->SetOffDays(value);
84                 return true;
85             } },
86         { DOM_CALENDAR_SHOW_HOLIDAY,
87             [](const std::string& value, DomCalendar& calendar) {
88                 calendar.calendarComponent_->SetShowHoliday(StringToBool(value));
89                 return true;
90             } },
91         { DOM_CALENDAR_SHOW_LUNAR,
92             [](const std::string& value, DomCalendar& calendar) {
93                 calendar.calendarComponent_->SetShowLunar(StringToBool(value));
94                 return true;
95             } },
96         { DOM_CALENDAR_START_DAY_OF_WEEK,
97             [](const std::string& value, DomCalendar& calendar) {
98                 auto indexOfWeek = StringToInt(value);
99                 if (0 <= indexOfWeek && indexOfWeek < 7) {
100                     calendar.calendarComponent_->SetStartDayOfWeek(indexOfWeek);
101                     return true;
102                 }
103                 return false;
104             } },
105         { DOM_CALENDAR_TYPE,
106             [](const std::string& value, DomCalendar& calendar) {
107                 if (value == "normal") {
108                     calendar.calendarComponent_->SetCalendarType(CalendarType::NORMAL);
109                 } else if (value == "simple") {
110                     calendar.calendarComponent_->SetCalendarType(CalendarType::SIMPLE);
111                 }
112                 return true;
113             } },
114         { DOM_CALENDAR_WORK_DAYS,
115             [](const std::string& value, DomCalendar& calendar) {
116                 calendar.calendarComponent_->SetWorkDays(value);
117                 return true;
118             } },
119     };
120     auto operatorIter =
121         BinarySearchFindIndex(calendarAttrOperators, ArraySize(calendarAttrOperators), attr.first.c_str());
122     if (operatorIter != -1) {
123         return calendarAttrOperators[operatorIter].value(attr.second, *this);
124     }
125     return false;
126 }
127 
CallSpecializedMethod(const std::string & method,const std::string & args)128 void DomCalendar::CallSpecializedMethod(const std::string& method, const std::string& args)
129 {
130     if (method == DOM_CALENDAR_METHOD_GO_TO) {
131         HandleGoTo(args);
132     }
133 }
134 
AddSpecializedEvent(int32_t pageId,const std::string & event)135 bool DomCalendar::AddSpecializedEvent(int32_t pageId, const std::string& event)
136 {
137     if (event == DOM_CALENDAR_EVENT_SELECTED_CHANGE) {
138         selectedChangeEvent_ = EventMarker(GetNodeIdForEvent(), event, pageId);
139         calendarComponent_->SetSelectedChangeEvent(selectedChangeEvent_);
140         return true;
141     } else if (event == DOM_CALENDAR_EVENT_REQUEST_DATA) {
142         requestDataEvent_ = EventMarker(GetNodeIdForEvent(), event, pageId);
143         calendarComponent_->SetRequestDataEvent(requestDataEvent_);
144         return true;
145     }
146     return false;
147 }
148 
ParseDataAdapter(const std::string & value)149 bool DomCalendar::ParseDataAdapter(const std::string& value)
150 {
151     std::unique_ptr<JsonValue> dataAdapterValue = JsonUtil::ParseJsonString(value);
152     if (!dataAdapterValue) {
153         LOGE("data adapter format is error");
154         return false;
155     }
156     std::unique_ptr<JsonValue> bundleNameValue = dataAdapterValue->GetValue("bundleName");
157     if (!bundleNameValue || !bundleNameValue->IsString()) {
158         LOGE("get bundleName failed");
159         return false;
160     }
161     std::unique_ptr<JsonValue> abilityNameValue = dataAdapterValue->GetValue("abilityName");
162     if (!abilityNameValue || !abilityNameValue->IsString()) {
163         LOGE("get abilityName failed");
164         return false;
165     }
166     std::unique_ptr<JsonValue> messageCodeValue = dataAdapterValue->GetValue("messageCode");
167     if (!messageCodeValue || !messageCodeValue->IsNumber()) {
168         LOGE("get messageCode failed");
169         return false;
170     }
171     std::string bundleName = bundleNameValue->GetString();
172     std::string abilityName = abilityNameValue->GetString();
173     int32_t messageCode = messageCodeValue->GetInt();
174     CalendarDataAdapterAction dataAdapterAction {
175         { .bundleName = bundleName, .abilityName = abilityName, .messageCode = messageCode }
176     };
177     calendarComponent_->SetDataAdapterAction(dataAdapterAction);
178     return true;
179 }
180 
HandleGoTo(const std::string & args)181 void DomCalendar::HandleGoTo(const std::string& args)
182 {
183     std::unique_ptr<JsonValue> argsValue = JsonUtil::ParseJsonString(args);
184     if (!argsValue || !argsValue->IsArray() || argsValue->GetArraySize() != METHOD_GO_TO_ARGS_SIZE) {
185         LOGE("parse args error: %{private}s", args.c_str());
186         return;
187     }
188     auto gotoArg = argsValue->GetArrayItem(0);
189     if (!gotoArg || !gotoArg->Contains(GO_TO_ARG_KEY_YEAR) || !gotoArg->Contains(GO_TO_ARG_KEY_MONTH)) {
190         LOGE("calendar goto arg no year or month");
191         return;
192     }
193 
194     std::unique_ptr<JsonValue> yearValue = gotoArg->GetValue(GO_TO_ARG_KEY_YEAR);
195     if (!yearValue || !yearValue->IsNumber()) {
196         LOGE("get year failed");
197         return;
198     }
199 
200     std::unique_ptr<JsonValue> monthValue = gotoArg->GetValue(GO_TO_ARG_KEY_MONTH);
201     if (!monthValue || !monthValue->IsNumber()) {
202         LOGE("get month failed");
203         return;
204     }
205     int32_t year = yearValue->GetInt();
206     int32_t month = monthValue->GetInt();
207     // default selected first day of month
208     int32_t day = -1;
209 
210     std::unique_ptr<JsonValue> dayValue = gotoArg->GetValue(GO_TO_ARG_KEY_DAY);
211     if (dayValue && dayValue->IsNumber()) {
212         day = dayValue->GetInt();
213     }
214     calendarComponent_->GoTo(year, month, day);
215 }
216 
SetSpecializedStyle(const std::pair<std::string,std::string> & style)217 bool DomCalendar::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
218 {
219     static const LinearMapNode<void (*)(const std::string&, CalendarThemeStructure&, const DomCalendar&)>
220         calendarStyleOperators[] = {
221             { "boundaryColumnOffset",
222                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
223                     theme.boundaryColOffset = node.ParseDimension(value);
224                 } },
225             { "boundaryRowOffset",
226                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
227                     theme.boundaryRowOffset = node.ParseDimension(value);
228                 } },
229             { "columnSpace", [](const std::string& value, CalendarThemeStructure& theme,
230                                  const DomCalendar& node) { theme.colSpace = node.ParseDimension(value); } },
231             { "dailyFiveRowSpace",
232                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
233                     theme.dailyFiveRowSpace = node.ParseDimension(value);
234                 } },
235             { "dailySixRowSpace",
236                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
237                     theme.dailySixRowSpace = node.ParseDimension(value);
238                 } },
239             { "dayColor", [](const std::string& value, CalendarThemeStructure& theme,
240                               const DomCalendar& node) { theme.dayColor = node.ParseColor(value); } },
241             { "dayFontSize", [](const std::string& value, CalendarThemeStructure& theme,
242                                  const DomCalendar& node) { theme.dayFontSize = node.ParseDimension(value); } },
243             { "dayHeight", [](const std::string& value, CalendarThemeStructure& theme,
244                                const DomCalendar& node) { theme.dayHeight = node.ParseDimension(value); } },
245             { "dayWidth", [](const std::string& value, CalendarThemeStructure& theme,
246                               const DomCalendar& node) { theme.dayWidth = node.ParseDimension(value); } },
247             { "dayYAxisOffset", [](const std::string& value, CalendarThemeStructure& theme,
248                                     const DomCalendar& node) { theme.dayYAxisOffset = node.ParseDimension(value); } },
249             { "focusedAreaBackgroundColor",
250                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
251                     theme.focusedAreaBackgroundColor = node.ParseColor(value);
252                 } },
253             { "focusedAreaRadius",
254                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
255                     theme.focusedAreaRadius = node.ParseDimension(value);
256                 } },
257             { "focusedDayColor", [](const std::string& value, CalendarThemeStructure& theme,
258                                      const DomCalendar& node) { theme.focusedDayColor = node.ParseColor(value); } },
259             { "focusedLunarColor", [](const std::string& value, CalendarThemeStructure& theme,
260                                        const DomCalendar& node) { theme.focusedLunarColor = node.ParseColor(value); } },
261             { "gregorianCalendarHeight",
262                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
263                     theme.gregorianCalendarHeight = node.ParseDimension(value);
264                 } },
265             { "lunarColor", [](const std::string& value, CalendarThemeStructure& theme,
266                                 const DomCalendar& node) { theme.lunarColor = node.ParseColor(value); } },
267             { "lunarDayFontSize",
268                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
269                     theme.lunarDayFontSize = node.ParseDimension(value);
270                 } },
271             { "lunarDayYAxisOffset",
272                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
273                     theme.lunarDayYAxisOffset = node.ParseDimension(value);
274                 } },
275             { "lunarHeight", [](const std::string& value, CalendarThemeStructure& theme,
276                                  const DomCalendar& node) { theme.lunarHeight = node.ParseDimension(value); } },
277             { "markLunarColor", [](const std::string& value, CalendarThemeStructure& theme,
278                                     const DomCalendar& node) { theme.markLunarColor = node.ParseColor(value); } },
279             { "nonCurrentMonthDayColor",
280                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
281                     theme.nonCurrentMonthDayColor = node.ParseColor(value);
282                 } },
283             { "nonCurrentMonthLunarColor",
284                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
285                     theme.nonCurrentMonthLunarColor = node.ParseColor(value);
286                 } },
287             { "nonCurrentMonthOffDayMarkColor",
288                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
289                     theme.nonCurrentMonthOffDayMarkColor = node.ParseColor(value);
290                 } },
291             { "nonCurrentMonthWorkDayMarkColor",
292                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
293                     theme.nonCurrentMonthWorkDayMarkColor = node.ParseColor(value);
294                 } },
295             { "offDayMarkColor", [](const std::string& value, CalendarThemeStructure& theme,
296                                      const DomCalendar& node) { theme.offDayMarkColor = node.ParseColor(value); } },
297             { "offDayMarkSize", [](const std::string& value, CalendarThemeStructure& theme,
298                                     const DomCalendar& node) { theme.offDayMarkSize = node.ParseDimension(value); } },
299             { "scheduleMarkerRadius",
300                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
301                     theme.scheduleMarkerRadius = node.ParseDimension(value);
302                 } },
303             { "scheduleMarkerXAxisOffset",
304                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
305                     theme.scheduleMarkerXAxisOffset = node.ParseDimension(value);
306                 } },
307             { "scheduleMarkerYAxisOffset",
308                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
309                     theme.scheduleMarkerYAxisOffset = node.ParseDimension(value);
310                 } },
311             { "simpleOffTextColor",
312                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
313                     theme.simpleOffTextColor = node.ParseColor(value);
314                 } },
315             { "simpleWorkTextColor",
316                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
317                     theme.simpleWorkTextColor = node.ParseColor(value);
318                 } },
319             { "underscoreLength",
320                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
321                     theme.underscoreLength = node.ParseDimension(value);
322                 } },
323             { "underscoreWidth", [](const std::string& value, CalendarThemeStructure& theme,
324                                      const DomCalendar& node) { theme.underscoreWidth = node.ParseDimension(value); } },
325             { "underscoreXAxisOffset",
326                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
327                     theme.underscoreXAxisOffset = node.ParseDimension(value);
328                 } },
329             { "underscoreYAxisOffset",
330                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
331                     theme.underscoreYAxisOffset = node.ParseDimension(value);
332                 } },
333             { "weekAndDayRowSpace",
334                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
335                     theme.weekAndDayRowSpace = node.ParseDimension(value);
336                 } },
337             { "weekColor", [](const std::string& value, CalendarThemeStructure& theme,
338                                const DomCalendar& node) { theme.weekColor = node.ParseColor(value); } },
339             { "weekFontSize", [](const std::string& value, CalendarThemeStructure& theme,
340                                   const DomCalendar& node) { theme.weekFontSize = node.ParseDimension(value); } },
341             { "weekHeight", [](const std::string& value, CalendarThemeStructure& theme,
342                                 const DomCalendar& node) { theme.weekHeight = node.ParseDimension(value); } },
343             { "weekWidth", [](const std::string& value, CalendarThemeStructure& theme,
344                                const DomCalendar& node) { theme.weekWidth = node.ParseDimension(value); } },
345             { "weekendDayColor", [](const std::string& value, CalendarThemeStructure& theme,
346                                      const DomCalendar& node) { theme.weekendDayColor = node.ParseColor(value); } },
347             { "weekendLunarColor", [](const std::string& value, CalendarThemeStructure& theme,
348                                        const DomCalendar& node) { theme.weekendLunarColor = node.ParseColor(value); } },
349             { "workDayMarkColor", [](const std::string& value, CalendarThemeStructure& theme,
350                                       const DomCalendar& node) { theme.workDayMarkColor = node.ParseColor(value); } },
351             { "workDayMarkSize", [](const std::string& value, CalendarThemeStructure& theme,
352                                      const DomCalendar& node) { theme.workDayMarkSize = node.ParseDimension(value); } },
353             { "workStateHorizontalMovingDistance",
354                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
355                     theme.workStateHorizontalMovingDistance = node.ParseDimension(value);
356                 } },
357             { "workStateOffset", [](const std::string& value, CalendarThemeStructure& theme,
358                                      const DomCalendar& node) { theme.workStateOffset = node.ParseDimension(value); } },
359             { "workStateVerticalMovingDistance",
360                 [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
361                     theme.workStateVerticalMovingDistance = node.ParseDimension(value);
362                 } },
363             { "workStateWidth", [](const std::string& value, CalendarThemeStructure& theme,
364                                     const DomCalendar& node) { theme.workStateWidth = node.ParseDimension(value); } },
365         };
366     auto context = GetPipelineContext().Upgrade();
367     if (!context) {
368         return false;
369     }
370     auto theme = calendarComponent_->GetCalendarTheme();
371     if (!theme) {
372         theme = GetTheme<CalendarTheme>();
373         calendarComponent_->SetCalendarTheme(theme);
374     }
375     auto operatorIter =
376         BinarySearchFindIndex(calendarStyleOperators, ArraySize(calendarStyleOperators), style.first.c_str());
377     if (operatorIter != -1) {
378         auto& calendarTheme = context->IsJsCard() ? theme->GetCardCalendarTheme() : theme->GetCalendarTheme();
379         calendarStyleOperators[operatorIter].value(style.second, calendarTheme, *this);
380         return true;
381     }
382     return false;
383 }
384 
385 } // namespace OHOS::Ace::Framework
386