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)233 void JSTabContent::GetFontContent(const JSRef<JSVal> font, LabelStyle& labelStyle)
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 labelStyle.fontWeight = ConvertStrToFontWeight(weight->ToString());
246 }
247
248 JSRef<JSVal> family = obj->GetProperty("family");
249 std::vector<std::string> fontFamilies;
250 if (ParseJsFontFamilies(family, fontFamilies)) {
251 labelStyle.fontFamily = fontFamilies;
252 }
253
254 JSRef<JSVal> style = obj->GetProperty("style");
255 if (style->IsNumber()) {
256 int32_t value = style->ToNumber<int32_t>();
257 if (value >= 0 && value < static_cast<int32_t>(FONT_STYLES.size())) {
258 labelStyle.fontStyle = FONT_STYLES[value];
259 }
260 }
261 }
262
SetLabelStyle(const JSRef<JSVal> & info,bool isSubTabStyle)263 void JSTabContent::SetLabelStyle(const JSRef<JSVal>& info, bool isSubTabStyle)
264 {
265 LabelStyle labelStyle;
266 if (!info->IsObject()) {
267 LOGW("info not is Object");
268 } else {
269 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info);
270 JSRef<JSVal> overflowValue = obj->GetProperty("overflow");
271 if (!overflowValue->IsNull() && overflowValue->IsNumber()) {
272 auto overflow = overflowValue->ToNumber<int32_t>();
273 if (overflow >= 0 && overflow < static_cast<int32_t>(TEXT_OVERFLOWS.size())) {
274 labelStyle.textOverflow = TEXT_OVERFLOWS[overflow];
275 }
276 }
277
278 JSRef<JSVal> maxLines = obj->GetProperty("maxLines");
279 if (!maxLines->IsNull() && maxLines->IsNumber() && maxLines->ToNumber<int32_t>() > 0) {
280 labelStyle.maxLines = maxLines->ToNumber<int32_t>();
281 }
282
283 JSRef<JSVal> minFontSizeValue = obj->GetProperty("minFontSize");
284 CalcDimension minFontSize;
285 if (ParseJsDimensionFp(minFontSizeValue, minFontSize) && NonNegative(minFontSize.Value()) &&
286 minFontSize.Unit() != DimensionUnit::PERCENT) {
287 labelStyle.minFontSize = minFontSize;
288 }
289
290 JSRef<JSVal> maxFontSizeValue = obj->GetProperty("maxFontSize");
291 CalcDimension maxFontSize;
292 if (ParseJsDimensionFp(maxFontSizeValue, maxFontSize) && NonNegative(maxFontSize.Value()) &&
293 maxFontSize.Unit() != DimensionUnit::PERCENT) {
294 labelStyle.maxFontSize = maxFontSize;
295 }
296
297 JSRef<JSVal> heightAdaptivePolicyValue = obj->GetProperty("heightAdaptivePolicy");
298 if (!heightAdaptivePolicyValue->IsNull() && heightAdaptivePolicyValue->IsNumber()) {
299 auto heightAdaptivePolicy = heightAdaptivePolicyValue->ToNumber<int32_t>();
300 if (heightAdaptivePolicy >= 0 &&
301 heightAdaptivePolicy < static_cast<int32_t>(HEIGHT_ADAPTIVE_POLICIES.size())) {
302 labelStyle.heightAdaptivePolicy = HEIGHT_ADAPTIVE_POLICIES[heightAdaptivePolicy];
303 }
304 }
305
306 JSRef<JSVal> font = obj->GetProperty("font");
307 if (!font->IsNull() && font->IsObject()) {
308 GetFontContent(font, labelStyle);
309 }
310 }
311 CompleteParameters(labelStyle, isSubTabStyle);
312 TabContentModel::GetInstance()->SetLabelStyle(labelStyle);
313 }
314
SetPadding(const JSRef<JSVal> & info,bool isSubTabStyle)315 void JSTabContent::SetPadding(const JSRef<JSVal>& info, bool isSubTabStyle)
316 {
317 CalcDimension length;
318 NG::PaddingProperty padding;
319 if (ParseJsDimensionVp(info, length) && NonNegative(length.Value()) && length.Unit() != DimensionUnit::PERCENT) {
320 padding.left = NG::CalcLength(length);
321 padding.right = NG::CalcLength(length);
322 padding.top = NG::CalcLength(length);
323 padding.bottom = NG::CalcLength(length);
324 TabContentModel::GetInstance()->SetPadding(padding);
325 return;
326 }
327
328 RefPtr<TabTheme> tabTheme = GetTheme<TabTheme>();
329 if (tabTheme) {
330 if (isSubTabStyle) {
331 padding.top = NG::CalcLength(tabTheme->GetSubTabTopPadding());
332 padding.bottom = NG::CalcLength(tabTheme->GetSubTabBottomPadding());
333 padding.left = NG::CalcLength(tabTheme->GetSubTabHorizontalPadding());
334 padding.right = NG::CalcLength(tabTheme->GetSubTabHorizontalPadding());
335 } else {
336 padding.top = NG::CalcLength(0.0_vp);
337 padding.bottom = NG::CalcLength(0.0_vp);
338 padding.left = NG::CalcLength(tabTheme->GetBottomTabHorizontalPadding());
339 padding.right = NG::CalcLength(tabTheme->GetBottomTabHorizontalPadding());
340 }
341 }
342 if (info->IsObject()) {
343 JSRef<JSObject> paddingObj = JSRef<JSObject>::Cast(info);
344 CalcDimension left;
345 if (ParseJsDimensionVp(paddingObj->GetProperty("left"), left) && NonNegative(left.Value()) &&
346 left.Unit() != DimensionUnit::PERCENT) {
347 padding.left = NG::CalcLength(left);
348 }
349 CalcDimension right;
350 if (ParseJsDimensionVp(paddingObj->GetProperty("right"), right) && NonNegative(right.Value()) &&
351 right.Unit() != DimensionUnit::PERCENT) {
352 padding.right = NG::CalcLength(right);
353 }
354 CalcDimension top;
355 if (ParseJsDimensionVp(paddingObj->GetProperty("top"), top) && NonNegative(top.Value()) &&
356 top.Unit() != DimensionUnit::PERCENT) {
357 padding.top = NG::CalcLength(top);
358 }
359 CalcDimension bottom;
360 if (ParseJsDimensionVp(paddingObj->GetProperty("bottom"), bottom) && NonNegative(bottom.Value()) &&
361 bottom.Unit() != DimensionUnit::PERCENT) {
362 padding.bottom = NG::CalcLength(bottom);
363 }
364 }
365 TabContentModel::GetInstance()->SetPadding(padding);
366 }
367
CompleteParameters(LabelStyle & labelStyle,bool isSubTabStyle)368 void JSTabContent::CompleteParameters(LabelStyle& labelStyle, bool isSubTabStyle)
369 {
370 auto tabTheme = GetTheme<TabTheme>();
371 if (!tabTheme) {
372 return;
373 }
374 if (!labelStyle.maxLines.has_value()) {
375 labelStyle.maxLines = 1;
376 }
377 if (!labelStyle.minFontSize.has_value()) {
378 labelStyle.minFontSize = 0.0_vp;
379 }
380 if (!labelStyle.maxFontSize.has_value()) {
381 labelStyle.maxFontSize = 0.0_vp;
382 }
383 if (!labelStyle.fontSize.has_value()) {
384 if (isSubTabStyle) {
385 labelStyle.fontSize = tabTheme->GetSubTabTextDefaultFontSize();
386 } else {
387 labelStyle.fontSize = tabTheme->GetBottomTabTextSize();
388 }
389 }
390 if (!labelStyle.fontWeight.has_value()) {
391 if (isSubTabStyle) {
392 labelStyle.fontWeight = FontWeight::NORMAL;
393 } else {
394 labelStyle.fontWeight = FontWeight::MEDIUM;
395 }
396 }
397 if (!labelStyle.fontStyle.has_value()) {
398 labelStyle.fontStyle = FontStyle::NORMAL;
399 }
400 if (!labelStyle.fontFamily.has_value()) {
401 labelStyle.fontFamily = { "HarmonyOS Sans" };
402 }
403 if (!labelStyle.heightAdaptivePolicy.has_value()) {
404 labelStyle.heightAdaptivePolicy = TextHeightAdaptivePolicy::MAX_LINES_FIRST;
405 }
406 if (!labelStyle.textOverflow.has_value()) {
407 labelStyle.textOverflow = TextOverflow::ELLIPSIS;
408 }
409 }
410
SetSubTabBarStyle(const JSRef<JSObject> & paramObject)411 void JSTabContent::SetSubTabBarStyle(const JSRef<JSObject>& paramObject)
412 {
413 JSRef<JSVal> contentParam = paramObject->GetProperty("content");
414 auto isContentEmpty = contentParam->IsEmpty() || contentParam->IsUndefined() || contentParam->IsNull();
415 if (isContentEmpty) {
416 LOGW("The content param is empty");
417 }
418 std::optional<std::string> contentOpt;
419 std::string content;
420 if (ParseJsString(contentParam, content)) {
421 contentOpt = content;
422 }
423
424 JSRef<JSVal> indicatorParam = paramObject->GetProperty("indicator");
425 SetIndicator(indicatorParam);
426
427 JSRef<JSVal> selectedModeParam = paramObject->GetProperty("selectedMode");
428 SetSelectedMode(selectedModeParam);
429
430 JSRef<JSVal> boardParam = paramObject->GetProperty("board");
431 SetBoard(boardParam);
432
433 JSRef<JSVal> labelStyleParam = paramObject->GetProperty("labelStyle");
434 SetLabelStyle(labelStyleParam, true);
435
436 JSRef<JSVal> paddingParam = paramObject->GetProperty("padding");
437 SetPadding(paddingParam, true);
438
439 TabContentModel::GetInstance()->SetTabBarStyle(TabBarStyle::SUBTABBATSTYLE);
440 TabContentModel::GetInstance()->SetTabBar(contentOpt, std::nullopt, nullptr, false);
441 }
442
SetLayoutMode(const JSRef<JSVal> & info)443 void JSTabContent::SetLayoutMode(const JSRef<JSVal>& info)
444 {
445 int32_t layoutMode;
446 if (!ConvertFromJSValue(info, layoutMode)) {
447 TabContentModel::GetInstance()->SetLayoutMode(LayoutMode::VERTICAL);
448 } else {
449 TabContentModel::GetInstance()->SetLayoutMode(static_cast<LayoutMode>(layoutMode));
450 }
451 }
452
SetVerticalAlign(const JSRef<JSVal> & info)453 void JSTabContent::SetVerticalAlign(const JSRef<JSVal>& info)
454 {
455 auto align = FlexAlign::CENTER;
456 if (info->IsNumber()) {
457 auto value = info->ToNumber<int32_t>();
458 if (value >= static_cast<int32_t>(FlexAlign::FLEX_START) &&
459 value <= static_cast<int32_t>(FlexAlign::FLEX_END)) {
460 align = static_cast<FlexAlign>(value);
461 }
462 }
463 TabContentModel::GetInstance()->SetVerticalAlign(align);
464 }
465
SetSymmetricExtensible(const JSRef<JSVal> & info)466 void JSTabContent::SetSymmetricExtensible(const JSRef<JSVal>& info)
467 {
468 bool isExtensible = false;
469 ParseJsBool(info, isExtensible);
470 TabContentModel::GetInstance()->SetSymmetricExtensible(isExtensible);
471 }
472
SetBottomTabBarStyle(const JSRef<JSObject> & paramObject)473 void JSTabContent::SetBottomTabBarStyle(const JSRef<JSObject>& paramObject)
474 {
475 JSRef<JSVal> textParam = paramObject->GetProperty("text");
476 std::optional<std::string> textOpt = std::nullopt;
477 std::string text;
478 if (ParseJsString(textParam, text)) {
479 textOpt = text;
480 }
481
482 JSRef<JSVal> iconParam = paramObject->GetProperty("icon");
483 std::optional<std::string> iconOpt = std::nullopt;
484 std::string icon;
485 if (ParseJsMedia(iconParam, icon)) {
486 iconOpt = icon;
487 }
488
489 JSRef<JSVal> paddingParam = paramObject->GetProperty("padding");
490 SetPadding(paddingParam, false);
491
492 JSRef<JSVal> layoutParam = paramObject->GetProperty("layoutMode");
493 SetLayoutMode(layoutParam);
494
495 JSRef<JSVal> verticalAlignParam = paramObject->GetProperty("verticalAlign");
496 SetVerticalAlign(verticalAlignParam);
497
498 JSRef<JSVal> extensibleParam = paramObject->GetProperty("symmetricExtensible");
499 SetSymmetricExtensible(extensibleParam);
500
501 JSRef<JSVal> labelStyleParam = paramObject->GetProperty("labelStyle");
502 SetLabelStyle(labelStyleParam, false);
503
504 TabContentModel::GetInstance()->SetTabBarStyle(TabBarStyle::BOTTOMTABBATSTYLE);
505 TabContentModel::GetInstance()->SetTabBar(textOpt, iconOpt, nullptr, false);
506 }
507
JSBind(BindingTarget globalObj)508 void JSTabContent::JSBind(BindingTarget globalObj)
509 {
510 JSClass<JSTabContent>::Declare("TabContent");
511 JSClass<JSTabContent>::StaticMethod("create", &JSTabContent::Create);
512 JSClass<JSTabContent>::StaticMethod("pop", &JSTabContent::Pop);
513 JSClass<JSTabContent>::StaticMethod("tabBar", &JSTabContent::SetTabBar);
514 JSClass<JSTabContent>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
515 JSClass<JSTabContent>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
516 JSClass<JSTabContent>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
517 JSClass<JSTabContent>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
518 JSClass<JSTabContent>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
519 JSClass<JSTabContent>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
520 JSClass<JSTabContent>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
521 JSClass<JSTabContent>::StaticMethod("width", &JSTabContent::SetTabContentWidth);
522 JSClass<JSTabContent>::StaticMethod("height", &JSTabContent::SetTabContentHeight);
523 JSClass<JSTabContent>::StaticMethod("size", &JSTabContent::SetTabContentSize);
524 JSClass<JSTabContent>::StaticMethod("remoteMessage", &JSInteractableView::JsCommonRemoteMessage);
525 JSClass<JSTabContent>::InheritAndBind<JSContainerBase>(globalObj);
526 }
527
528 } // namespace OHOS::Ace::Framework
529