• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "bridge/declarative_frontend/jsview/js_list.h"
17 
18 #include "base/geometry/axis.h"
19 #include "base/log/ace_scoring_log.h"
20 #include "bridge/declarative_frontend/engine/functions/js_drag_function.h"
21 #include "bridge/declarative_frontend/jsview/js_interactable_view.h"
22 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
23 #include "bridge/declarative_frontend/jsview/models/list_model_impl.h"
24 #include "core/components_ng/base/view_stack_model.h"
25 #include "core/components_ng/pattern/list/list_model.h"
26 #include "core/components_ng/pattern/list/list_model_ng.h"
27 #include "core/components_ng/pattern/list/list_position_controller.h"
28 #include "core/components_ng/pattern/scroll_bar/proxy/scroll_bar_proxy.h"
29 
30 namespace OHOS::Ace {
31 
32 std::unique_ptr<ListModel> ListModel::instance_ = nullptr;
33 
GetInstance()34 ListModel* ListModel::GetInstance()
35 {
36     if (!instance_) {
37 #ifdef NG_BUILD
38         instance_.reset(new NG::ListModelNG());
39 #else
40         if (Container::IsCurrentUseNewPipeline()) {
41             instance_.reset(new NG::ListModelNG());
42         } else {
43             instance_.reset(new Framework::ListModelImpl());
44         }
45 #endif
46     }
47     return instance_.get();
48 }
49 
50 } // namespace OHOS::Ace
51 
52 namespace OHOS::Ace::Framework {
53 
SetDirection(int32_t direction)54 void JSList::SetDirection(int32_t direction)
55 {
56     ListModel::GetInstance()->SetListDirection(static_cast<Axis>(direction));
57 }
58 
SetScrollBar(int32_t scrollBar)59 void JSList::SetScrollBar(int32_t scrollBar)
60 {
61     ListModel::GetInstance()->SetScrollBar(static_cast<DisplayMode>(scrollBar));
62 }
63 
SetEdgeEffect(int32_t edgeEffect)64 void JSList::SetEdgeEffect(int32_t edgeEffect)
65 {
66     ListModel::GetInstance()->SetEdgeEffect(static_cast<EdgeEffect>(edgeEffect));
67 }
68 
SetEditMode(bool editMode)69 void JSList::SetEditMode(bool editMode)
70 {
71     ListModel::GetInstance()->SetEditMode(editMode);
72 }
73 
SetCachedCount(const JSCallbackInfo & info)74 void JSList::SetCachedCount(const JSCallbackInfo& info)
75 {
76     int32_t cachedCount = 1;
77     ParseJsInteger<int32_t>(info[0], cachedCount);
78     cachedCount = cachedCount < 0 ? 1 : cachedCount;
79     ListModel::GetInstance()->SetCachedCount(cachedCount);
80 }
81 
SetScroller(RefPtr<JSScroller> scroller)82 void JSList::SetScroller(RefPtr<JSScroller> scroller)
83 {
84     if (scroller) {
85         RefPtr<ScrollControllerBase> listController = ListModel::GetInstance()->CreateScrollController();
86         scroller->SetController(listController);
87 
88         // Init scroll bar proxy.
89         auto proxy = scroller->GetScrollBarProxy();
90         if (!proxy) {
91             if (Container::IsCurrentUseNewPipeline()) {
92                 proxy = AceType::MakeRefPtr<NG::ScrollBarProxy>();
93             } else {
94                 proxy = AceType::MakeRefPtr<ScrollBarProxy>();
95             }
96             scroller->SetScrollBarProxy(proxy);
97         }
98         ListModel::GetInstance()->SetScroller(listController, proxy);
99     }
100 }
101 
Create(const JSCallbackInfo & args)102 void JSList::Create(const JSCallbackInfo& args)
103 {
104     ListModel::GetInstance()->Create();
105     if (args.Length() >= 1 && args[0]->IsObject()) {
106         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
107         JSRef<JSVal> spaceValue = obj->GetProperty("space");
108         if (!spaceValue->IsNull()) {
109             Dimension space;
110             ConvertFromJSValue(spaceValue, space);
111             ListModel::GetInstance()->SetSpace(space);
112         }
113         int32_t initialIndex = 0;
114         if (ConvertFromJSValue(obj->GetProperty("initialIndex"), initialIndex) && initialIndex >= 0) {
115             ListModel::GetInstance()->SetInitialIndex(initialIndex);
116         }
117         JSRef<JSVal> scrollerValue = obj->GetProperty("scroller");
118         if (scrollerValue->IsObject()) {
119             void* scroller = JSRef<JSObject>::Cast(scrollerValue)->Unwrap<JSScroller>();
120             RefPtr<JSScroller> jsScroller = Referenced::Claim(reinterpret_cast<JSScroller*>(scroller));
121             SetScroller(jsScroller);
122         }
123     }
124 
125     args.ReturnSelf();
126 }
127 
SetChainAnimation(bool enableChainAnimation)128 void JSList::SetChainAnimation(bool enableChainAnimation)
129 {
130     ListModel::GetInstance()->SetChainAnimation(enableChainAnimation);
131 }
132 
JsWidth(const JSCallbackInfo & info)133 void JSList::JsWidth(const JSCallbackInfo& info)
134 {
135     JSViewAbstract::JsWidth(info);
136     ListModel::GetInstance()->SetHasWidth(true);
137 }
138 
JsHeight(const JSCallbackInfo & info)139 void JSList::JsHeight(const JSCallbackInfo& info)
140 {
141     JSViewAbstract::JsHeight(info);
142     ListModel::GetInstance()->SetHasHeight(true);
143 }
144 
SetListItemAlign(int32_t itemAlignment)145 void JSList::SetListItemAlign(int32_t itemAlignment)
146 {
147     ListModel::GetInstance()->SetListItemAlign(static_cast<V2::ListItemAlign>(itemAlignment));
148 }
149 
SetLanes(const JSCallbackInfo & info)150 void JSList::SetLanes(const JSCallbackInfo& info)
151 {
152     if (info.Length() < 1) {
153         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
154         return;
155     }
156 
157     int32_t laneNum = 1;
158     if (ParseJsInteger<int32_t>(info[0], laneNum)) {
159         // when [lanes] is set, [laneConstrain_] of list component will be reset to std::nullopt
160         ListModel::GetInstance()->SetLanes(laneNum);
161         return;
162     }
163     if (info[0]->IsObject()) {
164         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
165         auto minLengthParam = jsObj->GetProperty("minLength");
166         auto maxLengthParam = jsObj->GetProperty("maxLength");
167         if (minLengthParam->IsNull() || maxLengthParam->IsNull()) {
168             LOGW("minLength and maxLength are not both set");
169             return;
170         }
171         Dimension minLengthValue;
172         Dimension maxLengthValue;
173         if (!ParseJsDimensionVp(minLengthParam, minLengthValue)
174             || !ParseJsDimensionVp(maxLengthParam, maxLengthValue)) {
175             LOGW("minLength param or maxLength param is invalid");
176             return;
177         }
178         ListModel::GetInstance()->SetLaneConstrain(minLengthValue, maxLengthValue);
179     }
180 }
181 
SetSticky(int32_t sticky)182 void JSList::SetSticky(int32_t sticky)
183 {
184     ListModel::GetInstance()->SetSticky(static_cast<V2::StickyStyle>(sticky));
185 }
186 
SetDivider(const JSCallbackInfo & args)187 void JSList::SetDivider(const JSCallbackInfo& args)
188 {
189     if (args.Length() < 1 || !args[0]->IsObject()) {
190         LOGW("Invalid params");
191         return;
192     }
193 
194     JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
195     V2::ItemDivider divider;
196     if (!ConvertFromJSValue(obj->GetProperty("strokeWidth"), divider.strokeWidth)) {
197         LOGW("Invalid strokeWidth of divider");
198         divider.strokeWidth.Reset();
199     }
200     if (!ConvertFromJSValue(obj->GetProperty("color"), divider.color)) {
201         // Failed to get color from param, using default color defined in theme
202         RefPtr<ListTheme> listTheme = GetTheme<ListTheme>();
203         if (listTheme) {
204             divider.color = listTheme->GetDividerColor();
205         }
206     }
207     ConvertFromJSValue(obj->GetProperty("startMargin"), divider.startMargin);
208     ConvertFromJSValue(obj->GetProperty("endMargin"), divider.endMargin);
209     ListModel::GetInstance()->SetDivider(divider);
210 
211     args.ReturnSelf();
212 }
213 
ScrollCallback(const JSCallbackInfo & args)214 void JSList::ScrollCallback(const JSCallbackInfo& args)
215 {
216     if (args[0]->IsFunction()) {
217         auto onScroll = [execCtx = args.GetExecutionContext(), func = JSRef<JSFunc>::Cast(args[0])](
218                             const Dimension& scrollOffset, const ScrollState& scrollState) {
219             auto params = ConvertToJSValues(scrollOffset, scrollState);
220             func->Call(JSRef<JSObject>(), params.size(), params.data());
221             return;
222         };
223         ListModel::GetInstance()->SetOnScroll(std::move(onScroll));
224     }
225     args.ReturnSelf();
226 }
227 
ReachStartCallback(const JSCallbackInfo & args)228 void JSList::ReachStartCallback(const JSCallbackInfo& args)
229 {
230     if (args[0]->IsFunction()) {
231         auto onReachStart = [execCtx = args.GetExecutionContext(), func = JSRef<JSFunc>::Cast(args[0])]() {
232             func->Call(JSRef<JSObject>());
233             return;
234         };
235         ListModel::GetInstance()->SetOnReachStart(std::move(onReachStart));
236     }
237     args.ReturnSelf();
238 }
239 
ReachEndCallback(const JSCallbackInfo & args)240 void JSList::ReachEndCallback(const JSCallbackInfo& args)
241 {
242     if (args[0]->IsFunction()) {
243         auto onReachEnd = [execCtx = args.GetExecutionContext(), func = JSRef<JSFunc>::Cast(args[0])]() {
244             func->Call(JSRef<JSObject>());
245             return;
246         };
247         ListModel::GetInstance()->SetOnReachEnd(std::move(onReachEnd));
248     }
249     args.ReturnSelf();
250 }
251 
ScrollStartCallback(const JSCallbackInfo & args)252 void JSList::ScrollStartCallback(const JSCallbackInfo& args)
253 {
254     if (args[0]->IsFunction()) {
255         auto onScrollStart = [execCtx = args.GetExecutionContext(), func = JSRef<JSFunc>::Cast(args[0])]() {
256             func->Call(JSRef<JSObject>());
257             return;
258         };
259         ListModel::GetInstance()->SetOnScrollStart(std::move(onScrollStart));
260     }
261     args.ReturnSelf();
262 }
263 
ScrollStopCallback(const JSCallbackInfo & args)264 void JSList::ScrollStopCallback(const JSCallbackInfo& args)
265 {
266     if (args[0]->IsFunction()) {
267         auto onScrollStop = [execCtx = args.GetExecutionContext(), func = JSRef<JSFunc>::Cast(args[0])]() {
268             func->Call(JSRef<JSObject>());
269             return;
270         };
271         ListModel::GetInstance()->SetOnScrollStop(std::move(onScrollStop));
272     }
273     args.ReturnSelf();
274 }
275 
ItemDeleteCallback(const JSCallbackInfo & args)276 void JSList::ItemDeleteCallback(const JSCallbackInfo& args)
277 {
278     if (args[0]->IsFunction()) {
279         auto onItemDelete = [execCtx = args.GetExecutionContext(), func = JSRef<JSFunc>::Cast(args[0])](
280                                 int32_t index) -> bool {
281             auto params = ConvertToJSValues(index);
282             func->Call(JSRef<JSObject>(), params.size(), params.data());
283             return true;
284         };
285         ListModel::GetInstance()->SetOnItemDelete(std::move(onItemDelete));
286     }
287     args.ReturnSelf();
288 }
289 
ItemMoveCallback(const JSCallbackInfo & args)290 void JSList::ItemMoveCallback(const JSCallbackInfo& args)
291 {
292     if (args[0]->IsFunction()) {
293         auto onItemMove = [execCtx = args.GetExecutionContext(), func = JSRef<JSFunc>::Cast(args[0])](
294                               int32_t start, int32_t end) -> bool {
295             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false);
296             auto params = ConvertToJSValues(start, end);
297             func->Call(JSRef<JSObject>(), params.size(), params.data());
298             return true;
299         };
300         ListModel::GetInstance()->SetOnItemMove(std::move(onItemMove));
301     }
302     args.ReturnSelf();
303 }
304 
ScrollIndexCallback(const JSCallbackInfo & args)305 void JSList::ScrollIndexCallback(const JSCallbackInfo& args)
306 {
307     if (args[0]->IsFunction()) {
308         auto onScrollIndex = [execCtx = args.GetExecutionContext(), func = JSRef<JSFunc>::Cast(args[0])](
309                                  const int32_t start, const int32_t end) {
310             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
311             auto params = ConvertToJSValues(start, end);
312             func->Call(JSRef<JSObject>(), params.size(), params.data());
313             return;
314         };
315         ListModel::GetInstance()->SetOnScrollIndex(std::move(onScrollIndex));
316     }
317     args.ReturnSelf();
318 }
319 
ItemDragStartCallback(const JSCallbackInfo & info)320 void JSList::ItemDragStartCallback(const JSCallbackInfo& info)
321 {
322     if (!info[0]->IsFunction()) {
323         LOGE("fail to bind onItemDragStart event due to info is not function");
324         return;
325     }
326 
327     RefPtr<JsDragFunction> jsOnDragFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
328     auto onItemDragStart = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragFunc)](
329                                const ItemDragInfo& dragInfo, int32_t itemIndex) -> RefPtr<AceType> {
330         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, nullptr);
331         auto ret = func->ItemDragStartExecute(dragInfo, itemIndex);
332         if (!ret->IsObject()) {
333             LOGE("builder param is not an object.");
334             return nullptr;
335         }
336 
337         auto builderObj = JSRef<JSObject>::Cast(ret);
338         auto builder = builderObj->GetProperty("builder");
339         if (!builder->IsFunction()) {
340             LOGE("builder param is not a function.");
341             return nullptr;
342         }
343         auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
344         if (!builderFunc) {
345             LOGE("builder function is null.");
346             return nullptr;
347         }
348         // use another VSP instance while executing the builder function
349         ViewStackModel::GetInstance()->NewScope();
350         {
351             ACE_SCORING_EVENT("List.onItemDragStart.builder");
352             builderFunc->Execute();
353         }
354         return ViewStackModel::GetInstance()->Finish();
355     };
356     ListModel::GetInstance()->SetOnItemDragStart(std::move(onItemDragStart));
357 }
358 
ItemDragEnterCallback(const JSCallbackInfo & info)359 void JSList::ItemDragEnterCallback(const JSCallbackInfo& info)
360 {
361     if (!info[0]->IsFunction()) {
362         LOGE("fail to bind onItemDragEnter event due to info is not function");
363         return;
364     }
365 
366     RefPtr<JsDragFunction> jsOnDragEnterFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
367     auto onItemDragEnter = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEnterFunc)](
368                                const ItemDragInfo& dragInfo) {
369         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
370         ACE_SCORING_EVENT("List.onItemDragEnter");
371         func->ItemDragEnterExecute(dragInfo);
372     };
373     ListModel::GetInstance()->SetOnItemDragEnter(std::move(onItemDragEnter));
374 }
375 
ItemDragMoveCallback(const JSCallbackInfo & info)376 void JSList::ItemDragMoveCallback(const JSCallbackInfo& info)
377 {
378     if (!info[0]->IsFunction()) {
379         LOGE("fail to bind onItemDragMove event due to info is not function");
380         return;
381     }
382 
383     RefPtr<JsDragFunction> jsOnDragMoveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
384     auto onItemDragMove = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragMoveFunc)](
385                               const ItemDragInfo& dragInfo, int32_t itemIndex, int32_t insertIndex) {
386         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
387         ACE_SCORING_EVENT("List.onItemDragMove");
388         func->ItemDragMoveExecute(dragInfo, itemIndex, insertIndex);
389     };
390     ListModel::GetInstance()->SetOnItemDragMove(std::move(onItemDragMove));
391 }
392 
ItemDragLeaveCallback(const JSCallbackInfo & info)393 void JSList::ItemDragLeaveCallback(const JSCallbackInfo& info)
394 {
395     if (!info[0]->IsFunction()) {
396         LOGE("fail to bind onItemDragLeave event due to info is not function");
397         return;
398     }
399 
400     RefPtr<JsDragFunction> jsOnDragLeaveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
401     auto onItemDragLeave = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragLeaveFunc)](
402                                const ItemDragInfo& dragInfo, int32_t itemIndex) {
403         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
404         ACE_SCORING_EVENT("List.onItemDragLeave");
405         func->ItemDragLeaveExecute(dragInfo, itemIndex);
406     };
407     ListModel::GetInstance()->SetOnItemDragLeave(std::move(onItemDragLeave));
408 }
409 
ItemDropCallback(const JSCallbackInfo & info)410 void JSList::ItemDropCallback(const JSCallbackInfo& info)
411 {
412     if (!info[0]->IsFunction()) {
413         LOGE("fail to bind onItemDrop event due to info is not function");
414         return;
415     }
416 
417     RefPtr<JsDragFunction> jsOnDropFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
418     auto onItemDrop = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDropFunc)](
419                           const ItemDragInfo& dragInfo, int32_t itemIndex, int32_t insertIndex, bool isSuccess) {
420         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
421         ACE_SCORING_EVENT("List.onItemDrop");
422         func->ItemDropExecute(dragInfo, itemIndex, insertIndex, isSuccess);
423     };
424     ListModel::GetInstance()->SetOnItemDrop(onItemDrop);
425 }
426 
SetMultiSelectable(bool multiSelectable)427 void JSList::SetMultiSelectable(bool multiSelectable)
428 {
429     ListModel::GetInstance()->SetMultiSelectable(multiSelectable);
430 }
431 
ScrollBeginCallback(const JSCallbackInfo & args)432 void JSList::ScrollBeginCallback(const JSCallbackInfo& args)
433 {
434     if (args[0]->IsFunction()) {
435         auto onScrollBegin = [execCtx = args.GetExecutionContext(), func = JSRef<JSFunc>::Cast(args[0])](
436                                  const Dimension& dx, const Dimension& dy) -> ScrollInfo {
437             ScrollInfo scrollInfo { .dx = dx, .dy = dy };
438             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, scrollInfo);
439             auto params = ConvertToJSValues(dx, dy);
440             auto result = func->Call(JSRef<JSObject>(), params.size(), params.data());
441             if (result.IsEmpty()) {
442                 LOGE("Error calling onScrollBegin, result is empty.");
443                 return scrollInfo;
444             }
445 
446             if (!result->IsObject()) {
447                 LOGE("Error calling onScrollBegin, result is not object.");
448                 return scrollInfo;
449             }
450 
451             auto resObj = JSRef<JSObject>::Cast(result);
452             auto dxRemainValue = resObj->GetProperty("dxRemain");
453             if (dxRemainValue->IsNumber()) {
454                 scrollInfo.dx = Dimension(dxRemainValue->ToNumber<float>(), DimensionUnit::VP);
455             }
456             auto dyRemainValue = resObj->GetProperty("dyRemain");
457             if (dyRemainValue->IsNumber()) {
458                 scrollInfo.dy = Dimension(dyRemainValue->ToNumber<float>(), DimensionUnit::VP);
459             }
460             return scrollInfo;
461         };
462         ListModel::GetInstance()->SetOnScrollBegin(std::move(onScrollBegin));
463     }
464 }
465 
ScrollFrameBeginCallback(const JSCallbackInfo & args)466 void JSList::ScrollFrameBeginCallback(const JSCallbackInfo& args)
467 {
468     if (args[0]->IsFunction()) {
469         auto onScrollBegin = [execCtx = args.GetExecutionContext(), func = JSRef<JSFunc>::Cast(args[0])](
470                                  const Dimension& offset, const ScrollState& state) -> ScrollFrameResult {
471             ScrollFrameResult scrollRes { .offset = offset };
472             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, scrollRes);
473             auto params = ConvertToJSValues(offset, state);
474             auto result = func->Call(JSRef<JSObject>(), params.size(), params.data());
475             if (result.IsEmpty()) {
476                 LOGE("Error calling onScrollFrameBegin, result is empty.");
477                 return scrollRes;
478             }
479 
480             if (!result->IsObject()) {
481                 LOGE("Error calling onScrollFrameBegin, result is not object.");
482                 return scrollRes;
483             }
484 
485             auto resObj = JSRef<JSObject>::Cast(result);
486             auto dxRemainValue = resObj->GetProperty("offsetRemain");
487             if (dxRemainValue->IsNumber()) {
488                 scrollRes.offset = Dimension(dxRemainValue->ToNumber<float>(), DimensionUnit::VP);
489             }
490             return scrollRes;
491         };
492         ListModel::GetInstance()->SetOnScrollFrameBegin(std::move(onScrollBegin));
493     }
494 }
495 
JSBind(BindingTarget globalObj)496 void JSList::JSBind(BindingTarget globalObj)
497 {
498     JSClass<JSList>::Declare("List");
499     JSClass<JSList>::StaticMethod("create", &JSList::Create);
500 
501     JSClass<JSList>::StaticMethod("width", &JSList::JsWidth);
502     JSClass<JSList>::StaticMethod("height", &JSList::JsHeight);
503     JSClass<JSList>::StaticMethod("listDirection", &JSList::SetDirection);
504     JSClass<JSList>::StaticMethod("scrollBar", &JSList::SetScrollBar);
505     JSClass<JSList>::StaticMethod("edgeEffect", &JSList::SetEdgeEffect);
506     JSClass<JSList>::StaticMethod("divider", &JSList::SetDivider);
507     JSClass<JSList>::StaticMethod("editMode", &JSList::SetEditMode);
508     JSClass<JSList>::StaticMethod("cachedCount", &JSList::SetCachedCount);
509     JSClass<JSList>::StaticMethod("chainAnimation", &JSList::SetChainAnimation);
510     JSClass<JSList>::StaticMethod("multiSelectable", &JSList::SetMultiSelectable);
511     JSClass<JSList>::StaticMethod("alignListItem", &JSList::SetListItemAlign);
512     JSClass<JSList>::StaticMethod("lanes", &JSList::SetLanes);
513     JSClass<JSList>::StaticMethod("sticky", &JSList::SetSticky);
514 
515     JSClass<JSList>::StaticMethod("onScroll", &JSList::ScrollCallback);
516     JSClass<JSList>::StaticMethod("onReachStart", &JSList::ReachStartCallback);
517     JSClass<JSList>::StaticMethod("onReachEnd", &JSList::ReachEndCallback);
518     JSClass<JSList>::StaticMethod("onScrollStart", &JSList::ScrollStartCallback);
519     JSClass<JSList>::StaticMethod("onScrollStop", &JSList::ScrollStopCallback);
520     JSClass<JSList>::StaticMethod("onItemDelete", &JSList::ItemDeleteCallback);
521     JSClass<JSList>::StaticMethod("onItemMove", &JSList::ItemMoveCallback);
522     JSClass<JSList>::StaticMethod("onScrollIndex", &JSList::ScrollIndexCallback);
523     JSClass<JSList>::StaticMethod("onScrollBegin", &JSList::ScrollBeginCallback);
524     JSClass<JSList>::StaticMethod("onScrollFrameBegin", &JSList::ScrollFrameBeginCallback);
525 
526     JSClass<JSList>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
527     JSClass<JSList>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
528     JSClass<JSList>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
529     JSClass<JSList>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
530     JSClass<JSList>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
531     JSClass<JSList>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
532     JSClass<JSList>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
533 
534     JSClass<JSList>::StaticMethod("onItemDragStart", &JSList::ItemDragStartCallback);
535     JSClass<JSList>::StaticMethod("onItemDragEnter", &JSList::ItemDragEnterCallback);
536     JSClass<JSList>::StaticMethod("onItemDragMove", &JSList::ItemDragMoveCallback);
537     JSClass<JSList>::StaticMethod("onItemDragLeave", &JSList::ItemDragLeaveCallback);
538     JSClass<JSList>::StaticMethod("onItemDrop", &JSList::ItemDropCallback);
539     JSClass<JSList>::StaticMethod("remoteMessage", &JSInteractableView::JsCommonRemoteMessage);
540 
541     JSClass<JSList>::Inherit<JSContainerBase>();
542     JSClass<JSList>::Inherit<JSViewAbstract>();
543     JSClass<JSList>::Bind(globalObj);
544 }
545 
546 } // namespace OHOS::Ace::Framework
547