• 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_tabs.h"
17 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
18 
19 #include "base/log/ace_scoring_log.h"
20 #include "bridge/declarative_frontend/engine/functions/js_event_function.h"
21 #include "bridge/declarative_frontend/engine/functions/js_swiper_function.h"
22 #include "bridge/declarative_frontend/engine/functions/js_tabs_function.h"
23 #include "bridge/declarative_frontend/jsview/js_scrollable.h"
24 #include "bridge/declarative_frontend/jsview/js_tabs_controller.h"
25 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
26 #include "bridge/declarative_frontend/jsview/models/tabs_model_impl.h"
27 #include "core/animation/curve.h"
28 #include "core/components/common/layout/constants.h"
29 #include "core/components/common/properties/decoration.h"
30 #include "core/components_ng/base/view_stack_model.h"
31 #include "core/components_ng/base/view_stack_processor.h"
32 #include "core/components_ng/pattern/tabs/tab_content_transition_proxy.h"
33 #include "core/components_ng/pattern/tabs/tabs_model_ng.h"
34 
35 namespace OHOS::Ace {
36 
37 std::unique_ptr<TabsModel> TabsModel::instance_ = nullptr;
38 std::mutex TabsModel::mutex_;
39 
GetInstance()40 TabsModel* TabsModel::GetInstance()
41 {
42     if (!instance_) {
43         std::lock_guard<std::mutex> lock(mutex_);
44         if (!instance_) {
45 #ifdef NG_BUILD
46             instance_.reset(new NG::TabsModelNG());
47 #else
48             if (Container::IsCurrentUseNewPipeline()) {
49                 instance_.reset(new NG::TabsModelNG());
50             } else {
51                 instance_.reset(new Framework::TabsModelImpl());
52             }
53 #endif
54         }
55     }
56     return instance_.get();
57 }
58 
59 } // namespace OHOS::Ace
60 
61 namespace OHOS::Ace::Framework {
62 namespace {
63 constexpr int32_t PARAM_COUNT = 2;
64 constexpr int32_t SM_COLUMN_NUM = 4;
65 constexpr int32_t MD_COLUMN_NUM = 8;
66 constexpr int32_t LG_COLUMN_NUM = 12;
67 constexpr int32_t DEFAULT_CUSTOM_ANIMATION_TIMEOUT = 1000;
68 const std::vector<BarPosition> BAR_POSITIONS = { BarPosition::START, BarPosition::END };
69 
70 const std::vector<BlurStyle> BAR_BLURSTYLE = {
71     BlurStyle::NO_MATERIAL,
72     BlurStyle::THIN,
73     BlurStyle::REGULAR,
74     BlurStyle::THICK,
75     BlurStyle::BACKGROUND_THIN,
76     BlurStyle::BACKGROUND_REGULAR,
77     BlurStyle::BACKGROUND_THICK,
78     BlurStyle::BACKGROUND_ULTRA_THICK,
79     BlurStyle::COMPONENT_ULTRA_THIN,
80     BlurStyle::COMPONENT_THIN,
81     BlurStyle::COMPONENT_REGULAR,
82     BlurStyle::COMPONENT_THICK,
83     BlurStyle::COMPONENT_ULTRA_THICK,
84 };
85 
TabContentChangeEventToJSValue(const TabContentChangeEvent & eventInfo)86 JSRef<JSVal> TabContentChangeEventToJSValue(const TabContentChangeEvent& eventInfo)
87 {
88     return JSRef<JSVal>::Make(ToJSValue(eventInfo.GetIndex()));
89 }
90 
CreateAnimationCurveByObject(const JSCallbackInfo & info)91 RefPtr<Curve> CreateAnimationCurveByObject(const JSCallbackInfo& info)
92 {
93     RefPtr<Curve> curve;
94     if (!info[0]->IsObject()) {
95         return curve;
96     }
97     auto object = JSRef<JSObject>::Cast(info[0]);
98     std::function<float(float)> customCallBack = nullptr;
99     JSRef<JSVal> onCallBack = object->GetProperty("__curveCustomFunc");
100     if (onCallBack->IsFunction()) {
101         RefPtr<JsFunction> jsFuncCallBack =
102             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onCallBack));
103         customCallBack = [func = std::move(jsFuncCallBack), id = Container::CurrentId()](float time) -> float {
104             ContainerScope scope(id);
105             JSRef<JSVal> params[1];
106             params[0] = JSRef<JSVal>::Make(ToJSValue(time));
107             auto result = func->ExecuteJS(1, params);
108             auto resultValue = result->IsNumber() ? result->ToNumber<float>() : 1.0f;
109             return resultValue;
110         };
111     }
112     auto jsCurveString = object->GetProperty("__curveString");
113     if (jsCurveString->IsString()) {
114         auto aniTimFunc = jsCurveString->ToString();
115         if (aniTimFunc == DOM_ANIMATION_TIMING_FUNCTION_CUSTOM && customCallBack) {
116             curve = CreateCurve(customCallBack);
117         } else if (aniTimFunc != DOM_ANIMATION_TIMING_FUNCTION_CUSTOM) {
118             curve = CreateCurve(aniTimFunc, false);
119         }
120     }
121     return curve;
122 }
123 } // namespace
124 
SetOnChange(const JSCallbackInfo & info)125 void JSTabs::SetOnChange(const JSCallbackInfo& info)
126 {
127     if (!info[0]->IsFunction()) {
128         return;
129     }
130 
131     auto changeHandler = AceType::MakeRefPtr<JsEventFunction<TabContentChangeEvent, 1>>(
132         JSRef<JSFunc>::Cast(info[0]), TabContentChangeEventToJSValue);
133     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
134     auto onChange = [executionContext = info.GetExecutionContext(), func = std::move(changeHandler), node = targetNode](
135                         const BaseEventInfo* info) {
136         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
137         const auto* tabsInfo = TypeInfoHelper::DynamicCast<TabContentChangeEvent>(info);
138         if (!tabsInfo) {
139             TAG_LOGW(AceLogTag::ACE_TABS, "Tabs onChange callback execute failed.");
140             return;
141         }
142         ACE_SCORING_EVENT("Tabs.onChange");
143         ACE_SCOPED_TRACE("Tabs.onChange index %d", tabsInfo->GetIndex());
144         PipelineContext::SetCallBackNode(node);
145         func->Execute(*tabsInfo);
146     };
147     TabsModel::GetInstance()->SetOnChange(std::move(onChange));
148 }
149 
SetOnTabBarClick(const JSCallbackInfo & info)150 void JSTabs::SetOnTabBarClick(const JSCallbackInfo& info)
151 {
152     if (!info[0]->IsFunction()) {
153         return;
154     }
155 
156     auto changeHandler = AceType::MakeRefPtr<JsEventFunction<TabContentChangeEvent, 1>>(
157         JSRef<JSFunc>::Cast(info[0]), TabContentChangeEventToJSValue);
158     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
159     auto onTabBarClick = [executionContext = info.GetExecutionContext(), func = std::move(changeHandler),
160                              node = targetNode](const BaseEventInfo* info) {
161         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
162         const auto* tabsInfo = TypeInfoHelper::DynamicCast<TabContentChangeEvent>(info);
163         if (!tabsInfo) {
164             TAG_LOGW(AceLogTag::ACE_TABS, "Tabs onTabBarClick callback execute failed.");
165             return;
166         }
167         ACE_SCORING_EVENT("Tabs.onTabBarClick");
168         PipelineContext::SetCallBackNode(node);
169         func->Execute(*tabsInfo);
170         UiSessionManager::GetInstance()->ReportComponentChangeEvent("event", "Tabs.onTabBarClick");
171     };
172     TabsModel::GetInstance()->SetOnTabBarClick(std::move(onTabBarClick));
173 }
174 
SetOnUnselected(const JSCallbackInfo & info)175 void JSTabs::SetOnUnselected(const JSCallbackInfo& info)
176 {
177     if (!info[0]->IsFunction()) {
178         return;
179     }
180     auto unselectedHandler = AceType::MakeRefPtr<JsEventFunction<TabContentChangeEvent, 1>>(
181         JSRef<JSFunc>::Cast(info[0]), TabContentChangeEventToJSValue);
182     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
183     auto onUnselected = [executionContext = info.GetExecutionContext(), func = std::move(unselectedHandler),
184                           node = targetNode](const BaseEventInfo* info) {
185         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
186         const auto* tabsInfo = TypeInfoHelper::DynamicCast<TabContentChangeEvent>(info);
187         if (!tabsInfo) {
188             TAG_LOGW(AceLogTag::ACE_TABS, "Tabs onUnselected callback execute failed.");
189             return;
190         }
191         ACE_SCORING_EVENT("Tabs.onUnselected");
192         ACE_SCOPED_TRACE("Tabs.onUnselected index %d", tabsInfo->GetIndex());
193         PipelineContext::SetCallBackNode(node);
194         func->Execute(*tabsInfo);
195     };
196     TabsModel::GetInstance()->SetOnUnselected(std::move(onUnselected));
197 }
198 
SetOnAnimationStart(const JSCallbackInfo & info)199 void JSTabs::SetOnAnimationStart(const JSCallbackInfo& info)
200 {
201     if (!info[0]->IsFunction()) {
202         return;
203     }
204 
205     auto animationStartHandler = AceType::MakeRefPtr<JsSwiperFunction>(JSRef<JSFunc>::Cast(info[0]));
206     auto onAnimationStart = [executionContext = info.GetExecutionContext(),
207                                 func = std::move(animationStartHandler)](
208                                 int32_t index, int32_t targetIndex, const AnimationCallbackInfo& info) {
209         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
210         ACE_SCORING_EVENT("Tabs.onAnimationStart");
211         func->Execute(index, targetIndex, info);
212     };
213     TabsModel::GetInstance()->SetOnAnimationStart(std::move(onAnimationStart));
214 }
215 
SetOnAnimationEnd(const JSCallbackInfo & info)216 void JSTabs::SetOnAnimationEnd(const JSCallbackInfo& info)
217 {
218     if (!info[0]->IsFunction()) {
219         return;
220     }
221 
222     auto animationEndHandler = AceType::MakeRefPtr<JsSwiperFunction>(JSRef<JSFunc>::Cast(info[0]));
223     auto onAnimationEnd = [executionContext = info.GetExecutionContext(), func = std::move(animationEndHandler)](
224                               int32_t index, const AnimationCallbackInfo& info) {
225         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
226         ACE_SCORING_EVENT("Tabs.onAnimationEnd");
227         func->Execute(index, info);
228         UiSessionManager::GetInstance()->ReportComponentChangeEvent("event", "Tabs.onAnimationEnd");
229     };
230     TabsModel::GetInstance()->SetOnAnimationEnd(std::move(onAnimationEnd));
231 }
232 
SetOnGestureSwipe(const JSCallbackInfo & info)233 void JSTabs::SetOnGestureSwipe(const JSCallbackInfo& info)
234 {
235     if (!info[0]->IsFunction()) {
236         return;
237     }
238 
239     auto gestureSwipeHandler = AceType::MakeRefPtr<JsSwiperFunction>(JSRef<JSFunc>::Cast(info[0]));
240     auto onGestureSwipe = [executionContext = info.GetExecutionContext(), func = std::move(gestureSwipeHandler)](
241                               int32_t index, const AnimationCallbackInfo& info) {
242         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
243         ACE_SCORING_EVENT("Tabs.onGestureSwipe");
244         func->Execute(index, info);
245     };
246     TabsModel::GetInstance()->SetOnGestureSwipe(std::move(onGestureSwipe));
247 }
248 
SetOnSelected(const JSCallbackInfo & info)249 void JSTabs::SetOnSelected(const JSCallbackInfo& info)
250 {
251     if (!info[0]->IsFunction()) {
252         return;
253     }
254     auto selectedHandler = AceType::MakeRefPtr<JsEventFunction<TabContentChangeEvent, 1>>(
255         JSRef<JSFunc>::Cast(info[0]), TabContentChangeEventToJSValue);
256     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
257     auto onSelected = [executionContext = info.GetExecutionContext(), func = std::move(selectedHandler),
258                           node = targetNode](const BaseEventInfo* info) {
259         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
260         const auto* tabsInfo = TypeInfoHelper::DynamicCast<TabContentChangeEvent>(info);
261         if (!tabsInfo) {
262             TAG_LOGW(AceLogTag::ACE_TABS, "Tabs onSelected callback execute failed.");
263             return;
264         }
265         ACE_SCORING_EVENT("Tabs.onSelected");
266         ACE_SCOPED_TRACE("Tabs.onSelected index %d", tabsInfo->GetIndex());
267         PipelineContext::SetCallBackNode(node);
268         func->Execute(*tabsInfo);
269     };
270     TabsModel::GetInstance()->SetOnSelected(std::move(onSelected));
271 }
272 
ParseTabsIndexObject(const JSCallbackInfo & info,const JSRef<JSVal> & changeEventVal)273 void ParseTabsIndexObject(const JSCallbackInfo& info, const JSRef<JSVal>& changeEventVal)
274 {
275     CHECK_NULL_VOID(!changeEventVal->IsUndefined() && changeEventVal->IsFunction());
276 
277     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
278     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
279     auto onChangeEvent = [executionContext = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
280                              const BaseEventInfo* info) {
281         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
282         const auto* tabsInfo = TypeInfoHelper::DynamicCast<TabContentChangeEvent>(info);
283         if (!tabsInfo) {
284             TAG_LOGW(AceLogTag::ACE_TABS, "ParseTabsIndexObject execute onChange event failed.");
285             return;
286         }
287         ACE_SCORING_EVENT("Tabs.onChangeEvent");
288         PipelineContext::SetCallBackNode(node);
289         auto newJSVal = JSRef<JSVal>::Make(ToJSValue(tabsInfo->GetIndex()));
290         func->ExecuteJS(1, &newJSVal);
291     };
292     TabsModel::GetInstance()->SetOnChangeEvent(std::move(onChangeEvent));
293 }
294 
Create(const JSCallbackInfo & info)295 void JSTabs::Create(const JSCallbackInfo& info)
296 {
297     BarPosition barPosition = BarPosition::START;
298     RefPtr<TabController> tabController;
299     RefPtr<NG::TabsControllerNG> tabsController = AceType::MakeRefPtr<NG::TabsControllerNG>();
300     int32_t index = -1;
301     JSRef<JSVal> changeEventVal;
302     auto jsValue = info[0];
303     if (jsValue->IsObject()) {
304         JSRef<JSObject> obj = JSRef<JSObject>::Cast(jsValue);
305         JSRef<JSVal> val = obj->GetProperty("barPosition");
306         if (val->IsNumber()) {
307             auto barPositionVal = val->ToNumber<int32_t>();
308             if (barPositionVal >= 0 && barPositionVal < static_cast<int32_t>(BAR_POSITIONS.size())) {
309                 barPosition = BAR_POSITIONS[barPositionVal];
310             }
311         }
312         JSRef<JSVal> controller = obj->GetProperty("controller");
313         if (controller->IsObject()) {
314             auto* jsTabsController = JSRef<JSObject>::Cast(controller)->Unwrap<JSTabsController>();
315             if (jsTabsController) {
316                 jsTabsController->SetInstanceId(Container::CurrentId());
317                 tabController = jsTabsController->GetController();
318                 jsTabsController->SetTabsController(tabsController);
319             }
320         }
321         JSRef<JSVal> indexVal = obj->GetProperty("index");
322         if (indexVal->IsNumber()) {
323             index = indexVal->ToNumber<int32_t>();
324             index = index < 0 ? 0 : index;
325             if (!tabController) {
326                 tabController = JSTabsController::CreateController();
327             }
328 #ifndef NG_BUILD
329             tabController->SetInitialIndex(index);
330 #endif
331             changeEventVal = obj->GetProperty("$index");
332         } else if (indexVal->IsObject()) {
333             JSRef<JSObject> indexObj = JSRef<JSObject>::Cast(indexVal);
334             auto indexValueProperty = indexObj->GetProperty("value");
335             if (indexValueProperty->IsNumber()) {
336                 index = indexValueProperty->ToNumber<int32_t>();
337                 index = index < 0 ? 0 : index;
338             }
339             changeEventVal = indexObj->GetProperty("changeEvent");
340         }
341     }
342 
343     TabsModel::GetInstance()->Create(barPosition, index, tabController, tabsController);
344     ParseTabsIndexObject(info, changeEventVal);
345     SetBarModifier(info, jsValue);
346 }
347 
Pop()348 void JSTabs::Pop()
349 {
350     if (ViewStackModel::GetInstance()->IsPrebuilding()) {
351         return ViewStackModel::GetInstance()->PushPrebuildCompCmd("[JSTabs][pop]", &JSTabs::Pop);
352     }
353     TabsModel::GetInstance()->Pop();
354 }
355 
SetBarPosition(const JSCallbackInfo & info)356 void JSTabs::SetBarPosition(const JSCallbackInfo& info)
357 {
358     BarPosition barVal = BarPosition::START;
359     if (info.Length() > 0 && info[0]->IsNumber()) {
360         auto barPositionVal = info[0]->ToNumber<int32_t>();
361         if (barPositionVal >= 0 && barPositionVal < static_cast<int32_t>(BAR_POSITIONS.size())) {
362             barVal = BAR_POSITIONS[barPositionVal];
363         }
364     }
365 
366     TabsModel::GetInstance()->SetTabBarPosition(barVal);
367 }
368 
SetVertical(const std::string & value)369 void JSTabs::SetVertical(const std::string& value)
370 {
371     TabsModel::GetInstance()->SetIsVertical(StringToBool(value));
372 }
373 
SetScrollable(const std::string & value)374 void JSTabs::SetScrollable(const std::string& value)
375 {
376     if (value == "undefined") {
377         TabsModel::GetInstance()->SetScrollable(true);
378         return;
379     }
380     TabsModel::GetInstance()->SetScrollable(StringToBool(value));
381 }
382 
SetBarMode(const JSCallbackInfo & info)383 void JSTabs::SetBarMode(const JSCallbackInfo& info)
384 {
385     TabBarMode barMode = TabBarMode::FIXED;
386     if (info.Length() < 1) {
387         TabsModel::GetInstance()->SetTabBarMode(barMode);
388         return;
389     }
390     auto barModeInfo = info[0];
391     if (barModeInfo->IsString()) {
392         barMode = ConvertStrToTabBarMode(barModeInfo->ToString());
393     }
394     if (barMode == TabBarMode::SCROLLABLE) {
395         if (info.Length() > 1 && info[1]->IsObject()) {
396             SetScrollableBarModeOptions(info[1]);
397         } else {
398             TabsModel::GetInstance()->ResetScrollableBarModeOptions();
399         }
400     }
401     TabsModel::GetInstance()->SetTabBarMode(barMode);
402 }
403 
SetBarWidth(const JSCallbackInfo & info)404 void JSTabs::SetBarWidth(const JSCallbackInfo& info)
405 {
406     if (info.Length() < 1) {
407         return;
408     }
409     RefPtr<ResourceObject> widthResObj;
410     CalcDimension width = Dimension(-1.0, DimensionUnit::VP);
411     TabsModel::GetInstance()->CreateWithResourceObj(TabJsResType::BAR_WIDTH, nullptr);
412     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
413         if (!ParseJsDimensionVpNG(info[0], width, widthResObj)) {
414             width = Dimension(-1.0, DimensionUnit::VP);
415             TabsModel::GetInstance()->SetTabBarWidth(width);
416             return;
417         }
418     } else {
419         ParseJsDimensionVp(info[0], width);
420     }
421     TabsModel::GetInstance()->SetTabBarWidth(width);
422     TabsModel::GetInstance()->CreateWithResourceObj(TabJsResType::BAR_WIDTH, widthResObj);
423 }
424 
SetBarHeight(const JSCallbackInfo & info)425 void JSTabs::SetBarHeight(const JSCallbackInfo& info)
426 {
427     if (info.Length() < 1) {
428         return;
429     }
430     CalcDimension height = Dimension(-1.0, DimensionUnit::VP);
431     RefPtr<ResourceObject> heightResObj;
432     bool adaptiveHeight = false;
433     bool noMinHeightLimit = false;
434     auto barHeightInfo = info[0];
435     if (info.Length() == 2) { //2 is info length
436         auto minHeightLimitInfo = info[1];
437         if (minHeightLimitInfo->IsBoolean()) {
438             noMinHeightLimit = minHeightLimitInfo->ToBoolean();
439         }
440     }
441 
442     if (barHeightInfo->IsString() && barHeightInfo->ToString() == "auto") {
443         adaptiveHeight = true;
444     } else {
445         if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
446             if (!ParseJsDimensionVpNG(barHeightInfo, height, heightResObj)) {
447                 height = Dimension(-1.0, DimensionUnit::VP);
448             }
449         } else {
450             ParseJsDimensionVp(barHeightInfo, height);
451         }
452     }
453     TabsModel::GetInstance()->SetBarAdaptiveHeight(adaptiveHeight);
454     TabsModel::GetInstance()->SetNoMinHeightLimit(noMinHeightLimit);
455     TabsModel::GetInstance()->SetTabBarHeight(height);
456     TabsModel::GetInstance()->CreateWithResourceObj(TabJsResType::BAR_HEIGHT, heightResObj);
457 }
458 
SetWidth(const JSCallbackInfo & info)459 void JSTabs::SetWidth(const JSCallbackInfo& info)
460 {
461     JSViewAbstract::JsWidth(info);
462     if (info.Length() < 1) {
463         return;
464     }
465     auto widthInfo = info[0];
466     if (widthInfo->IsString() && widthInfo->ToString().empty()) {
467         return;
468     }
469     if (widthInfo->IsString() && widthInfo->ToString() == "auto") {
470         ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
471         TabsModel::GetInstance()->SetWidthAuto(true);
472         return;
473     }
474 
475     TabsModel::GetInstance()->SetWidthAuto(false);
476 }
477 
SetHeight(const JSCallbackInfo & info)478 void JSTabs::SetHeight(const JSCallbackInfo& info)
479 {
480     JSViewAbstract::JsHeight(info);
481     if (info.Length() < 1) {
482         return;
483     }
484     auto heightInfo = info[0];
485     if (heightInfo->IsString() && heightInfo->ToString().empty()) {
486         return;
487     }
488     if (heightInfo->IsString() && heightInfo->ToString() == "auto") {
489         ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
490         TabsModel::GetInstance()->SetHeightAuto(true);
491         return;
492     }
493 
494     TabsModel::GetInstance()->SetHeightAuto(false);
495 }
496 
SetIndex(int32_t index)497 void JSTabs::SetIndex(int32_t index)
498 {
499     TabsModel::GetInstance()->SetIndex(index);
500 }
501 
SetAnimationCurve(const JSCallbackInfo & info)502 void JSTabs::SetAnimationCurve(const JSCallbackInfo& info)
503 {
504     RefPtr<Curve> curve;
505     if (info[0]->IsString()) {
506         curve = CreateCurve(info[0]->ToString(), false);
507     } else if (info[0]->IsObject()) {
508         curve = CreateAnimationCurveByObject(info);
509     }
510     TabsModel::GetInstance()->SetAnimationCurve(curve);
511 }
512 
SetAnimationDuration(const JSCallbackInfo & info)513 void JSTabs::SetAnimationDuration(const JSCallbackInfo& info)
514 {
515     if (info.Length() <= 0) {
516         TabsModel::GetInstance()->SetAnimationDuration(-1);
517         return;
518     }
519     auto animationDurationInfo = info[0];
520     if ((!animationDurationInfo->IsNull() && !animationDurationInfo->IsNumber()) ||
521         (animationDurationInfo->IsNull() && Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
522         TabsModel::GetInstance()->SetAnimationDuration(-1);
523         return;
524     }
525     auto value = animationDurationInfo->IsNumber() ? animationDurationInfo->ToNumber<int32_t>() : 0;
526     TabsModel::GetInstance()->SetAnimationDuration(value);
527 }
528 
SetFadingEdge(const JSCallbackInfo & info)529 void JSTabs::SetFadingEdge(const JSCallbackInfo& info)
530 {
531     bool fadingEdge = true;
532     if (info.Length() > 0) {
533         ParseJsBool(info[0], fadingEdge);
534     }
535     TabsModel::GetInstance()->SetFadingEdge(fadingEdge);
536 }
537 
SetBarOverlap(const JSCallbackInfo & info)538 void JSTabs::SetBarOverlap(const JSCallbackInfo& info)
539 {
540     bool barOverlap = false;
541     if (info.Length() > 0) {
542         ParseJsBool(info[0], barOverlap);
543     }
544     TabsModel::GetInstance()->SetBarOverlap(barOverlap);
545 }
546 
SetBarBackgroundColor(const JSCallbackInfo & info)547 void JSTabs::SetBarBackgroundColor(const JSCallbackInfo& info)
548 {
549     RefPtr<ResourceObject> resObj;
550     Color backgroundColor = Color::BLACK.BlendOpacity(0.0f);
551     if (info.Length() > 0) {
552         if (ConvertFromJSValue(info[0], backgroundColor, resObj)) {
553             TabsModel::GetInstance()->SetBarBackgroundColorByUser(true);
554         } else {
555             TabsModel::GetInstance()->SetBarBackgroundColorByUser(false);
556         }
557     }
558     if (SystemProperties::ConfigChangePerform()) {
559         TabsModel::GetInstance()->CreateWithResourceObj(TabJsResType::BAR_BACKGROUND_COLOR, resObj);
560     }
561     TabsModel::GetInstance()->SetBarBackgroundColor(backgroundColor);
562 }
563 
SetBarBackgroundBlurStyle(const JSCallbackInfo & info)564 void JSTabs::SetBarBackgroundBlurStyle(const JSCallbackInfo& info)
565 {
566     if (info.Length() == 0) {
567         return;
568     }
569     BlurStyleOption styleOption;
570     if (info[0]->IsNumber()) {
571         auto blurStyle = info[0]->ToNumber<int32_t>();
572         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
573             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
574             styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
575         }
576     }
577     RefPtr<ResourceObject> inactiveColorStrObj;
578     if (info.Length() > 1 && info[1]->IsObject()) {
579         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
580         ParseBlurStyleOption(jsOption, styleOption);
581         if (SystemProperties::ConfigChangePerform()) {
582             ParseJsColor(jsOption->GetProperty("inactiveColor"), styleOption.inactiveColor, inactiveColorStrObj);
583         }
584     }
585     TabsModel::GetInstance()->SetBarBackgroundBlurStyle(styleOption);
586     TabsModel::GetInstance()->CreateWithResourceObj(TabJsResType::BlurStyle_INACTIVE_COLOR, inactiveColorStrObj);
587 }
588 
SetDivider(const JSCallbackInfo & info)589 void JSTabs::SetDivider(const JSCallbackInfo& info)
590 {
591     TabsItemDivider divider;
592     CalcDimension dividerStrokeWidth;
593     CalcDimension dividerStartMargin;
594     CalcDimension dividerEndMargin;
595     RefPtr<TabTheme> tabTheme = GetTheme<TabTheme>();
596     CHECK_NULL_VOID(tabTheme);
597     RefPtr<ResourceObject> widthResObj;
598     RefPtr<ResourceObject> colorResObj;
599     RefPtr<ResourceObject> startMarginResObj;
600     RefPtr<ResourceObject> endMarginResObj;
601 
602     if (info.Length() > 0) {
603         auto dividerInfo = info[0];
604         JSRef<JSObject> obj = JSRef<JSObject>::New();
605         if (dividerInfo->IsObject()) {
606             obj = JSRef<JSObject>::Cast(dividerInfo);
607         }
608         if (dividerInfo->IsNull()) {
609             divider.isNull = true;
610         } else {
611             if (!dividerInfo->IsObject() ||
612                 !ParseJsDimensionVp(obj->GetProperty("strokeWidth"), dividerStrokeWidth, widthResObj) ||
613                 dividerStrokeWidth.Value() < 0.0f || dividerStrokeWidth.Unit() == DimensionUnit::PERCENT) {
614                 divider.strokeWidth.Reset();
615             } else {
616                 divider.strokeWidth = dividerStrokeWidth;
617             }
618             if (!dividerInfo->IsObject() ||
619                 !ConvertFromJSValue(obj->GetProperty("color"), divider.color, colorResObj)) {
620                 divider.color = tabTheme->GetDividerColor();
621                 TabsModel::GetInstance()->SetDividerColorByUser(false);
622             } else {
623                 TabsModel::GetInstance()->SetDividerColorByUser(true);
624             }
625             if (!dividerInfo->IsObject() ||
626                 !ParseJsDimensionVp(obj->GetProperty("startMargin"), dividerStartMargin, startMarginResObj) ||
627                 dividerStartMargin.Value() < 0.0f || dividerStartMargin.Unit() == DimensionUnit::PERCENT) {
628                 divider.startMargin.Reset();
629             } else {
630                 divider.startMargin = dividerStartMargin;
631             }
632             if (!dividerInfo->IsObject() ||
633                 !ParseJsDimensionVp(obj->GetProperty("endMargin"), dividerEndMargin, endMarginResObj) ||
634                 dividerEndMargin.Value() < 0.0f || dividerEndMargin.Unit() == DimensionUnit::PERCENT) {
635                 divider.endMargin.Reset();
636             } else {
637                 divider.endMargin = dividerEndMargin;
638             }
639         }
640     }
641     TabsModel::GetInstance()->SetDivider(divider);
642     TabsModel::GetInstance()->CreateWithResourceObj(TabJsResType::DIVIDER_STROKE_WIDTH, widthResObj);
643     TabsModel::GetInstance()->CreateWithResourceObj(TabJsResType::DIVIDER_COLOR, colorResObj);
644     TabsModel::GetInstance()->CreateWithResourceObj(TabJsResType::DIVIDER_START_MARGIN, startMarginResObj);
645     TabsModel::GetInstance()->CreateWithResourceObj(TabJsResType::DIVIDER_END_MARGIN, endMarginResObj);
646 }
647 
SetClip(const JSCallbackInfo & info)648 void JSTabs::SetClip(const JSCallbackInfo& info)
649 {
650     if (info[0]->IsObject() || !Container::IsCurrentUseNewPipeline()) {
651         JSViewAbstract::JsClip(info);
652         return;
653     }
654     if (info[0]->IsBoolean()) {
655         TabsModel::GetInstance()->SetClipEdge(info[0]->ToBoolean());
656     }
657 }
658 
SetScrollableBarModeOptions(const JSRef<JSVal> & info)659 void JSTabs::SetScrollableBarModeOptions(const JSRef<JSVal>& info)
660 {
661     ScrollableBarModeOptions option;
662     RefPtr<ResourceObject> resObj;
663     auto optionParam = JSRef<JSObject>::Cast(info);
664     CalcDimension margin = Dimension(0.0, DimensionUnit::VP);
665     if (!ParseJsDimensionVp(optionParam->GetProperty("margin"), margin, resObj) || Negative(margin.Value()) ||
666         margin.Unit() == DimensionUnit::PERCENT) {
667         option.margin = 0.0_vp;
668     } else {
669         option.margin = margin;
670     }
671     auto nonScrollableLayoutStyle = optionParam->GetProperty("nonScrollableLayoutStyle");
672     int32_t layoutStyle;
673     if (!ConvertFromJSValue(nonScrollableLayoutStyle, layoutStyle) ||
674         layoutStyle < static_cast<int32_t>(LayoutStyle::ALWAYS_CENTER) ||
675         layoutStyle > static_cast<int32_t>(LayoutStyle::SPACE_BETWEEN_OR_CENTER)) {
676         option.nonScrollableLayoutStyle = std::nullopt;
677     } else {
678         option.nonScrollableLayoutStyle = (static_cast<LayoutStyle>(layoutStyle));
679     }
680     TabsModel::GetInstance()->SetScrollableBarModeOptions(option);
681     TabsModel::GetInstance()->CreateWithResourceObj(TabJsResType::SCROLLABLE_BAR_MARGIN, resObj);
682 }
683 
SetBarGridAlign(const JSCallbackInfo & info)684 void JSTabs::SetBarGridAlign(const JSCallbackInfo& info)
685 {
686     BarGridColumnOptions columnOption;
687     RefPtr<ResourceObject> gutterResObj;
688     RefPtr<ResourceObject> marginResObj;
689     if (info.Length() > 0 && info[0]->IsObject()) {
690         auto gridParam = JSRef<JSObject>::Cast(info[0]);
691         auto sm = gridParam->GetProperty("sm");
692         if (sm->IsNumber() && sm->ToNumber<int32_t>() >= 0 && sm->ToNumber<int32_t>() <= SM_COLUMN_NUM &&
693             sm->ToNumber<int32_t>() % 2 == 0) {
694             columnOption.sm = sm->ToNumber<int32_t>();
695         }
696         auto md = gridParam->GetProperty("md");
697         if (md->IsNumber() && md->ToNumber<int32_t>() >= 0 && md->ToNumber<int32_t>() <= MD_COLUMN_NUM &&
698             md->ToNumber<int32_t>() % 2 == 0) {
699             columnOption.md = md->ToNumber<int32_t>();
700         }
701         auto lg = gridParam->GetProperty("lg");
702         if (lg->IsNumber() && lg->ToNumber<int32_t>() >= 0 && lg->ToNumber<int32_t>() <= LG_COLUMN_NUM &&
703             lg->ToNumber<int32_t>() % 2 == 0) {
704             columnOption.lg = lg->ToNumber<int32_t>();
705         }
706         CalcDimension columnGutter;
707         if (ParseJsDimensionVp(gridParam->GetProperty("gutter"), columnGutter, gutterResObj) &&
708             NonNegative(columnGutter.Value()) && columnGutter.Unit() != DimensionUnit::PERCENT) {
709             columnOption.gutter = columnGutter;
710         }
711         CalcDimension columnMargin;
712         if (ParseJsDimensionVp(gridParam->GetProperty("margin"), columnMargin, marginResObj) &&
713             NonNegative(columnMargin.Value()) && columnMargin.Unit() != DimensionUnit::PERCENT) {
714             columnOption.margin = columnMargin;
715         }
716     }
717     TabsModel::GetInstance()->SetBarGridAlign(columnOption);
718     TabsModel::GetInstance()->CreateWithResourceObj(TabJsResType::BAR_GRID_GUTTER, gutterResObj);
719     TabsModel::GetInstance()->CreateWithResourceObj(TabJsResType::BAR_GRID_MARGIN, marginResObj);
720 }
721 
SetCustomContentTransition(const JSCallbackInfo & info)722 void JSTabs::SetCustomContentTransition(const JSCallbackInfo& info)
723 {
724     if (info.Length() != 1) {
725         return;
726     }
727 
728     auto customContentTransitionInfo = info[0];
729     if (customContentTransitionInfo->IsUndefined() || !customContentTransitionInfo->IsFunction()) {
730         TabsModel::GetInstance()->SetIsCustomAnimation(false);
731         return;
732     }
733 
734     RefPtr<JsTabsFunction> jsCustomAnimationFunc =
735         AceType::MakeRefPtr<JsTabsFunction>(JSRef<JSFunc>::Cast(customContentTransitionInfo));
736     auto onCustomAnimation = [execCtx = info.GetExecutionContext(), func = std::move(jsCustomAnimationFunc)](
737                                  int32_t from, int32_t to) -> TabContentAnimatedTransition {
738         TabContentAnimatedTransition transitionInfo;
739         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, transitionInfo);
740 
741         auto ret = func->Execute(from, to);
742         if (!ret->IsObject()) {
743             return transitionInfo;
744         }
745 
746         auto transitionObj = JSRef<JSObject>::Cast(ret);
747         JSRef<JSVal> timeoutProperty = transitionObj->GetProperty("timeout");
748         if (timeoutProperty->IsNumber()) {
749             auto timeout = timeoutProperty->ToNumber<int32_t>();
750             transitionInfo.timeout = timeout < 0 ? DEFAULT_CUSTOM_ANIMATION_TIMEOUT : timeout;
751         } else {
752             transitionInfo.timeout = DEFAULT_CUSTOM_ANIMATION_TIMEOUT;
753         }
754 
755         JSRef<JSVal> transition = transitionObj->GetProperty("transition");
756         if (transition->IsFunction()) {
757             RefPtr<JsTabsFunction> jsOnTransition =
758                 AceType::MakeRefPtr<JsTabsFunction>(JSRef<JSFunc>::Cast(transition));
759             auto onTransition = [execCtx, func = std::move(jsOnTransition)](
760                                     const RefPtr<TabContentTransitionProxy>& proxy) {
761                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
762                 ACE_SCORING_EVENT("onTransition");
763                 func->Execute(proxy);
764             };
765 
766             transitionInfo.transition = std::move(onTransition);
767         }
768 
769         return transitionInfo;
770     };
771     TabsModel::GetInstance()->SetIsCustomAnimation(true);
772     TabsModel::GetInstance()->SetOnCustomAnimation(std::move(onCustomAnimation));
773 }
774 
SetOnContentWillChange(const JSCallbackInfo & info)775 void JSTabs::SetOnContentWillChange(const JSCallbackInfo& info)
776 {
777     if (!info[0]->IsFunction()) {
778         return;
779     }
780 
781     auto handler = AceType::MakeRefPtr<JsTabsFunction>(JSRef<JSFunc>::Cast(info[0]));
782     auto callback = [execCtx = info.GetExecutionContext(), func = std::move(handler)]
783         (int32_t currentIndex, int32_t comingIndex) -> bool {
784         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, true);
785         ACE_SCORING_EVENT("Tabs.onContentWillChange");
786         auto ret = func->Execute(currentIndex, comingIndex);
787         if (!ret->IsBoolean()) {
788             return true;
789         }
790         return ret->ToBoolean();
791     };
792     TabsModel::GetInstance()->SetOnContentWillChange(std::move(callback));
793 }
794 
SetAnimateMode(const JSCallbackInfo & info)795 void JSTabs::SetAnimateMode(const JSCallbackInfo& info)
796 {
797     JSRef<JSVal> args = info[0];
798     if (!args->IsNumber()) {
799         TabsModel::GetInstance()->SetAnimateMode(TabAnimateMode::CONTENT_FIRST);
800         return;
801     }
802     uint32_t value = args->ToNumber<uint32_t>();
803     if (value >= static_cast<uint32_t>(TabAnimateMode::MAX_VALUE)) {
804         TabsModel::GetInstance()->SetAnimateMode(TabAnimateMode::CONTENT_FIRST);
805         return;
806     }
807     TabsModel::GetInstance()->SetAnimateMode(static_cast<TabAnimateMode>(value));
808 }
809 
SetEdgeEffect(const JSCallbackInfo & info)810 void JSTabs::SetEdgeEffect(const JSCallbackInfo& info)
811 {
812     auto edgeEffect = EdgeEffect::SPRING;
813     if (info.Length() > 0) {
814         edgeEffect = JSScrollable::ParseEdgeEffect(info[0], EdgeEffect::SPRING);
815     }
816     TabsModel::GetInstance()->SetEdgeEffect(edgeEffect);
817 }
818 
SetBarBackgroundEffect(const JSCallbackInfo & info)819 void JSTabs::SetBarBackgroundEffect(const JSCallbackInfo& info)
820 {
821     if (info.Length() == 0) {
822         return;
823     }
824     EffectOption option;
825     RefPtr<ResourceObject> colorStrObj;
826     RefPtr<ResourceObject> inactiveColorStrObj;
827     if (info[0]->IsObject()) {
828         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
829         ParseEffectOption(jsOption, option);
830         if (SystemProperties::ConfigChangePerform()) {
831             ParseJsColor(jsOption->GetProperty("color"), option.color, colorStrObj);
832             ParseJsColor(jsOption->GetProperty("inactiveColor"), option.inactiveColor, inactiveColorStrObj);
833         }
834     }
835     TabsModel::GetInstance()->SetBarBackgroundEffect(option);
836     TabsModel::GetInstance()->CreateWithResourceObj(TabJsResType::COLOR, colorStrObj);
837     TabsModel::GetInstance()->CreateWithResourceObj(TabJsResType::INACTIVE_COLOR, inactiveColorStrObj);
838 }
839 
SetPageFlipMode(const JSCallbackInfo & info)840 void JSTabs::SetPageFlipMode(const JSCallbackInfo& info)
841 {
842     // default value
843     int32_t value = 0;
844     if (info.Length() < 1 || !info[0]->IsNumber()) {
845         TabsModel::GetInstance()->SetPageFlipMode(value);
846         return;
847     }
848     JSViewAbstract::ParseJsInt32(info[0], value);
849     TabsModel::GetInstance()->SetPageFlipMode(value);
850 }
851 
SetBarModifier(const JSCallbackInfo & info,const JsiRef<JsiValue> & jsValue)852 void JSTabs::SetBarModifier(const JSCallbackInfo& info, const JsiRef<JsiValue>& jsValue)
853 {
854     if (!jsValue->IsObject()) {
855         return;
856     }
857     JSRef<JSObject> obj = JSRef<JSObject>::Cast(jsValue);
858     JSRef<JSVal> val = obj->GetProperty("barModifier");
859     if (!val->IsObject()) {
860         return;
861     }
862     JSRef<JSObject> modifierObj = JSRef<JSObject>::Cast(val);
863     auto vm = info.GetVm();
864     auto globalObj = JSNApi::GetGlobalObject(vm);
865     auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applyCommonModifierToNode"));
866     JsiValue jsiValue(globalFunc);
867     JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
868     std::function<void(WeakPtr<NG::FrameNode>)> onApply = nullptr;
869     if (globalFuncRef->IsFunction()) {
870         RefPtr<JsFunction> jsFunc =
871             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
872         onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
873                       modifierParam = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
874             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
875             CHECK_NULL_VOID(func);
876             auto node = frameNode.Upgrade();
877             CHECK_NULL_VOID(node);
878             JSRef<JSVal> params[2];
879             params[0] = modifierParam;
880             params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
881             PipelineContext::SetCallBackNode(node);
882             func->ExecuteJS(2, params);
883         };
884     }
885     TabsModel::GetInstance()->SetBarModifier(std::move(onApply));
886 }
887 
SetBarModifierApply(const JSCallbackInfo & info,std::function<void (WeakPtr<NG::FrameNode>)> & barModiferApply,const JSRef<JSVal> val)888 void JSTabs::SetBarModifierApply(const JSCallbackInfo& info,
889     std::function<void(WeakPtr<NG::FrameNode>)>& barModiferApply, const JSRef<JSVal> val)
890 {
891     auto vm = info.GetVm();
892     auto globalObj = JSNApi::GetGlobalObject(vm);
893     auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applyCommonModifierToNode"));
894     JsiValue jsiValue(globalFunc);
895     JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
896     JSRef<JSObject> modifierObj = JSRef<JSObject>::Cast(val);
897     std::function<void(WeakPtr<NG::FrameNode>)> onApply = nullptr;
898     if (globalFuncRef->IsFunction()) {
899         RefPtr<JsFunction> jsFunc =
900             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
901         onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
902                       modifierParam = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
903             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
904             CHECK_NULL_VOID(func);
905             auto node = frameNode.Upgrade();
906             CHECK_NULL_VOID(node);
907             JSRef<JSVal> params[PARAM_COUNT];
908             params[0] = modifierParam;
909             params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
910             PipelineContext::SetCallBackNode(node);
911             func->ExecuteJS(PARAM_COUNT, params);
912         };
913         barModiferApply = onApply;
914     }
915 }
916 
SetCachedMaxCount(const JSCallbackInfo & info)917 void JSTabs::SetCachedMaxCount(const JSCallbackInfo& info)
918 {
919     if (info.Length() <= 1) {
920         return;
921     }
922 
923     std::optional<int32_t> cachedMaxCount;
924     if (info[0]->IsNumber()) {
925         auto count = info[0]->ToNumber<int32_t>();
926         if (count >= 0) {
927             cachedMaxCount = count;
928         }
929     }
930     auto cacheMode = TabsCacheMode::CACHE_BOTH_SIDE;
931     if (info[1]->IsNumber()) {
932         auto mode = info[1]->ToNumber<int32_t>();
933         if (mode >= static_cast<int32_t>(TabsCacheMode::CACHE_BOTH_SIDE) &&
934             mode <= static_cast<int32_t>(TabsCacheMode::CACHE_LATEST_SWITCHED)) {
935             cacheMode = static_cast<TabsCacheMode>(mode);
936         }
937     }
938     TabsModel::GetInstance()->SetCachedMaxCount(cachedMaxCount, cacheMode);
939 }
940 
JSBind(BindingTarget globalObj)941 void JSTabs::JSBind(BindingTarget globalObj)
942 {
943     JsTabContentTransitionProxy::JSBind(globalObj);
944     JSClass<JSTabs>::Declare("Tabs");
945     JSClass<JSTabs>::StaticMethod("create", &JSTabs::Create);
946     JSClass<JSTabs>::StaticMethod("pop", &JSTabs::Pop);
947     JSClass<JSTabs>::StaticMethod("vertical", &JSTabs::SetVertical);
948     JSClass<JSTabs>::StaticMethod("barPosition", &JSTabs::SetBarPosition);
949     JSClass<JSTabs>::StaticMethod("barBackgroundBlurStyle", &JSTabs::SetBarBackgroundBlurStyle);
950     JSClass<JSTabs>::StaticMethod("scrollable", &JSTabs::SetScrollable);
951     JSClass<JSTabs>::StaticMethod("barMode", &JSTabs::SetBarMode);
952     JSClass<JSTabs>::StaticMethod("barWidth", &JSTabs::SetBarWidth);
953     JSClass<JSTabs>::StaticMethod("barHeight", &JSTabs::SetBarHeight);
954     JSClass<JSTabs>::StaticMethod("width", &JSTabs::SetWidth);
955     JSClass<JSTabs>::StaticMethod("height", &JSTabs::SetHeight);
956     JSClass<JSTabs>::StaticMethod("index", &JSTabs::SetIndex);
957     JSClass<JSTabs>::StaticMethod("animationCurve", &JSTabs::SetAnimationCurve);
958     JSClass<JSTabs>::StaticMethod("animationDuration", &JSTabs::SetAnimationDuration);
959     JSClass<JSTabs>::StaticMethod("divider", &JSTabs::SetDivider);
960     JSClass<JSTabs>::StaticMethod("onChange", &JSTabs::SetOnChange);
961     JSClass<JSTabs>::StaticMethod("onTabBarClick", &JSTabs::SetOnTabBarClick);
962     JSClass<JSTabs>::StaticMethod("onUnselected", &JSTabs::SetOnUnselected);
963     JSClass<JSTabs>::StaticMethod("onAnimationStart", &JSTabs::SetOnAnimationStart);
964     JSClass<JSTabs>::StaticMethod("onAnimationEnd", &JSTabs::SetOnAnimationEnd);
965     JSClass<JSTabs>::StaticMethod("onGestureSwipe", &JSTabs::SetOnGestureSwipe);
966     JSClass<JSTabs>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
967     JSClass<JSTabs>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
968     JSClass<JSTabs>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
969     JSClass<JSTabs>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
970     JSClass<JSTabs>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
971     JSClass<JSTabs>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
972     JSClass<JSTabs>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
973     JSClass<JSTabs>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
974     JSClass<JSTabs>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
975     JSClass<JSTabs>::StaticMethod("remoteMessage", &JSInteractableView::JsCommonRemoteMessage);
976     JSClass<JSTabs>::StaticMethod("fadingEdge", &JSTabs::SetFadingEdge);
977     JSClass<JSTabs>::StaticMethod("barOverlap", &JSTabs::SetBarOverlap);
978     JSClass<JSTabs>::StaticMethod("barBackgroundColor", &JSTabs::SetBarBackgroundColor);
979     JSClass<JSTabs>::StaticMethod("clip", &JSTabs::SetClip);
980     JSClass<JSTabs>::StaticMethod("barGridAlign", &JSTabs::SetBarGridAlign);
981     JSClass<JSTabs>::StaticMethod("customContentTransition", &JSTabs::SetCustomContentTransition);
982     JSClass<JSTabs>::StaticMethod("onContentWillChange", &JSTabs::SetOnContentWillChange);
983     JSClass<JSTabs>::StaticMethod("animationMode", &JSTabs::SetAnimateMode);
984     JSClass<JSTabs>::StaticMethod("edgeEffect", &JSTabs::SetEdgeEffect);
985     JSClass<JSTabs>::StaticMethod("barBackgroundEffect", &JSTabs::SetBarBackgroundEffect);
986     JSClass<JSTabs>::StaticMethod("pageFlipMode", &JSTabs::SetPageFlipMode);
987     JSClass<JSTabs>::StaticMethod("onSelected", &JSTabs::SetOnSelected);
988     JSClass<JSTabs>::StaticMethod("cachedMaxCount", &JSTabs::SetCachedMaxCount);
989 
990     JSClass<JSTabs>::InheritAndBind<JSContainerBase>(globalObj);
991 }
992 
993 } // namespace OHOS::Ace::Framework
994