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_navigation_bar.h"
17 
18 #include "base/log/event_report.h"
19 #include "frameworks/bridge/common/utils/utils.h"
20 
21 namespace OHOS::Ace::Framework {
22 namespace {
23 
24 const char EMPHASIZE[] = "emphasize";
GetType(const std::string & value)25 NavigationBarType GetType(const std::string& value)
26 {
27     return value == EMPHASIZE ? NavigationBarType::EMPHASIZE : NavigationBarType::NORMAL;
28 }
29 
30 } // namespace
31 
DomNavigationBar(NodeId nodeId,const std::string & nodeName)32 DomNavigationBar::DomNavigationBar(NodeId nodeId, const std::string& nodeName)
33     : DOMNode(nodeId, nodeName),
34       navigationBarComponent_(AceType::MakeRefPtr<NavigationBarComponent>(std::to_string(nodeId), nodeName)),
35       navigationBarData_(navigationBarComponent_->GetData())
36 {
37     if (IsRightToLeft()) {
38         navigationBarComponent_->SetTextDirection(TextDirection::RTL);
39     }
40 }
41 
InitializeStyle()42 void DomNavigationBar::InitializeStyle()
43 {
44     auto theme = GetTheme<NavigationBarTheme>();
45     navigationBarData_->theme = theme;
46     navigationBarData_->subTitleColor = theme->GetSubTitleColor();
47     navigationBarData_->titleColor = theme->GetTitleColor();
48 }
49 
ResetInitializedStyle()50 void DomNavigationBar::ResetInitializedStyle()
51 {
52     InitializeStyle();
53 }
54 
55 #ifndef WEARABLE_PRODUCT
OnChildNodeRemoved(const RefPtr<DOMNode> & child)56 void DomNavigationBar::OnChildNodeRemoved(const RefPtr<DOMNode>& child)
57 {
58     if (!child || !navigationBarData_) {
59         return;
60     }
61 
62     auto menu = AceType::DynamicCast<MenuComponent>(child->GetSpecializedComponent());
63     if (menu) {
64         navigationBarData_->menu = nullptr;
65         navigationBarData_->allMenuItems.clear();
66         return;
67     }
68     auto tabBar = AceType::DynamicCast<TabBarComponent>(child->GetSpecializedComponent());
69     if (tabBar) {
70         navigationBarData_->tabBar = nullptr;
71         return;
72     }
73 
74     auto selectPopup = AceType::DynamicCast<SelectComponent>(child->GetSpecializedComponent());
75     if (selectPopup) {
76         navigationBarData_->selectPopup = nullptr;
77     }
78 }
79 
OnChildNodeAdded(const RefPtr<DOMNode> & child,int32_t slot)80 void DomNavigationBar::OnChildNodeAdded(const RefPtr<DOMNode>& child, int32_t slot)
81 {
82     if (!child || !navigationBarComponent_) {
83         return;
84     }
85 
86     auto menu = AceType::DynamicCast<MenuComponent>(child->GetSpecializedComponent());
87     if (menu) {
88         navigationBarData_->menu = menu;
89         return;
90     }
91     auto tabBar = AceType::DynamicCast<TabBarComponent>(child->GetSpecializedComponent());
92     if (tabBar) {
93         navigationBarData_->tabBar = tabBar;
94         return;
95     }
96 
97     auto selectPopup = AceType::DynamicCast<SelectComponent>(child->GetSpecializedComponent());
98     if (selectPopup) {
99         navigationBarData_->selectPopup = selectPopup;
100     }
101 }
102 #endif
103 
CallSpecializedMethod(const std::string & method,const std::string & args)104 void DomNavigationBar::CallSpecializedMethod(const std::string& method, const std::string& args)
105 {
106     if (!navigationBarData_->controller) {
107         EventReport::SendComponentException(ComponentExcepType::NAVIGATION_BAR_ERR);
108         return;
109     }
110     if (method == DOM_NAVIGATION_BAR_METHOD_SHOW) {
111         navigationBarData_->controller->Show();
112     } else if (method == DOM_NAVIGATION_BAR_METHOD_HIDE) {
113         navigationBarData_->controller->Hide();
114     }
115 }
116 
PrepareSpecializedComponent()117 void DomNavigationBar::PrepareSpecializedComponent()
118 {
119     navigationBarData_->imageFill = GetImageFill();
120 }
121 
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)122 bool DomNavigationBar::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
123 {
124     static const LinearMapNode<void (*)(const std::string&, const RefPtr<NavigationBarData>&)> attrOperators[] = {
125         { DOM_NAVIGATION_BAR_BACK_ENABLED,
126             [](const std::string& val, const RefPtr<NavigationBarData>& navigationBar) {
127                 navigationBar->backEnabled = StringToBool(val);
128             } },
129         { DOM_NAVIGATION_BAR_END_ICON,
130             [](const std::string& val, const RefPtr<NavigationBarData>& navigationBar) {
131                 navigationBar->endIcon = val;
132             } },
133         { DOM_NAVIGATION_BAR_HEADER, [](const std::string& val,
134                                      const RefPtr<NavigationBarData>& navigationBar) { navigationBar->header = val; } },
135         { DOM_NAVIGATION_BAR_LOGO,
136             [](const std::string& val, const RefPtr<NavigationBarData>& navigationBar) { navigationBar->logo = val; } },
137         { DOM_NAVIGATION_BAR_START_ICON,
138             [](const std::string& val, const RefPtr<NavigationBarData>& navigationBar) {
139                 navigationBar->startIcon = val;
140             } },
141         { DOM_NAVIGATION_BAR_SUBTITLE,
142             [](const std::string& val, const RefPtr<NavigationBarData>& navigationBar) {
143                 navigationBar->subTitle = val;
144             } },
145         { DOM_NAVIGATION_BAR_TITLE, [](const std::string& val,
146                                     const RefPtr<NavigationBarData>& navigationBar) { navigationBar->title = val; } },
147         { DOM_NAVIGATION_BAR_TYPE,
148             [](const std::string& val, const RefPtr<NavigationBarData>& navigationBar) {
149                 navigationBar->type = GetType(val);
150             } },
151     };
152     auto operatorIter = BinarySearchFindIndex(attrOperators, ArraySize(attrOperators), attr.first.c_str());
153     if (operatorIter != -1) {
154         attrOperators[operatorIter].value(attr.second, navigationBarData_);
155         return true;
156     }
157     return false;
158 }
159 
SetSpecializedStyle(const std::pair<std::string,std::string> & style)160 bool DomNavigationBar::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
161 {
162     static const LinearMapNode<void (*)(const std::string&, const DomNavigationBar&)> navigationBarStyleOperators[] = {
163         { DOM_NAVIGATION_BAR_SUBTITLE_COLOR,
164             [](const std::string& val, const DomNavigationBar& node) {
165                 node.navigationBarData_->subTitleColor = node.ParseColor(val);
166             } },
167         { DOM_NAVIGATION_BAR_TITLE_COLOR,
168             [](const std::string& val, const DomNavigationBar& node) {
169                 node.navigationBarData_->titleColor = node.ParseColor(val);
170             } },
171     };
172     auto operatorIter =
173         BinarySearchFindIndex(navigationBarStyleOperators, ArraySize(navigationBarStyleOperators), style.first.c_str());
174     if (operatorIter != -1) {
175         navigationBarStyleOperators[operatorIter].value(style.second, *this);
176         return true;
177     }
178     return false;
179 }
180 
AddSpecializedEvent(int32_t pageId,const std::string & event)181 bool DomNavigationBar::AddSpecializedEvent(int32_t pageId, const std::string& event)
182 {
183     if (event == DOM_NAVIGATION_BAR_EVENT_BACK_CLICK) {
184         navigationBarData_->backClickMarker = EventMarker(GetNodeIdForEvent(), event, pageId);
185     } else if (event == DOM_NAVIGATION_BAR_EVENT_START_CLICK) {
186         navigationBarData_->startClickMarker = EventMarker(GetNodeIdForEvent(), event, pageId);
187     } else if (event == DOM_NAVIGATION_BAR_EVENT_END_CLICK) {
188         navigationBarData_->endClickMarker = EventMarker(GetNodeIdForEvent(), event, pageId);
189     } else {
190         return false;
191     }
192     return true;
193 }
194 
195 } // namespace OHOS::Ace::Framework
196