* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "frameworks/bridge/common/dom/dom_calendar.h"
#include "frameworks/bridge/common/utils/utils.h"
namespace OHOS::Ace::Framework {
namespace {
constexpr uint32_t METHOD_GO_TO_ARGS_SIZE = 1;
const char GO_TO_ARG_KEY_YEAR[] = "year";
const char GO_TO_ARG_KEY_MONTH[] = "month";
const char GO_TO_ARG_KEY_DAY[] = "day";
}
DomCalendar::DomCalendar(NodeId nodeId, const std::string& nodeName)
: DOMNode(nodeId, nodeName),
calendarComponent_(AceType::MakeRefPtr<CalendarComponent>(std::to_string(nodeId), nodeName))
{
if (IsRightToLeft()) {
calendarComponent_->SetTextDirection(TextDirection::RTL);
}
}
bool DomCalendar::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
{
static const LinearMapNode<bool (*)(const std::string&, DomCalendar&)> calendarAttrOperators[] = {
{ DOM_CALENDAR_DATA,
[](const std::string& value, DomCalendar& calendar) {
calendar.calendarComponent_->SetCalendarData(value);
return true;
} },
{ DOM_CALENDAR_CARD_CALENDAR,
[](const std::string& value, DomCalendar& calendar) {
calendar.calendarComponent_->SetCardCalendar(StringToBool(value));
return true;
} },
{ DOM_CALENDAR_DATE,
[](const std::string& value, DomCalendar& calendar) {
CalendarDay day;
auto isLegal = StringUtils::StringToCalendarDay(value, day);
if (isLegal) {
calendar.calendarComponent_->SetCalendarDate(day);
return true;
}
return false;
} },
{ DOM_CALENDAR_DATE_ADAPTER,
[](const std::string& value, DomCalendar& calendar) { return calendar.ParseDataAdapter(value); } },
{ DOM_CALENDAR_DIRECTION,
[](const std::string& value, DomCalendar& calendar) {
if (value == "vertical") {
calendar.calendarComponent_->SetAxis(Axis::VERTICAL);
} else if (value == "horizontal") {
calendar.calendarComponent_->SetAxis(Axis::HORIZONTAL);
} else {
LOGW("input do not match any direction");
}
return true;
} },
{ DOM_CALENDAR_HOLIDAYS,
[](const std::string& value, DomCalendar& calendar) {
calendar.calendarComponent_->SetHolidays(value);
return true;
} },
{ DOM_CALENDAR_OFF_DAYS,
[](const std::string& value, DomCalendar& calendar) {
calendar.calendarComponent_->SetOffDays(value);
return true;
} },
{ DOM_CALENDAR_SHOW_HOLIDAY,
[](const std::string& value, DomCalendar& calendar) {
calendar.calendarComponent_->SetShowHoliday(StringToBool(value));
return true;
} },
{ DOM_CALENDAR_SHOW_LUNAR,
[](const std::string& value, DomCalendar& calendar) {
calendar.calendarComponent_->SetShowLunar(StringToBool(value));
return true;
} },
{ DOM_CALENDAR_START_DAY_OF_WEEK,
[](const std::string& value, DomCalendar& calendar) {
auto indexOfWeek = StringToInt(value);
if (0 <= indexOfWeek && indexOfWeek < 7) {
calendar.calendarComponent_->SetStartDayOfWeek(indexOfWeek);
return true;
}
return false;
} },
{ DOM_CALENDAR_TYPE,
[](const std::string& value, DomCalendar& calendar) {
if (value == "normal") {
calendar.calendarComponent_->SetCalendarType(CalendarType::NORMAL);
} else if (value == "simple") {
calendar.calendarComponent_->SetCalendarType(CalendarType::SIMPLE);
}
return true;
} },
{ DOM_CALENDAR_WORK_DAYS,
[](const std::string& value, DomCalendar& calendar) {
calendar.calendarComponent_->SetWorkDays(value);
return true;
} },
};
auto operatorIter =
BinarySearchFindIndex(calendarAttrOperators, ArraySize(calendarAttrOperators), attr.first.c_str());
if (operatorIter != -1) {
return calendarAttrOperators[operatorIter].value(attr.second, *this);
}
return false;
}
void DomCalendar::CallSpecializedMethod(const std::string& method, const std::string& args)
{
if (method == DOM_CALENDAR_METHOD_GO_TO) {
HandleGoTo(args);
}
}
bool DomCalendar::AddSpecializedEvent(int32_t pageId, const std::string& event)
{
if (event == DOM_CALENDAR_EVENT_SELECTED_CHANGE) {
selectedChangeEvent_ = EventMarker(GetNodeIdForEvent(), event, pageId);
calendarComponent_->SetSelectedChangeEvent(selectedChangeEvent_);
return true;
} else if (event == DOM_CALENDAR_EVENT_REQUEST_DATA) {
requestDataEvent_ = EventMarker(GetNodeIdForEvent(), event, pageId);
calendarComponent_->SetRequestDataEvent(requestDataEvent_);
return true;
}
return false;
}
bool DomCalendar::ParseDataAdapter(const std::string& value)
{
std::unique_ptr<JsonValue> dataAdapterValue = JsonUtil::ParseJsonString(value);
if (!dataAdapterValue) {
return false;
}
std::unique_ptr<JsonValue> bundleNameValue = dataAdapterValue->GetValue("bundleName");
if (!bundleNameValue || !bundleNameValue->IsString()) {
return false;
}
std::unique_ptr<JsonValue> abilityNameValue = dataAdapterValue->GetValue("abilityName");
if (!abilityNameValue || !abilityNameValue->IsString()) {
return false;
}
std::unique_ptr<JsonValue> messageCodeValue = dataAdapterValue->GetValue("messageCode");
if (!messageCodeValue || !messageCodeValue->IsNumber()) {
return false;
}
std::string bundleName = bundleNameValue->GetString();
std::string abilityName = abilityNameValue->GetString();
int32_t messageCode = messageCodeValue->GetInt();
CalendarDataAdapterAction dataAdapterAction {
{ .bundleName = bundleName, .abilityName = abilityName, .messageCode = messageCode }
};
calendarComponent_->SetDataAdapterAction(dataAdapterAction);
return true;
}
void DomCalendar::HandleGoTo(const std::string& args)
{
std::unique_ptr<JsonValue> argsValue = JsonUtil::ParseJsonString(args);
if (!argsValue || !argsValue->IsArray() || argsValue->GetArraySize() != METHOD_GO_TO_ARGS_SIZE) {
return;
}
auto gotoArg = argsValue->GetArrayItem(0);
if (!gotoArg || !gotoArg->Contains(GO_TO_ARG_KEY_YEAR) || !gotoArg->Contains(GO_TO_ARG_KEY_MONTH)) {
return;
}
std::unique_ptr<JsonValue> yearValue = gotoArg->GetValue(GO_TO_ARG_KEY_YEAR);
if (!yearValue || !yearValue->IsNumber()) {
return;
}
std::unique_ptr<JsonValue> monthValue = gotoArg->GetValue(GO_TO_ARG_KEY_MONTH);
if (!monthValue || !monthValue->IsNumber()) {
return;
}
int32_t year = yearValue->GetInt();
int32_t month = monthValue->GetInt();
int32_t day = -1;
std::unique_ptr<JsonValue> dayValue = gotoArg->GetValue(GO_TO_ARG_KEY_DAY);
if (dayValue && dayValue->IsNumber()) {
day = dayValue->GetInt();
}
calendarComponent_->GoTo(year, month, day);
}
bool DomCalendar::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
{
static const LinearMapNode<void (*)(const std::string&, CalendarThemeStructure&, const DomCalendar&)>
calendarStyleOperators[] = {
{ "boundaryColumnOffset",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.boundaryColOffset = node.ParseDimension(value);
} },
{ "boundaryRowOffset",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.boundaryRowOffset = node.ParseDimension(value);
} },
{ "columnSpace", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.colSpace = node.ParseDimension(value); } },
{ "dailyFiveRowSpace",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.dailyFiveRowSpace = node.ParseDimension(value);
} },
{ "dailySixRowSpace",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.dailySixRowSpace = node.ParseDimension(value);
} },
{ "dayColor", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.dayColor = node.ParseColor(value); } },
{ "dayFontSize", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.dayFontSize = node.ParseDimension(value); } },
{ "dayHeight", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.dayHeight = node.ParseDimension(value); } },
{ "dayWidth", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.dayWidth = node.ParseDimension(value); } },
{ "dayYAxisOffset", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.dayYAxisOffset = node.ParseDimension(value); } },
{ "focusedAreaBackgroundColor",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.focusedAreaBackgroundColor = node.ParseColor(value);
} },
{ "focusedAreaRadius",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.focusedAreaRadius = node.ParseDimension(value);
} },
{ "focusedDayColor", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.focusedDayColor = node.ParseColor(value); } },
{ "focusedLunarColor", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.focusedLunarColor = node.ParseColor(value); } },
{ "gregorianCalendarHeight",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.gregorianCalendarHeight = node.ParseDimension(value);
} },
{ "lunarColor", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.lunarColor = node.ParseColor(value); } },
{ "lunarDayFontSize",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.lunarDayFontSize = node.ParseDimension(value);
} },
{ "lunarDayYAxisOffset",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.lunarDayYAxisOffset = node.ParseDimension(value);
} },
{ "lunarHeight", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.lunarHeight = node.ParseDimension(value); } },
{ "markLunarColor", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.markLunarColor = node.ParseColor(value); } },
{ "nonCurrentMonthDayColor",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.nonCurrentMonthDayColor = node.ParseColor(value);
} },
{ "nonCurrentMonthLunarColor",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.nonCurrentMonthLunarColor = node.ParseColor(value);
} },
{ "nonCurrentMonthOffDayMarkColor",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.nonCurrentMonthOffDayMarkColor = node.ParseColor(value);
} },
{ "nonCurrentMonthWorkDayMarkColor",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.nonCurrentMonthWorkDayMarkColor = node.ParseColor(value);
} },
{ "offDayMarkColor", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.offDayMarkColor = node.ParseColor(value); } },
{ "offDayMarkSize", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.offDayMarkSize = node.ParseDimension(value); } },
{ "scheduleMarkerRadius",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.scheduleMarkerRadius = node.ParseDimension(value);
} },
{ "scheduleMarkerXAxisOffset",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.scheduleMarkerXAxisOffset = node.ParseDimension(value);
} },
{ "scheduleMarkerYAxisOffset",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.scheduleMarkerYAxisOffset = node.ParseDimension(value);
} },
{ "simpleOffTextColor",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.simpleOffTextColor = node.ParseColor(value);
} },
{ "simpleWorkTextColor",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.simpleWorkTextColor = node.ParseColor(value);
} },
{ "underscoreLength",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.underscoreLength = node.ParseDimension(value);
} },
{ "underscoreWidth", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.underscoreWidth = node.ParseDimension(value); } },
{ "underscoreXAxisOffset",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.underscoreXAxisOffset = node.ParseDimension(value);
} },
{ "underscoreYAxisOffset",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.underscoreYAxisOffset = node.ParseDimension(value);
} },
{ "weekAndDayRowSpace",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.weekAndDayRowSpace = node.ParseDimension(value);
} },
{ "weekColor", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.weekColor = node.ParseColor(value); } },
{ "weekFontSize", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.weekFontSize = node.ParseDimension(value); } },
{ "weekHeight", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.weekHeight = node.ParseDimension(value); } },
{ "weekWidth", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.weekWidth = node.ParseDimension(value); } },
{ "weekendDayColor", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.weekendDayColor = node.ParseColor(value); } },
{ "weekendLunarColor", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.weekendLunarColor = node.ParseColor(value); } },
{ "workDayMarkColor", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.workDayMarkColor = node.ParseColor(value); } },
{ "workDayMarkSize", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.workDayMarkSize = node.ParseDimension(value); } },
{ "workStateHorizontalMovingDistance",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.workStateHorizontalMovingDistance = node.ParseDimension(value);
} },
{ "workStateOffset", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.workStateOffset = node.ParseDimension(value); } },
{ "workStateVerticalMovingDistance",
[](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) {
theme.workStateVerticalMovingDistance = node.ParseDimension(value);
} },
{ "workStateWidth", [](const std::string& value, CalendarThemeStructure& theme,
const DomCalendar& node) { theme.workStateWidth = node.ParseDimension(value); } },
};
auto context = GetPipelineContext().Upgrade();
if (!context) {
return false;
}
auto theme = calendarComponent_->GetCalendarTheme();
if (!theme) {
theme = GetTheme<CalendarTheme>();
calendarComponent_->SetCalendarTheme(theme);
}
auto operatorIter =
BinarySearchFindIndex(calendarStyleOperators, ArraySize(calendarStyleOperators), style.first.c_str());
if (operatorIter != -1) {
auto& calendarTheme = context->IsJsCard() ? theme->GetCardCalendarTheme() : theme->GetCalendarTheme();
calendarStyleOperators[operatorIter].value(style.second, calendarTheme, *this);
return true;
}
return false;
}
}