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