• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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/js_view_common_def.h"
22 #include "bridge/declarative_frontend/jsview/models/tab_content_model_impl.h"
23 #include "core/components/tab_bar/tab_theme.h"
24 #include "core/components_ng/pattern/tabs/tab_content_model_ng.h"
25 #include "core/components_ng/property/measure_property.h"
26 
27 namespace OHOS::Ace {
28 
29 std::unique_ptr<TabContentModel> TabContentModel::instance_ = nullptr;
30 std::mutex TabContentModel::mutex_;
31 
32 const std::vector<TextOverflow> TEXT_OVERFLOWS = { TextOverflow::NONE, TextOverflow::CLIP, TextOverflow::ELLIPSIS,
33     TextOverflow::MARQUEE };
34 const std::vector<FontStyle> FONT_STYLES = { FontStyle::NORMAL, FontStyle::ITALIC };
35 const std::vector<TextHeightAdaptivePolicy> HEIGHT_ADAPTIVE_POLICIES = { TextHeightAdaptivePolicy::MAX_LINES_FIRST,
36     TextHeightAdaptivePolicy::MIN_FONT_SIZE_FIRST, TextHeightAdaptivePolicy::LAYOUT_CONSTRAINT_FIRST };
37 
GetInstance()38 TabContentModel* TabContentModel::GetInstance()
39 {
40     if (!instance_) {
41         std::lock_guard<std::mutex> lock(mutex_);
42         if (!instance_) {
43 #ifdef NG_BUILD
44             instance_.reset(new NG::TabContentModelNG());
45 #else
46             if (Container::IsCurrentUseNewPipeline()) {
47                 instance_.reset(new NG::TabContentModelNG());
48             } else {
49                 instance_.reset(new Framework::TabContentModelImpl());
50             }
51 #endif
52         }
53     }
54     return instance_.get();
55 }
56 
57 } // namespace OHOS::Ace
58 
59 namespace OHOS::Ace::Framework {
60 
Create(const JSCallbackInfo & info)61 void JSTabContent::Create(const JSCallbackInfo& info)
62 {
63     if (Container::IsCurrentUsePartialUpdate()) {
64         CreateForPartialUpdate(info);
65         return;
66     }
67     TabContentModel::GetInstance()->Create();
68 }
69 
CreateForPartialUpdate(const JSCallbackInfo & info)70 void JSTabContent::CreateForPartialUpdate(const JSCallbackInfo& info)
71 {
72     if (info.Length() <= 0 && !info[0]->IsFunction()) {
73         TabContentModel::GetInstance()->Create();
74         return;
75     }
76 
77     JSRef<JSVal> builderFunctionJS = info[0];
78     auto builderFunc = [context = info.GetExecutionContext(), builder = std::move(builderFunctionJS)]() {
79         JAVASCRIPT_EXECUTION_SCOPE(context)
80         JSRef<JSFunc>::Cast(builder)->Call(JSRef<JSObject>());
81     };
82     TabContentModel::GetInstance()->Create(std::move(builderFunc));
83 }
84 
SetTabBar(const JSCallbackInfo & info)85 void JSTabContent::SetTabBar(const JSCallbackInfo& info)
86 {
87     if (info.Length() <= 0) {
88         return;
89     }
90 
91     std::string infoStr;
92     if (ParseJsString(info[0], infoStr)) {
93         TabContentModel::GetInstance()->SetTabBarStyle(TabBarStyle::NOSTYLE);
94         TabContentModel::GetInstance()->SetTabBar(infoStr, std::nullopt, nullptr, true);
95         return;
96     }
97 
98     if (!info[0]->IsObject()) {
99         return;
100     }
101 
102     auto paramObject = JSRef<JSObject>::Cast(info[0]);
103     JSRef<JSVal> builderFuncParam = paramObject->GetProperty("builder");
104     if (builderFuncParam->IsFunction()) {
105         auto tabBarBuilder = AceType::MakeRefPtr<JsFunction>(info.This(), JSRef<JSFunc>::Cast(builderFuncParam));
106         auto tabBarBuilderFunc = [execCtx = info.GetExecutionContext(),
107                                      tabBarBuilderFunc = std::move(tabBarBuilder)]() {
108             if (tabBarBuilderFunc) {
109                 ACE_SCOPED_TRACE("JSTabContent::Execute TabBar builder");
110                 JAVASCRIPT_EXECUTION_SCOPE(execCtx);
111                 tabBarBuilderFunc->ExecuteJS();
112             }
113         };
114         TabContentModel::GetInstance()->SetTabBarStyle(TabBarStyle::NOSTYLE);
115         TabContentModel::GetInstance()->SetTabBar(std::nullopt, std::nullopt, std::move(tabBarBuilderFunc), false);
116         return;
117     }
118     JSRef<JSVal> typeParam = paramObject->GetProperty("type");
119     if (typeParam->IsString()) {
120         auto type = typeParam->ToString();
121         if (type == "SubTabBarStyle") {
122             SetSubTabBarStyle(paramObject);
123             return;
124         }
125         if (type == "BottomTabBarStyle") {
126             SetBottomTabBarStyle(paramObject);
127             return;
128         }
129     }
130 
131     JSRef<JSVal> textParam = paramObject->GetProperty("text");
132     auto isTextEmpty = textParam->IsEmpty() || textParam->IsUndefined() || textParam->IsNull();
133     std::optional<std::string> textOpt = std::nullopt;
134     if (!isTextEmpty) {
135         std::string text;
136         if (ParseJsString(textParam, text)) {
137             textOpt = text;
138         }
139     }
140 
141     JSRef<JSVal> iconParam = paramObject->GetProperty("icon");
142     auto isIconEmpty = iconParam->IsEmpty() || iconParam->IsUndefined() || iconParam->IsNull();
143     std::optional<std::string> iconOpt = std::nullopt;
144     if (!isIconEmpty) {
145         std::string icon;
146         if (ParseJsMedia(iconParam, icon)) {
147             iconOpt = icon;
148         }
149     }
150     TabContentModel::GetInstance()->SetTabBarStyle(TabBarStyle::NOSTYLE);
151     TabContentModel::GetInstance()->SetTabBar(textOpt, iconOpt, nullptr, false);
152 }
153 
Pop()154 void JSTabContent::Pop()
155 {
156     TabContentModel::GetInstance()->Pop();
157 }
158 
SetIndicator(const JSRef<JSVal> & info)159 void JSTabContent::SetIndicator(const JSRef<JSVal>& info)
160 {
161     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info);
162     IndicatorStyle indicator;
163     CalcDimension indicatorHeight;
164     CalcDimension indicatorWidth;
165     CalcDimension indicatorBorderRadius;
166     CalcDimension indicatorMarginTop;
167     if (!info->IsObject() || !ConvertFromJSValue(obj->GetProperty("color"), indicator.color)) {
168         RefPtr<TabTheme> tabTheme = GetTheme<TabTheme>();
169         if (tabTheme) {
170             indicator.color = tabTheme->GetActiveIndicatorColor();
171         }
172     }
173     if (!info->IsObject() || !ParseJsDimensionVp(obj->GetProperty("height"), indicatorHeight) ||
174         indicatorHeight.Value() < 0.0f || indicatorHeight.Unit() == DimensionUnit::PERCENT) {
175         RefPtr<TabTheme> tabTheme = GetTheme<TabTheme>();
176         if (tabTheme) {
177             indicator.height = tabTheme->GetActiveIndicatorWidth();
178         }
179     } else {
180         indicator.height = indicatorHeight;
181     }
182     if (!info->IsObject() || !ParseJsDimensionVp(obj->GetProperty("width"), indicatorWidth) ||
183         indicatorWidth.Value() < 0.0f || indicatorWidth.Unit() == DimensionUnit::PERCENT) {
184         indicator.width = 0.0_vp;
185     } else {
186         indicator.width = indicatorWidth;
187     }
188     if (!info->IsObject() || !ParseJsDimensionVp(obj->GetProperty("borderRadius"), indicatorBorderRadius) ||
189         indicatorBorderRadius.Value() < 0.0f || indicatorBorderRadius.Unit() == DimensionUnit::PERCENT) {
190         indicator.borderRadius = 0.0_vp;
191     } else {
192         indicator.borderRadius = indicatorBorderRadius;
193     }
194     if (!info->IsObject() || !ParseJsDimensionVp(obj->GetProperty("marginTop"), indicatorMarginTop) ||
195         indicatorMarginTop.Value() < 0.0f || indicatorMarginTop.Unit() == DimensionUnit::PERCENT) {
196         RefPtr<TabTheme> tabTheme = GetTheme<TabTheme>();
197         if (tabTheme) {
198             indicator.marginTop = tabTheme->GetSubTabIndicatorGap();
199         }
200     } else {
201         indicator.marginTop = indicatorMarginTop;
202     }
203     TabContentModel::GetInstance()->SetIndicator(indicator);
204 }
205 
SetBoard(const JSRef<JSVal> & info)206 void JSTabContent::SetBoard(const JSRef<JSVal>& info)
207 {
208     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info);
209     BoardStyle board;
210     CalcDimension borderRadius;
211     if (!info->IsObject() || !ParseJsDimensionVp(obj->GetProperty("borderRadius"), borderRadius) ||
212         borderRadius.Value() < 0.0f || borderRadius.Unit() == DimensionUnit::PERCENT) {
213         RefPtr<TabTheme> tabTheme = GetTheme<TabTheme>();
214         if (tabTheme) {
215             board.borderRadius = tabTheme->GetFocusIndicatorRadius();
216         }
217     } else {
218         board.borderRadius = borderRadius;
219     }
220     TabContentModel::GetInstance()->SetBoard(board);
221 }
222 
SetSelectedMode(const JSRef<JSVal> & info)223 void JSTabContent::SetSelectedMode(const JSRef<JSVal>& info)
224 {
225     int32_t selectedMode;
226     if (!ConvertFromJSValue(info, selectedMode)) {
227         TabContentModel::GetInstance()->SetSelectedMode(SelectedMode::INDICATOR);
228     } else {
229         TabContentModel::GetInstance()->SetSelectedMode(static_cast<SelectedMode>(selectedMode));
230     }
231 }
232 
GetFontContent(const JSRef<JSVal> font,LabelStyle & labelStyle,bool isSubTabStyle)233 void JSTabContent::GetFontContent(const JSRef<JSVal> font, LabelStyle& labelStyle, bool isSubTabStyle)
234 {
235     JSRef<JSObject> obj = JSRef<JSObject>::Cast(font);
236     JSRef<JSVal> size = obj->GetProperty("size");
237     CalcDimension fontSize;
238     if (ParseJsDimensionFp(size, fontSize) && NonNegative(fontSize.Value()) &&
239         fontSize.Unit() != DimensionUnit::PERCENT) {
240         labelStyle.fontSize = fontSize;
241     }
242 
243     JSRef<JSVal> weight = obj->GetProperty("weight");
244     if (weight->IsString() || weight->IsNumber()) {
245         auto parseResult = ParseFontWeight(weight->ToString());
246         if (parseResult.first || !isSubTabStyle) {
247             labelStyle.fontWeight = parseResult.second;
248         }
249     }
250 
251     JSRef<JSVal> family = obj->GetProperty("family");
252     std::vector<std::string> fontFamilies;
253     if (ParseJsFontFamilies(family, fontFamilies)) {
254         labelStyle.fontFamily = fontFamilies;
255     }
256 
257     JSRef<JSVal> style = obj->GetProperty("style");
258     if (style->IsNumber()) {
259         int32_t value = style->ToNumber<int32_t>();
260         if (value >= 0 && value < static_cast<int32_t>(FONT_STYLES.size())) {
261             labelStyle.fontStyle = FONT_STYLES[value];
262         }
263     }
264 }
265 
SetLabelStyle(const JSRef<JSVal> & info,bool isSubTabStyle)266 void JSTabContent::SetLabelStyle(const JSRef<JSVal>& info, bool isSubTabStyle)
267 {
268     LabelStyle labelStyle;
269     if (!info->IsObject()) {
270         LOGW("info not is Object");
271     } else {
272         JSRef<JSObject> obj = JSRef<JSObject>::Cast(info);
273         JSRef<JSVal> overflowValue = obj->GetProperty("overflow");
274         if (!overflowValue->IsNull() && overflowValue->IsNumber()) {
275             auto overflow = overflowValue->ToNumber<int32_t>();
276             if (overflow >= 0 && overflow < static_cast<int32_t>(TEXT_OVERFLOWS.size())) {
277                 labelStyle.textOverflow = TEXT_OVERFLOWS[overflow];
278             }
279         }
280 
281         JSRef<JSVal> maxLines = obj->GetProperty("maxLines");
282         if (!maxLines->IsNull() && maxLines->IsNumber() && maxLines->ToNumber<int32_t>() > 0) {
283             labelStyle.maxLines = maxLines->ToNumber<int32_t>();
284         }
285 
286         JSRef<JSVal> minFontSizeValue = obj->GetProperty("minFontSize");
287         CalcDimension minFontSize;
288         if (ParseJsDimensionFp(minFontSizeValue, minFontSize) && NonNegative(minFontSize.Value()) &&
289             minFontSize.Unit() != DimensionUnit::PERCENT) {
290             labelStyle.minFontSize = minFontSize;
291         }
292 
293         JSRef<JSVal> maxFontSizeValue = obj->GetProperty("maxFontSize");
294         CalcDimension maxFontSize;
295         if (ParseJsDimensionFp(maxFontSizeValue, maxFontSize) && NonNegative(maxFontSize.Value()) &&
296             maxFontSize.Unit() != DimensionUnit::PERCENT) {
297             labelStyle.maxFontSize = maxFontSize;
298         }
299 
300         JSRef<JSVal> heightAdaptivePolicyValue = obj->GetProperty("heightAdaptivePolicy");
301         if (!heightAdaptivePolicyValue->IsNull() && heightAdaptivePolicyValue->IsNumber()) {
302             auto heightAdaptivePolicy = heightAdaptivePolicyValue->ToNumber<int32_t>();
303             if (heightAdaptivePolicy >= 0 &&
304                 heightAdaptivePolicy < static_cast<int32_t>(HEIGHT_ADAPTIVE_POLICIES.size())) {
305                 labelStyle.heightAdaptivePolicy = HEIGHT_ADAPTIVE_POLICIES[heightAdaptivePolicy];
306             }
307         }
308 
309         JSRef<JSVal> font = obj->GetProperty("font");
310         if (!font->IsNull() && font->IsObject()) {
311             GetFontContent(font, labelStyle, isSubTabStyle);
312         }
313     }
314     CompleteParameters(labelStyle, isSubTabStyle);
315     TabContentModel::GetInstance()->SetLabelStyle(labelStyle);
316 }
317 
SetPadding(const JSRef<JSVal> & info,bool isSubTabStyle)318 void JSTabContent::SetPadding(const JSRef<JSVal>& info, bool isSubTabStyle)
319 {
320     CalcDimension length;
321     NG::PaddingProperty padding;
322     if (ParseJsDimensionVp(info, length) && NonNegative(length.Value()) && length.Unit() != DimensionUnit::PERCENT) {
323         padding.left = NG::CalcLength(length);
324         padding.right = NG::CalcLength(length);
325         padding.top = NG::CalcLength(length);
326         padding.bottom = NG::CalcLength(length);
327         TabContentModel::GetInstance()->SetPadding(padding);
328         return;
329     }
330 
331     RefPtr<TabTheme> tabTheme = GetTheme<TabTheme>();
332     if (tabTheme) {
333         if (isSubTabStyle) {
334             padding.top = NG::CalcLength(tabTheme->GetSubTabTopPadding());
335             padding.bottom = NG::CalcLength(tabTheme->GetSubTabBottomPadding());
336             padding.left = NG::CalcLength(tabTheme->GetSubTabHorizontalPadding());
337             padding.right = NG::CalcLength(tabTheme->GetSubTabHorizontalPadding());
338         } else {
339             padding.top = NG::CalcLength(0.0_vp);
340             padding.bottom = NG::CalcLength(0.0_vp);
341             padding.left = NG::CalcLength(tabTheme->GetBottomTabHorizontalPadding());
342             padding.right = NG::CalcLength(tabTheme->GetBottomTabHorizontalPadding());
343         }
344     }
345     if (info->IsObject()) {
346         JSRef<JSObject> paddingObj = JSRef<JSObject>::Cast(info);
347         CalcDimension left;
348         if (ParseJsDimensionVp(paddingObj->GetProperty("left"), left) && NonNegative(left.Value()) &&
349             left.Unit() != DimensionUnit::PERCENT) {
350             padding.left = NG::CalcLength(left);
351         }
352         CalcDimension right;
353         if (ParseJsDimensionVp(paddingObj->GetProperty("right"), right) && NonNegative(right.Value()) &&
354             right.Unit() != DimensionUnit::PERCENT) {
355             padding.right = NG::CalcLength(right);
356         }
357         CalcDimension top;
358         if (ParseJsDimensionVp(paddingObj->GetProperty("top"), top) && NonNegative(top.Value()) &&
359             top.Unit() != DimensionUnit::PERCENT) {
360             padding.top = NG::CalcLength(top);
361         }
362         CalcDimension bottom;
363         if (ParseJsDimensionVp(paddingObj->GetProperty("bottom"), bottom) && NonNegative(bottom.Value()) &&
364             bottom.Unit() != DimensionUnit::PERCENT) {
365             padding.bottom = NG::CalcLength(bottom);
366         }
367     }
368     TabContentModel::GetInstance()->SetPadding(padding);
369 }
370 
SetId(const JSRef<JSVal> & info)371 void JSTabContent::SetId(const JSRef<JSVal>& info)
372 {
373     std::string id;
374     if (!ParseJsString(info, id)) {
375         return;
376     }
377     TabContentModel::GetInstance()->SetId(id);
378 }
379 
CompleteParameters(LabelStyle & labelStyle,bool isSubTabStyle)380 void JSTabContent::CompleteParameters(LabelStyle& labelStyle, bool isSubTabStyle)
381 {
382     auto tabTheme = GetTheme<TabTheme>();
383     if (!tabTheme) {
384         return;
385     }
386     if (!labelStyle.maxLines.has_value()) {
387         labelStyle.maxLines = 1;
388     }
389     if (!labelStyle.minFontSize.has_value()) {
390         labelStyle.minFontSize = 0.0_vp;
391     }
392     if (!labelStyle.maxFontSize.has_value()) {
393         labelStyle.maxFontSize = 0.0_vp;
394     }
395     if (!labelStyle.fontSize.has_value()) {
396         if (isSubTabStyle) {
397             labelStyle.fontSize = tabTheme->GetSubTabTextDefaultFontSize();
398         } else {
399             labelStyle.fontSize = tabTheme->GetBottomTabTextSize();
400         }
401     }
402     if (!labelStyle.fontWeight.has_value() && !isSubTabStyle) {
403         labelStyle.fontWeight = FontWeight::MEDIUM;
404     }
405     if (!labelStyle.fontStyle.has_value()) {
406         labelStyle.fontStyle = FontStyle::NORMAL;
407     }
408     if (!labelStyle.fontFamily.has_value()) {
409         labelStyle.fontFamily = { "HarmonyOS Sans" };
410     }
411     if (!labelStyle.heightAdaptivePolicy.has_value()) {
412         labelStyle.heightAdaptivePolicy = TextHeightAdaptivePolicy::MAX_LINES_FIRST;
413     }
414     if (!labelStyle.textOverflow.has_value()) {
415         labelStyle.textOverflow = TextOverflow::ELLIPSIS;
416     }
417 }
418 
SetSubTabBarStyle(const JSRef<JSObject> & paramObject)419 void JSTabContent::SetSubTabBarStyle(const JSRef<JSObject>& paramObject)
420 {
421     JSRef<JSVal> contentParam = paramObject->GetProperty("content");
422     auto isContentEmpty = contentParam->IsEmpty() || contentParam->IsUndefined() || contentParam->IsNull();
423     if (isContentEmpty) {
424         LOGW("The content param is empty");
425     }
426     std::optional<std::string> contentOpt;
427     std::string content;
428     if (ParseJsString(contentParam, content)) {
429         contentOpt = content;
430     }
431 
432     JSRef<JSVal> indicatorParam = paramObject->GetProperty("indicator");
433     SetIndicator(indicatorParam);
434 
435     JSRef<JSVal> selectedModeParam = paramObject->GetProperty("selectedMode");
436     SetSelectedMode(selectedModeParam);
437 
438     JSRef<JSVal> boardParam = paramObject->GetProperty("board");
439     SetBoard(boardParam);
440 
441     JSRef<JSVal> labelStyleParam = paramObject->GetProperty("labelStyle");
442     SetLabelStyle(labelStyleParam, true);
443 
444     JSRef<JSVal> paddingParam = paramObject->GetProperty("padding");
445     SetPadding(paddingParam, true);
446 
447     JSRef<JSVal> idParam = paramObject->GetProperty("id");
448     SetId(idParam);
449 
450     TabContentModel::GetInstance()->SetTabBarStyle(TabBarStyle::SUBTABBATSTYLE);
451     TabContentModel::GetInstance()->SetTabBar(contentOpt, std::nullopt, nullptr, false);
452 }
453 
SetLayoutMode(const JSRef<JSVal> & info)454 void JSTabContent::SetLayoutMode(const JSRef<JSVal>& info)
455 {
456     int32_t layoutMode;
457     if (!ConvertFromJSValue(info, layoutMode)) {
458         TabContentModel::GetInstance()->SetLayoutMode(LayoutMode::VERTICAL);
459     } else {
460         TabContentModel::GetInstance()->SetLayoutMode(static_cast<LayoutMode>(layoutMode));
461     }
462 }
463 
SetVerticalAlign(const JSRef<JSVal> & info)464 void JSTabContent::SetVerticalAlign(const JSRef<JSVal>& info)
465 {
466     auto align = FlexAlign::CENTER;
467     if (info->IsNumber()) {
468         auto value = info->ToNumber<int32_t>();
469         if (value >= static_cast<int32_t>(FlexAlign::FLEX_START) &&
470             value <= static_cast<int32_t>(FlexAlign::FLEX_END)) {
471             align = static_cast<FlexAlign>(value);
472         }
473     }
474     TabContentModel::GetInstance()->SetVerticalAlign(align);
475 }
476 
SetSymmetricExtensible(const JSRef<JSVal> & info)477 void JSTabContent::SetSymmetricExtensible(const JSRef<JSVal>& info)
478 {
479     bool isExtensible = false;
480     ParseJsBool(info, isExtensible);
481     TabContentModel::GetInstance()->SetSymmetricExtensible(isExtensible);
482 }
483 
SetBottomTabBarStyle(const JSRef<JSObject> & paramObject)484 void JSTabContent::SetBottomTabBarStyle(const JSRef<JSObject>& paramObject)
485 {
486     JSRef<JSVal> textParam = paramObject->GetProperty("text");
487     std::optional<std::string> textOpt = std::nullopt;
488     std::string text;
489     if (ParseJsString(textParam, text)) {
490         textOpt = text;
491     }
492 
493     JSRef<JSVal> iconParam = paramObject->GetProperty("icon");
494     std::optional<std::string> iconOpt = std::nullopt;
495     std::string icon;
496     if (ParseJsMedia(iconParam, icon)) {
497         iconOpt = icon;
498     }
499 
500     JSRef<JSVal> paddingParam = paramObject->GetProperty("padding");
501     SetPadding(paddingParam, false);
502 
503     JSRef<JSVal> layoutParam = paramObject->GetProperty("layoutMode");
504     SetLayoutMode(layoutParam);
505 
506     JSRef<JSVal> verticalAlignParam = paramObject->GetProperty("verticalAlign");
507     SetVerticalAlign(verticalAlignParam);
508 
509     JSRef<JSVal> extensibleParam = paramObject->GetProperty("symmetricExtensible");
510     SetSymmetricExtensible(extensibleParam);
511 
512     JSRef<JSVal> labelStyleParam = paramObject->GetProperty("labelStyle");
513     SetLabelStyle(labelStyleParam, false);
514 
515     JSRef<JSVal> idParam = paramObject->GetProperty("id");
516     SetId(idParam);
517 
518     TabContentModel::GetInstance()->SetTabBarStyle(TabBarStyle::BOTTOMTABBATSTYLE);
519     TabContentModel::GetInstance()->SetTabBar(textOpt, iconOpt, nullptr, false);
520 }
521 
JSBind(BindingTarget globalObj)522 void JSTabContent::JSBind(BindingTarget globalObj)
523 {
524     JSClass<JSTabContent>::Declare("TabContent");
525     JSClass<JSTabContent>::StaticMethod("create", &JSTabContent::Create);
526     JSClass<JSTabContent>::StaticMethod("pop", &JSTabContent::Pop);
527     JSClass<JSTabContent>::StaticMethod("tabBar", &JSTabContent::SetTabBar);
528     JSClass<JSTabContent>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
529     JSClass<JSTabContent>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
530     JSClass<JSTabContent>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
531     JSClass<JSTabContent>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
532     JSClass<JSTabContent>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
533     JSClass<JSTabContent>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
534     JSClass<JSTabContent>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
535     JSClass<JSTabContent>::StaticMethod("width", &JSTabContent::SetTabContentWidth);
536     JSClass<JSTabContent>::StaticMethod("height", &JSTabContent::SetTabContentHeight);
537     JSClass<JSTabContent>::StaticMethod("size", &JSTabContent::SetTabContentSize);
538     JSClass<JSTabContent>::StaticMethod("remoteMessage", &JSInteractableView::JsCommonRemoteMessage);
539     JSClass<JSTabContent>::InheritAndBind<JSContainerBase>(globalObj);
540 }
541 
542 } // namespace OHOS::Ace::Framework
543