* 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_navigation_bar.h"
#include "base/log/event_report.h"
#include "core/common/dynamic_module_helper.h"
#include "compatible/components/tab_bar/modifier/tab_modifier_api.h"
#include "frameworks/bridge/common/utils/utils.h"
namespace OHOS::Ace::Framework {
namespace {
const char EMPHASIZE[] = "emphasize";
NavigationBarType GetType(const std::string& value)
{
return value == EMPHASIZE ? NavigationBarType::EMPHASIZE : NavigationBarType::NORMAL;
}
const ArkUIInnerTabBarModifier* GetTabBarInnerModifier()
{
static const ArkUIInnerTabBarModifier* cachedModifier = nullptr;
if (cachedModifier == nullptr) {
auto loader = DynamicModuleHelper::GetInstance().GetLoaderByName("tab-bar");
CHECK_NULL_RETURN(loader, nullptr);
cachedModifier = reinterpret_cast<const ArkUIInnerTabBarModifier*>(loader->GetCustomModifier());
}
return cachedModifier;
}
}
DomNavigationBar::DomNavigationBar(NodeId nodeId, const std::string& nodeName)
: DOMNode(nodeId, nodeName),
navigationBarComponent_(AceType::MakeRefPtr<NavigationBarComponent>(std::to_string(nodeId), nodeName)),
navigationBarData_(navigationBarComponent_->GetData())
{
if (IsRightToLeft()) {
navigationBarComponent_->SetTextDirection(TextDirection::RTL);
}
}
void DomNavigationBar::InitializeStyle()
{
auto theme = GetTheme<NavigationBarTheme>();
navigationBarData_->theme = theme;
navigationBarData_->subTitleColor = theme->GetSubTitleColor();
navigationBarData_->titleColor = theme->GetTitleColor();
}
void DomNavigationBar::ResetInitializedStyle()
{
InitializeStyle();
}
#ifndef WEARABLE_PRODUCT
void DomNavigationBar::OnChildNodeRemoved(const RefPtr<DOMNode>& child)
{
if (!child || !navigationBarData_) {
return;
}
auto menu = AceType::DynamicCast<MenuComponent>(child->GetSpecializedComponent());
if (menu) {
navigationBarData_->menu = nullptr;
navigationBarData_->allMenuItems.clear();
return;
}
if (auto modifier = GetTabBarInnerModifier()) {
if (modifier->getTabBarComponent(child->GetSpecializedComponent())) {
navigationBarData_->tabBar = nullptr;
return;
}
}
auto selectPopup = AceType::DynamicCast<SelectComponent>(child->GetSpecializedComponent());
if (selectPopup) {
navigationBarData_->selectPopup = nullptr;
}
}
void DomNavigationBar::OnChildNodeAdded(const RefPtr<DOMNode>& child, int32_t slot)
{
if (!child || !navigationBarComponent_) {
return;
}
auto menu = AceType::DynamicCast<MenuComponent>(child->GetSpecializedComponent());
if (menu) {
navigationBarData_->menu = menu;
return;
}
if (auto modifier = GetTabBarInnerModifier()) {
auto tabBar = modifier->getTabBarComponent(child->GetSpecializedComponent());
if (tabBar) {
navigationBarData_->tabBar = tabBar;
return;
}
}
auto selectPopup = AceType::DynamicCast<SelectComponent>(child->GetSpecializedComponent());
if (selectPopup) {
navigationBarData_->selectPopup = selectPopup;
}
}
#endif
void DomNavigationBar::CallSpecializedMethod(const std::string& method, const std::string& args)
{
if (!navigationBarData_->controller) {
EventReport::SendComponentException(ComponentExcepType::NAVIGATION_BAR_ERR);
return;
}
if (method == DOM_NAVIGATION_BAR_METHOD_SHOW) {
navigationBarData_->controller->Show();
} else if (method == DOM_NAVIGATION_BAR_METHOD_HIDE) {
navigationBarData_->controller->Hide();
}
}
void DomNavigationBar::PrepareSpecializedComponent()
{
navigationBarData_->imageFill = GetImageFill();
}
bool DomNavigationBar::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
{
static const LinearMapNode<void (*)(const std::string&, const RefPtr<NavigationBarData>&)> attrOperators[] = {
{ DOM_NAVIGATION_BAR_BACK_ENABLED,
[](const std::string& val, const RefPtr<NavigationBarData>& navigationBar) {
navigationBar->backEnabled = StringToBool(val);
} },
{ DOM_NAVIGATION_BAR_END_ICON,
[](const std::string& val, const RefPtr<NavigationBarData>& navigationBar) {
navigationBar->endIcon = val;
} },
{ DOM_NAVIGATION_BAR_HEADER, [](const std::string& val,
const RefPtr<NavigationBarData>& navigationBar) { navigationBar->header = val; } },
{ DOM_NAVIGATION_BAR_LOGO,
[](const std::string& val, const RefPtr<NavigationBarData>& navigationBar) { navigationBar->logo = val; } },
{ DOM_NAVIGATION_BAR_START_ICON,
[](const std::string& val, const RefPtr<NavigationBarData>& navigationBar) {
navigationBar->startIcon = val;
} },
{ DOM_NAVIGATION_BAR_SUBTITLE,
[](const std::string& val, const RefPtr<NavigationBarData>& navigationBar) {
navigationBar->subTitle = val;
} },
{ DOM_NAVIGATION_BAR_TITLE, [](const std::string& val,
const RefPtr<NavigationBarData>& navigationBar) { navigationBar->title = val; } },
{ DOM_NAVIGATION_BAR_TYPE,
[](const std::string& val, const RefPtr<NavigationBarData>& navigationBar) {
navigationBar->type = GetType(val);
} },
};
auto operatorIter = BinarySearchFindIndex(attrOperators, ArraySize(attrOperators), attr.first.c_str());
if (operatorIter != -1) {
attrOperators[operatorIter].value(attr.second, navigationBarData_);
return true;
}
return false;
}
bool DomNavigationBar::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
{
static const LinearMapNode<void (*)(const std::string&, const DomNavigationBar&)> navigationBarStyleOperators[] = {
{ DOM_NAVIGATION_BAR_SUBTITLE_COLOR,
[](const std::string& val, const DomNavigationBar& node) {
node.navigationBarData_->subTitleColor = node.ParseColor(val);
} },
{ DOM_NAVIGATION_BAR_TITLE_COLOR,
[](const std::string& val, const DomNavigationBar& node) {
node.navigationBarData_->titleColor = node.ParseColor(val);
} },
};
auto operatorIter =
BinarySearchFindIndex(navigationBarStyleOperators, ArraySize(navigationBarStyleOperators), style.first.c_str());
if (operatorIter != -1) {
navigationBarStyleOperators[operatorIter].value(style.second, *this);
return true;
}
return false;
}
bool DomNavigationBar::AddSpecializedEvent(int32_t pageId, const std::string& event)
{
if (event == DOM_NAVIGATION_BAR_EVENT_BACK_CLICK) {
navigationBarData_->backClickMarker = EventMarker(GetNodeIdForEvent(), event, pageId);
} else if (event == DOM_NAVIGATION_BAR_EVENT_START_CLICK) {
navigationBarData_->startClickMarker = EventMarker(GetNodeIdForEvent(), event, pageId);
} else if (event == DOM_NAVIGATION_BAR_EVENT_END_CLICK) {
navigationBarData_->endClickMarker = EventMarker(GetNodeIdForEvent(), event, pageId);
} else {
return false;
}
return true;
}
}