1 /*
2 * Copyright (c) 2021-2022 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_tab_content.h"
17
18 #include <optional>
19
20 #include "base/log/ace_trace.h"
21 #include "bridge/declarative_frontend/jsview/models/tab_content_model_impl.h"
22 #include "core/components_ng/pattern/tabs/tab_content_model_ng.h"
23
24 namespace OHOS::Ace {
25
26 std::unique_ptr<TabContentModel> TabContentModel::instance_ = nullptr;
27
GetInstance()28 TabContentModel* TabContentModel::GetInstance()
29 {
30 if (!instance_) {
31 #ifdef NG_BUILD
32 instance_.reset(new NG::TabContentModelNG());
33 #else
34 if (Container::IsCurrentUseNewPipeline()) {
35 instance_.reset(new NG::TabContentModelNG());
36 } else {
37 instance_.reset(new Framework::TabContentModelImpl());
38 }
39 #endif
40 }
41 return instance_.get();
42 }
43
44 } // namespace OHOS::Ace
45
46 namespace OHOS::Ace::Framework {
47
Create(const JSCallbackInfo & info)48 void JSTabContent::Create(const JSCallbackInfo& info)
49 {
50 if (Container::IsCurrentUsePartialUpdate()) {
51 CreateForPartialUpdate(info);
52 return;
53 }
54 TabContentModel::GetInstance()->Create();
55 }
56
CreateForPartialUpdate(const JSCallbackInfo & info)57 void JSTabContent::CreateForPartialUpdate(const JSCallbackInfo& info)
58 {
59 if (info.Length() <= 0 && !info[0]->IsFunction()) {
60 TabContentModel::GetInstance()->Create();
61 return;
62 }
63
64 JSRef<JSVal> builderFunctionJS = info[0];
65 auto builderFunc = [context = info.GetExecutionContext(), builder = std::move(builderFunctionJS)]() {
66 JAVASCRIPT_EXECUTION_SCOPE(context)
67 JSRef<JSFunc>::Cast(builder)->Call(JSRef<JSObject>());
68 };
69 TabContentModel::GetInstance()->Create(std::move(builderFunc));
70 }
71
SetTabBar(const JSCallbackInfo & info)72 void JSTabContent::SetTabBar(const JSCallbackInfo& info)
73 {
74 if (info.Length() <= 0) {
75 return;
76 }
77
78 std::string infoStr;
79 if (ParseJsString(info[0], infoStr)) {
80 TabContentModel::GetInstance()->SetTabBar(infoStr, std::nullopt, nullptr, true);
81 return;
82 }
83
84 if (!info[0]->IsObject()) {
85 return;
86 }
87
88 auto paramObject = JSRef<JSObject>::Cast(info[0]);
89 JSRef<JSVal> builderFuncParam = paramObject->GetProperty("builder");
90 if (builderFuncParam->IsFunction()) {
91 auto tabBarBuilder = AceType::MakeRefPtr<JsFunction>(info.This(), JSRef<JSFunc>::Cast(builderFuncParam));
92 auto tabBarBuilderFunc = [execCtx = info.GetExecutionContext(),
93 tabBarBuilderFunc = std::move(tabBarBuilder)]() {
94 if (tabBarBuilderFunc) {
95 ACE_SCOPED_TRACE("JSTabContent::Execute TabBar builder");
96 JAVASCRIPT_EXECUTION_SCOPE(execCtx);
97 tabBarBuilderFunc->ExecuteJS();
98 }
99 };
100 TabContentModel::GetInstance()->SetTabBarStyle(TabBarStyle::NOSTYLE);
101 TabContentModel::GetInstance()->SetTabBar(std::nullopt, std::nullopt, std::move(tabBarBuilderFunc), false);
102 return;
103 }
104 JSRef<JSVal> typeParam = paramObject->GetProperty("type");
105 if (typeParam->IsString()) {
106 auto type = typeParam->ToString();
107 if (type == "SubTabBarStyle") {
108 JSRef<JSVal> contentParam = paramObject->GetProperty("content");
109 auto isContentEmpty = contentParam->IsEmpty() || contentParam->IsUndefined() || contentParam->IsNull();
110 if (isContentEmpty) {
111 LOGE("The content param is empty");
112 return;
113 }
114 std::optional<std::string> contentOpt = std::nullopt;
115 std::string content;
116 if (ParseJsString(contentParam, content)) {
117 contentOpt = content;
118 }
119 TabContentModel::GetInstance()->SetTabBarStyle(TabBarStyle::SUBTABBATSTYLE);
120 TabContentModel::GetInstance()->SetTabBar(contentOpt, std::nullopt, nullptr, false);
121 return;
122 }
123 if (type == "BottomTabBarStyle") {
124 JSRef<JSVal> textParam = paramObject->GetProperty("text");
125 auto isTextEmpty = textParam->IsEmpty() || textParam->IsUndefined() || textParam->IsNull();
126 std::optional<std::string> textOpt = std::nullopt;
127 if (isTextEmpty) {
128 LOGE("The text param is empty");
129 return;
130 }
131 std::string text;
132 if (ParseJsString(textParam, text)) {
133 textOpt = text;
134 }
135
136 JSRef<JSVal> iconParam = paramObject->GetProperty("icon");
137 auto isIconEmpty = iconParam->IsEmpty() || iconParam->IsUndefined() || iconParam->IsNull();
138 std::optional<std::string> iconOpt = std::nullopt;
139 if (isIconEmpty) {
140 LOGE("The icon param is empty");
141 return;
142 }
143 std::string icon;
144 if (ParseJsMedia(iconParam, icon)) {
145 iconOpt = icon;
146 }
147 TabContentModel::GetInstance()->SetTabBarStyle(TabBarStyle::BOTTOMTABBATSTYLE);
148 TabContentModel::GetInstance()->SetTabBar(textOpt, iconOpt, nullptr, false);
149 return;
150 }
151 }
152
153 JSRef<JSVal> textParam = paramObject->GetProperty("text");
154 auto isTextEmpty = textParam->IsEmpty() || textParam->IsUndefined() || textParam->IsNull();
155 std::optional<std::string> textOpt = std::nullopt;
156 if (!isTextEmpty) {
157 std::string text;
158 if (ParseJsString(textParam, text)) {
159 textOpt = text;
160 }
161 }
162
163 JSRef<JSVal> iconParam = paramObject->GetProperty("icon");
164 auto isIconEmpty = iconParam->IsEmpty() || iconParam->IsUndefined() || iconParam->IsNull();
165 std::optional<std::string> iconOpt = std::nullopt;
166 if (!isIconEmpty) {
167 std::string icon;
168 if (ParseJsMedia(iconParam, icon)) {
169 iconOpt = icon;
170 }
171 }
172 TabContentModel::GetInstance()->SetTabBarStyle(TabBarStyle::NOSTYLE);
173 TabContentModel::GetInstance()->SetTabBar(textOpt, iconOpt, nullptr, false);
174 }
175
Pop()176 void JSTabContent::Pop()
177 {
178 TabContentModel::GetInstance()->Pop();
179 }
180
JSBind(BindingTarget globalObj)181 void JSTabContent::JSBind(BindingTarget globalObj)
182 {
183 JSClass<JSTabContent>::Declare("TabContent");
184 JSClass<JSTabContent>::StaticMethod("create", &JSTabContent::Create);
185 JSClass<JSTabContent>::StaticMethod("pop", &JSTabContent::Pop);
186 JSClass<JSTabContent>::StaticMethod("tabBar", &JSTabContent::SetTabBar);
187 JSClass<JSTabContent>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
188 JSClass<JSTabContent>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
189 JSClass<JSTabContent>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
190 JSClass<JSTabContent>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
191 JSClass<JSTabContent>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
192 JSClass<JSTabContent>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
193 JSClass<JSTabContent>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
194 JSClass<JSTabContent>::StaticMethod("width", &JSTabContent::SetTabContentWidth);
195 JSClass<JSTabContent>::StaticMethod("height", &JSTabContent::SetTabContentHeight);
196 JSClass<JSTabContent>::StaticMethod("size", &JSTabContent::SetTabContentSize);
197 JSClass<JSTabContent>::StaticMethod("remoteMessage", &JSInteractableView::JsCommonRemoteMessage);
198 JSClass<JSTabContent>::Inherit<JSContainerBase>();
199 JSClass<JSTabContent>::Bind<>(globalObj);
200 }
201
202 } // namespace OHOS::Ace::Framework
203