1 /*
2 * Copyright (c) 2024 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/declarative_frontend/jsview/js_navigation_utils.h"
17
18 #include "bridge/declarative_frontend/jsview/js_utils.h"
19 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
20
21 namespace OHOS::Ace::Framework {
22
23 namespace {
24 // navigation title bar options
25 constexpr char BACKGROUND_COLOR_PROPERTY[] = "backgroundColor";
26 constexpr char BACKGROUND_BLUR_STYLE_PROPERTY[] = "backgroundBlurStyle";
27 constexpr char BAR_STYLE_PROPERTY[] = "barStyle";
28 constexpr char PADDING_START_PROPERTY[] = "paddingStart";
29 constexpr char PADDING_END_PROPERTY[] = "paddingEnd";
30 constexpr char MAIN_TITLE_MODIFIER[] = "mainTitleModifier";
31 constexpr char SUB_TITLE_MODIFIER[] = "subTitleModifier";
32
ParseSymbolAndIcon(const JSCallbackInfo & info,NG::BarItem & toolBarItem,const JSRef<JSObject> & itemObject)33 void ParseSymbolAndIcon(const JSCallbackInfo& info, NG::BarItem& toolBarItem,
34 const JSRef<JSObject>& itemObject)
35 {
36 std::string icon;
37 std::string activeIcon;
38 auto itemSymbolIconObject = itemObject->GetProperty("symbolIcon");
39 if (itemSymbolIconObject->IsObject()) {
40 std::function<void(WeakPtr<NG::FrameNode>)> iconSymbol = nullptr;
41 JSViewAbstract::SetSymbolOptionApply(info, iconSymbol, itemSymbolIconObject);
42 toolBarItem.iconSymbol = iconSymbol;
43 }
44 auto itemIconObject = itemObject->GetProperty("icon");
45 if (JSViewAbstract::ParseJsMedia(itemIconObject, icon)) {
46 toolBarItem.icon = icon;
47 }
48
49 auto itemActiveSymbolIconObject = itemObject->GetProperty("activeSymbolIcon");
50 if (itemActiveSymbolIconObject->IsObject()) {
51 std::function<void(WeakPtr<NG::FrameNode>)> activeSymbol = nullptr;
52 JSViewAbstract::SetSymbolOptionApply(info, activeSymbol, itemActiveSymbolIconObject);
53 toolBarItem.activeIconSymbol = activeSymbol;
54 }
55 auto itemActiveIconObject = itemObject->GetProperty("activeIcon");
56 if (JSViewAbstract::ParseJsMedia(itemActiveIconObject, activeIcon)) {
57 toolBarItem.activeIcon = activeIcon;
58 }
59 }
60
ParseBackgroundOptions(const JSRef<JSVal> & obj,NG::NavigationBackgroundOptions & options)61 void ParseBackgroundOptions(const JSRef<JSVal>& obj, NG::NavigationBackgroundOptions& options)
62 {
63 options.color.reset();
64 options.blurStyle.reset();
65 if (!obj->IsObject()) {
66 return;
67 }
68 auto optObj = JSRef<JSObject>::Cast(obj);
69 auto colorProperty = optObj->GetProperty(BACKGROUND_COLOR_PROPERTY);
70 Color color;
71 if (JSViewAbstract::ParseJsColor(colorProperty, color)) {
72 options.color = color;
73 }
74 auto blurProperty = optObj->GetProperty(BACKGROUND_BLUR_STYLE_PROPERTY);
75 if (blurProperty->IsNumber()) {
76 auto blurStyle = blurProperty->ToNumber<int32_t>();
77 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
78 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
79 options.blurStyle = static_cast<BlurStyle>(blurStyle);
80 }
81 }
82 }
83
ParseBarOptions(const JSRef<JSVal> & obj,NG::NavigationBarOptions & options)84 void ParseBarOptions(const JSRef<JSVal>& obj, NG::NavigationBarOptions& options)
85 {
86 options.paddingStart.reset();
87 options.paddingEnd.reset();
88 options.barStyle.reset();
89 if (!obj->IsObject()) {
90 return;
91 }
92 auto optObj = JSRef<JSObject>::Cast(obj);
93 auto barStyleProperty = optObj->GetProperty(BAR_STYLE_PROPERTY);
94 if (barStyleProperty->IsNumber()) {
95 auto barStyle = barStyleProperty->ToNumber<int32_t>();
96 if (barStyle >= static_cast<int32_t>(NG::BarStyle::STANDARD) &&
97 barStyle <= static_cast<int32_t>(NG::BarStyle::SAFE_AREA_PADDING)) {
98 options.barStyle = static_cast<NG::BarStyle>(barStyle);
99 } else {
100 options.barStyle = NG::BarStyle::STANDARD;
101 }
102 }
103 CalcDimension paddingStart;
104 if (JSViewAbstract::ParseLengthMetricsToDimension(optObj->GetProperty(PADDING_START_PROPERTY), paddingStart)) {
105 options.paddingStart = paddingStart;
106 }
107 CalcDimension paddingEnd;
108 if (JSViewAbstract::ParseLengthMetricsToDimension(optObj->GetProperty(PADDING_END_PROPERTY), paddingEnd)) {
109 options.paddingEnd = paddingEnd;
110 }
111 }
112
ParseTextOptions(const JSCallbackInfo & info,const JSRef<JSVal> & obj,NG::NavigationTextOptions & options)113 void ParseTextOptions(const JSCallbackInfo& info, const JSRef<JSVal>& obj, NG::NavigationTextOptions& options)
114 {
115 options.Reset();
116 if (!obj->IsObject()) {
117 return;
118 }
119 auto optObj = JSRef<JSObject>::Cast(obj);
120 auto mainTitleModifierProperty = optObj->GetProperty(MAIN_TITLE_MODIFIER);
121 auto subTitleModifierProperty = optObj->GetProperty(SUB_TITLE_MODIFIER);
122 JSViewAbstract::SetTextStyleApply(info, options.mainTitleApplyFunc, mainTitleModifierProperty);
123 JSViewAbstract::SetTextStyleApply(info, options.subTitleApplyFunc, subTitleModifierProperty);
124 }
125
ParseToolBarItemAction(const WeakPtr<NG::FrameNode> & targetNode,const JSCallbackInfo & info,const JSRef<JSObject> & itemObject,NG::BarItem & toolBarItem)126 void ParseToolBarItemAction(const WeakPtr<NG::FrameNode>& targetNode,
127 const JSCallbackInfo& info, const JSRef<JSObject>& itemObject, NG::BarItem& toolBarItem)
128 {
129 auto itemActionValue = itemObject->GetProperty("action");
130 if (!itemActionValue->IsFunction()) {
131 return;
132 }
133
134 RefPtr<JsFunction> onClickFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(itemActionValue));
135 auto onItemClick = [execCtx = info.GetExecutionContext(), func = std::move(onClickFunc),
136 node = targetNode]() {
137 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
138 if (func) {
139 PipelineContext::SetCallBackNode(node);
140 func->ExecuteJS();
141 }
142 };
143 toolBarItem.action = onItemClick;
144 }
145 }
146
ParseToolbarItemsConfiguration(const WeakPtr<NG::FrameNode> & targetNode,const JSCallbackInfo & info,const JSRef<JSArray> & jsArray,std::vector<NG::BarItem> & items)147 void JSNavigationUtils::ParseToolbarItemsConfiguration(const WeakPtr<NG::FrameNode>& targetNode,
148 const JSCallbackInfo& info, const JSRef<JSArray>& jsArray, std::vector<NG::BarItem>& items)
149 {
150 auto length = jsArray->Length();
151 for (size_t i = 0; i < length; i++) {
152 auto item = jsArray->GetValueAt(i);
153 if (!item->IsObject()) {
154 continue;
155 }
156
157 NG::BarItem toolBarItem;
158 std::string text;
159 auto itemObject = JSRef<JSObject>::Cast(item);
160 auto itemValueObject = itemObject->GetProperty("value");
161 if (JSViewAbstract::ParseJsString(itemValueObject, text)) {
162 toolBarItem.text = text;
163 }
164
165 ParseToolBarItemAction(targetNode, info, itemObject, toolBarItem);
166
167 auto itemStatusValue = itemObject->GetProperty("status");
168 if (itemStatusValue->IsNumber()) {
169 toolBarItem.status = static_cast<NG::NavToolbarItemStatus>(itemStatusValue->ToNumber<int32_t>());
170 }
171 ParseSymbolAndIcon(info, toolBarItem, itemObject);
172 items.push_back(toolBarItem);
173 }
174 }
175
ParseTitleBarOptions(const JSCallbackInfo & info,bool needSetDefaultValue,NG::NavigationTitlebarOptions & options)176 void JSNavigationUtils::ParseTitleBarOptions(
177 const JSCallbackInfo& info, bool needSetDefaultValue, NG::NavigationTitlebarOptions& options)
178 {
179 if (needSetDefaultValue) {
180 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
181 auto pipelineContext = PipelineBase::GetCurrentContext();
182 CHECK_NULL_VOID(pipelineContext);
183 auto theme = pipelineContext->GetTheme<NavigationBarTheme>();
184 CHECK_NULL_VOID(theme);
185 auto blurStyle = static_cast<BlurStyle>(theme->GetTitlebarBackgroundBlurStyle());
186 if (blurStyle != BlurStyle::NO_MATERIAL) {
187 options.bgOptions.blurStyle = blurStyle;
188 options.bgOptions.color = Color::TRANSPARENT;
189 }
190 }
191 }
192
193 if (info.Length() > 1) {
194 if (!info[1]->IsObject()) {
195 return;
196 }
197 ParseBackgroundOptions(info[1], options.bgOptions);
198 ParseBarOptions(info[1], options.brOptions);
199 ParseTextOptions(info, info[1], options.textOptions);
200 JSRef<JSObject> jsObjOption = JSRef<JSObject>::Cast(info[1]);
201 auto enableHoverModeProperty = jsObjOption->GetProperty("enableHoverMode");
202 if (enableHoverModeProperty->IsBoolean()) {
203 options.enableHoverMode = enableHoverModeProperty->ToBoolean();
204 }
205 }
206 }
207
ParseToolbarOptions(const JSCallbackInfo & info,NG::NavigationToolbarOptions & options)208 void JSNavigationUtils::ParseToolbarOptions(const JSCallbackInfo& info, NG::NavigationToolbarOptions& options)
209 {
210 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
211 auto pipelineContext = PipelineBase::GetCurrentContext();
212 CHECK_NULL_VOID(pipelineContext);
213 auto theme = pipelineContext->GetTheme<NavigationBarTheme>();
214 CHECK_NULL_VOID(theme);
215 auto blurStyle = static_cast<BlurStyle>(theme->GetToolbarBackgroundBlurStyle());
216 if (blurStyle != BlurStyle::NO_MATERIAL) {
217 options.bgOptions.blurStyle = blurStyle;
218 options.bgOptions.color = Color::TRANSPARENT;
219 }
220 }
221 if (info.Length() > 1) {
222 ParseBackgroundOptions(info[1], options.bgOptions);
223 ParseBarOptions(info[1], options.brOptions);
224 }
225 }
226
ParseBarItems(const WeakPtr<NG::FrameNode> & targetNode,const JSCallbackInfo & info,const JSRef<JSArray> & jsArray,std::vector<NG::BarItem> & items)227 void JSNavigationUtils::ParseBarItems(const WeakPtr<NG::FrameNode>& targetNode,
228 const JSCallbackInfo& info, const JSRef<JSArray>& jsArray, std::vector<NG::BarItem>& items)
229 {
230 auto length = jsArray->Length();
231 for (size_t i = 0; i < length; i++) {
232 auto item = jsArray->GetValueAt(i);
233 if (!item->IsObject()) {
234 continue;
235 }
236 auto itemObject = JSRef<JSObject>::Cast(item);
237 NG::BarItem toolBarItem;
238 std::string value;
239 auto itemValueObject = itemObject->GetProperty("value");
240 if (JSViewAbstract::ParseJsString(itemValueObject, value)) {
241 toolBarItem.text = value;
242 }
243
244 auto itemSymbolIconObject = itemObject->GetProperty("symbolIcon");
245 if (itemSymbolIconObject->IsObject()) {
246 std::function<void(WeakPtr<NG::FrameNode>)> iconSymbol = nullptr;
247 JSViewAbstract::SetSymbolOptionApply(info, iconSymbol, itemSymbolIconObject);
248 toolBarItem.iconSymbol = iconSymbol;
249 }
250 std::string icon;
251 auto itemIconObject = itemObject->GetProperty("icon");
252 if (JSViewAbstract::ParseJsMedia(itemIconObject, icon)) {
253 toolBarItem.icon = icon;
254 }
255
256 auto itemEnabledObject = itemObject->GetProperty("isEnabled");
257 if (itemEnabledObject->IsBoolean()) {
258 toolBarItem.isEnabled = itemEnabledObject->ToBoolean();
259 }
260
261 ParseToolBarItemAction(targetNode, info, itemObject, toolBarItem);
262 items.push_back(toolBarItem);
263 }
264 }
265
266 } // namespace OHOS::Ace::Framework
267