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