1 /*
2 * Copyright (c) 2021 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_swiper.h"
17
18 #include <algorithm>
19 #include <iterator>
20
21 #include "bridge/common/utils/utils.h"
22 #include "core/components/common/layout/constants.h"
23 #include "core/components/swiper/swiper_component.h"
24 #include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
25
26 namespace OHOS::Ace::Framework {
27 namespace {
28
29 constexpr int32_t DEFAULT_SWIPER_CACHED_COUNT = 1;
30
SwiperChangeEventToJSValue(const SwiperChangeEvent & eventInfo)31 JSRef<JSVal> SwiperChangeEventToJSValue(const SwiperChangeEvent& eventInfo)
32 {
33 return JSRef<JSVal>::Make(ToJSValue(eventInfo.GetIndex()));
34 }
35
36 } // namespace
37
Create(const JSCallbackInfo & info)38 void JSSwiper::Create(const JSCallbackInfo& info)
39 {
40 std::list<RefPtr<OHOS::Ace::Component>> componentChildren;
41 RefPtr<OHOS::Ace::SwiperComponent> component = AceType::MakeRefPtr<OHOS::Ace::SwiperComponent>(componentChildren);
42 if (info.Length() > 0 && info[0]->IsObject()) {
43 JSSwiperController* jsController = JSRef<JSObject>::Cast(info[0])->Unwrap<JSSwiperController>();
44 if (jsController) {
45 jsController->SetController(component->GetSwiperController());
46 }
47 }
48 component->SetIndicator(InitIndicatorStyle());
49 component->SetMainSwiperSize(MainSwiperSize::MIN);
50 component->SetCachedSize(DEFAULT_SWIPER_CACHED_COUNT);
51 component->SetCurve(Curves::LINEAR);
52 ViewStackProcessor::GetInstance()->Push(component);
53 JSInteractableView::SetFocusNode(true);
54 }
55
JsRemoteMessage(const JSCallbackInfo & info)56 void JSSwiper::JsRemoteMessage(const JSCallbackInfo& info)
57 {
58 EventMarker remoteMessageEventId;
59 JSInteractableView::JsRemoteMessage(info, remoteMessageEventId);
60 auto stack = ViewStackProcessor::GetInstance();
61 auto swiperComponent = AceType::DynamicCast<SwiperComponent>(stack->GetMainComponent());
62 swiperComponent->SetRemoteMessageEventId(remoteMessageEventId);
63 }
64
JSBind(BindingTarget globalObj)65 void JSSwiper::JSBind(BindingTarget globalObj)
66 {
67 JSClass<JSSwiper>::Declare("Swiper");
68 MethodOptions opt = MethodOptions::NONE;
69 JSClass<JSSwiper>::StaticMethod("create", &JSSwiper::Create, opt);
70 JSClass<JSSwiper>::StaticMethod("autoPlay", &JSSwiper::SetAutoplay, opt);
71 JSClass<JSSwiper>::StaticMethod("digital", &JSSwiper::SetDigital, opt);
72 JSClass<JSSwiper>::StaticMethod("duration", &JSSwiper::SetDuration, opt);
73 JSClass<JSSwiper>::StaticMethod("index", &JSSwiper::SetIndex, opt);
74 JSClass<JSSwiper>::StaticMethod("interval", &JSSwiper::SetInterval, opt);
75 JSClass<JSSwiper>::StaticMethod("loop", &JSSwiper::SetLoop, opt);
76 JSClass<JSSwiper>::StaticMethod("vertical", &JSSwiper::SetVertical, opt);
77 JSClass<JSSwiper>::StaticMethod("indicator", &JSSwiper::SetIndicator, opt);
78 JSClass<JSSwiper>::StaticMethod("cancelSwipeOnOtherAxis", &JSSwiper::SetCancelSwipeOnOtherAxis, opt);
79 JSClass<JSSwiper>::StaticMethod("displayMode", &JSSwiper::SetDisplayMode);
80 JSClass<JSSwiper>::StaticMethod("effectMode", &JSSwiper::SetEffectMode);
81 JSClass<JSSwiper>::StaticMethod("displayCount", &JSSwiper::SetDisplayCount);
82 JSClass<JSSwiper>::StaticMethod("itemSpace", &JSSwiper::SetItemSpace);
83 JSClass<JSSwiper>::StaticMethod("cachedCount", &JSSwiper::SetCachedCount);
84 JSClass<JSSwiper>::StaticMethod("curve", &JSSwiper::SetCurve);
85 JSClass<JSSwiper>::StaticMethod("onChange", &JSSwiper::SetOnChange);
86 JSClass<JSSwiper>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
87 JSClass<JSSwiper>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
88 JSClass<JSSwiper>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
89 JSClass<JSSwiper>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
90 JSClass<JSSwiper>::StaticMethod("remoteMessage", &JSSwiper::JsRemoteMessage);
91 JSClass<JSSwiper>::StaticMethod("onClick", &JSSwiper::SetOnClick);
92 JSClass<JSSwiper>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
93 JSClass<JSSwiper>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
94 JSClass<JSSwiper>::StaticMethod("indicatorStyle", &JSSwiper::SetIndicatorStyle);
95 JSClass<JSSwiper>::StaticMethod("enabled", &JSSwiper::SetEnabled);
96 JSClass<JSSwiper>::StaticMethod("disableSwipe", &JSSwiper::SetDisableSwipe);
97 JSClass<JSSwiper>::StaticMethod("height", &JSSwiper::SetHeight);
98 JSClass<JSSwiper>::StaticMethod("width", &JSSwiper::SetWidth);
99 JSClass<JSSwiper>::StaticMethod("size", &JSSwiper::SetSize);
100 JSClass<JSSwiper>::Inherit<JSContainerBase>();
101 JSClass<JSSwiper>::Inherit<JSViewAbstract>();
102 JSClass<JSSwiper>::Bind<>(globalObj);
103 }
104
SetAutoplay(bool autoPlay)105 void JSSwiper::SetAutoplay(bool autoPlay)
106 {
107 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
108 auto swiper = AceType::DynamicCast<OHOS::Ace::SwiperComponent>(component);
109 if (swiper) {
110 swiper->SetAutoPlay(autoPlay);
111 }
112 }
113
SetEnabled(const JSCallbackInfo & info)114 void JSSwiper::SetEnabled(const JSCallbackInfo& info)
115 {
116 JSViewAbstract::JsEnabled(info);
117 if (info.Length() < 1) {
118 LOGE("The info is wrong, it is supposed to have at least 1 arguments");
119 return;
120 }
121
122 if (!info[0]->IsBoolean()) {
123 LOGE("info is not bool.");
124 return;
125 }
126 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
127 auto swiper = AceType::DynamicCast<OHOS::Ace::SwiperComponent>(component);
128 if (swiper) {
129 swiper->SetDisabledStatus(!(info[0]->ToBoolean()));
130 }
131 }
132
SetDisableSwipe(bool disable)133 void JSSwiper::SetDisableSwipe(bool disable)
134 {
135 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
136 auto swiper = AceType::DynamicCast<OHOS::Ace::SwiperComponent>(component);
137 if (swiper) {
138 swiper->DisableSwipe(disable);
139 }
140 }
141
SetEffectMode(const JSCallbackInfo & info)142 void JSSwiper::SetEffectMode(const JSCallbackInfo& info)
143 {
144 if (info.Length() < 1) {
145 LOGE("The info is wrong, it is supposed to have atleast 1 arguments");
146 return;
147 }
148 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
149 auto swiper = AceType::DynamicCast<OHOS::Ace::SwiperComponent>(component);
150 if (!swiper) {
151 return;
152 }
153
154 if (!info[0]->IsNumber()) {
155 LOGE("info is not a number ");
156 return;
157 }
158 auto swiperMode = static_cast<EdgeEffect>(info[0]->ToNumber<int32_t>());
159 if (swiperMode == EdgeEffect::SPRING) {
160 swiper->SetEdgeEffect(EdgeEffect::SPRING);
161 } else if (swiperMode == EdgeEffect::FADE) {
162 swiper->SetEdgeEffect(EdgeEffect::FADE);
163 } else {
164 swiper->SetEdgeEffect(EdgeEffect::NONE);
165 }
166 }
167
SetDisplayCount(const JSCallbackInfo & info)168 void JSSwiper::SetDisplayCount(const JSCallbackInfo& info)
169 {
170 if (info.Length() < 1) {
171 LOGE("The info is wrong, it is supposed to have atleast 1 arguments");
172 return;
173 }
174 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
175 auto swiper = AceType::DynamicCast<OHOS::Ace::SwiperComponent>(component);
176 if (!swiper) {
177 return;
178 }
179
180 if (info[0]->ToString() == "auto") {
181 swiper->SetDisplayMode(SwiperDisplayMode::AUTO_LINEAR);
182 }
183
184 if (info[0]->IsNumber()) {
185 swiper->SetDisplayCount(info[0]->ToNumber<int32_t>());
186 }
187 }
188
SetDigital(bool digitalIndicator)189 void JSSwiper::SetDigital(bool digitalIndicator)
190 {
191 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
192 auto swiper = AceType::DynamicCast<OHOS::Ace::SwiperComponent>(component);
193 if (swiper) {
194 swiper->SetDigitalIndicator(digitalIndicator);
195 }
196 }
197
SetDuration(double duration)198 void JSSwiper::SetDuration(double duration)
199 {
200 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
201 auto swiper = AceType::DynamicCast<OHOS::Ace::SwiperComponent>(component);
202 if (swiper) {
203 swiper->SetDuration(duration);
204 }
205 }
206
SetIndex(uint32_t index)207 void JSSwiper::SetIndex(uint32_t index)
208 {
209 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
210 auto swiper = AceType::DynamicCast<OHOS::Ace::SwiperComponent>(component);
211 if (swiper) {
212 swiper->SetIndex(index);
213 }
214 }
215
SetInterval(double interval)216 void JSSwiper::SetInterval(double interval)
217 {
218 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
219 auto swiper = AceType::DynamicCast<OHOS::Ace::SwiperComponent>(component);
220 if (swiper) {
221 swiper->SetAutoPlayInterval(interval);
222 }
223 }
224
SetLoop(bool loop)225 void JSSwiper::SetLoop(bool loop)
226 {
227 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
228 auto swiper = AceType::DynamicCast<OHOS::Ace::SwiperComponent>(component);
229 if (swiper) {
230 swiper->SetLoop(loop);
231 }
232 }
233
SetVertical(bool isVertical)234 void JSSwiper::SetVertical(bool isVertical)
235 {
236 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
237 auto swiper = AceType::DynamicCast<OHOS::Ace::SwiperComponent>(component);
238 if (swiper) {
239 swiper->SetAxis(isVertical ? Axis::VERTICAL : Axis::HORIZONTAL);
240 }
241 }
242
SetIndicator(bool showIndicator)243 void JSSwiper::SetIndicator(bool showIndicator)
244 {
245 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
246 auto swiper = AceType::DynamicCast<OHOS::Ace::SwiperComponent>(component);
247 if (swiper) {
248 swiper->SetShowIndicator(showIndicator);
249 if (!showIndicator) {
250 swiper->SetIndicator(nullptr);
251 }
252 }
253 }
254
SetCancelSwipeOnOtherAxis(bool cancel)255 void JSSwiper::SetCancelSwipeOnOtherAxis(bool cancel)
256 {
257 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
258 auto swiper = AceType::DynamicCast<OHOS::Ace::SwiperComponent>(component);
259 // TODO: swiper->SetCancelSwipeOnOtherAxis(cancel) is no longer supported. check whether need this method
260 }
261
SetIndicatorStyle(const JSCallbackInfo & info)262 void JSSwiper::SetIndicatorStyle(const JSCallbackInfo& info)
263 {
264 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
265 auto swiper = AceType::DynamicCast<OHOS::Ace::SwiperComponent>(component);
266 if (swiper) {
267 auto indictor = swiper->GetIndicator();
268 if (!indictor) {
269 return;
270 }
271
272 if (info[0]->IsObject()) {
273 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
274 JSRef<JSVal> leftValue = obj->GetProperty("left");
275 JSRef<JSVal> topValue = obj->GetProperty("top");
276 JSRef<JSVal> rightValue = obj->GetProperty("right");
277 JSRef<JSVal> bottomValue = obj->GetProperty("bottom");
278 JSRef<JSVal> sizeValue = obj->GetProperty("size");
279 JSRef<JSVal> maskValue = obj->GetProperty("mask");
280 JSRef<JSVal> colorValue = obj->GetProperty("color");
281 JSRef<JSVal> selectedColorValue = obj->GetProperty("selectedColor");
282
283 Dimension dimLeft;
284 if (ParseJsDimensionPx(leftValue, dimLeft)) {
285 indictor->SetLeft(dimLeft);
286 }
287 Dimension dimTop;
288 if (ParseJsDimensionPx(topValue, dimTop)) {
289 indictor->SetTop(dimTop);
290 }
291 Dimension dimRight;
292 if (ParseJsDimensionPx(rightValue, dimRight)) {
293 indictor->SetRight(dimRight);
294 }
295 Dimension dimBottom;
296 if (ParseJsDimensionPx(bottomValue, dimBottom)) {
297 indictor->SetBottom(dimBottom);
298 }
299 Dimension dimSize;
300 if (ParseJsDimensionPx(sizeValue, dimSize)) {
301 indictor->SetSize(dimSize);
302 }
303 if (maskValue->IsBoolean()) {
304 auto mask = maskValue->ToBoolean();
305 indictor->SetIndicatorMask(mask);
306 }
307 Color colorVal;
308 if (ParseJsColor(colorValue, colorVal)) {
309 indictor->SetColor(colorVal);
310 }
311 Color selectedColorVal;
312 if (ParseJsColor(selectedColorValue, selectedColorVal)) {
313 indictor->SetSelectedColor(selectedColorVal);
314 }
315 }
316 }
317 info.ReturnSelf();
318 }
319
SetItemSpace(const JSCallbackInfo & info)320 void JSSwiper::SetItemSpace(const JSCallbackInfo& info)
321 {
322 if (info.Length() < 1) {
323 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
324 return;
325 }
326
327 Dimension value;
328 if (!ParseJsDimensionVp(info[0], value)) {
329 return;
330 }
331
332 if (LessNotEqual(value.Value(), 0.0)) {
333 value.SetValue(0.0);
334 }
335 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
336 auto swiper = AceType::DynamicCast<OHOS::Ace::SwiperComponent>(component);
337 if (swiper) {
338 swiper->SetItemSpace(value);
339 }
340 }
341
SetDisplayMode(int32_t index)342 void JSSwiper::SetDisplayMode(int32_t index)
343 {
344 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
345 auto swiper = AceType::DynamicCast<OHOS::Ace::SwiperComponent>(component);
346 if (swiper) {
347 swiper->SetDisplayMode(static_cast<SwiperDisplayMode>(index));
348 }
349 }
350
SetCachedCount(int32_t cachedCount)351 void JSSwiper::SetCachedCount(int32_t cachedCount)
352 {
353 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
354 auto swiper = AceType::DynamicCast<OHOS::Ace::SwiperComponent>(component);
355 if (swiper) {
356 swiper->SetCachedSize(cachedCount);
357 }
358 }
359
SetCurve(const std::string & curveStr)360 void JSSwiper::SetCurve(const std::string& curveStr)
361 {
362 RefPtr<Curve> curve = CreateCurve(curveStr);
363
364 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
365 auto swiper = AceType::DynamicCast<OHOS::Ace::SwiperComponent>(component);
366 swiper->SetCurve(curve);
367 }
368
SetOnChange(const JSCallbackInfo & args)369 void JSSwiper::SetOnChange(const JSCallbackInfo& args)
370 {
371 if (args[0]->IsFunction()) {
372 auto changeHandler = AceType::MakeRefPtr<JsEventFunction<SwiperChangeEvent, 1>>(
373 JSRef<JSFunc>::Cast(args[0]), SwiperChangeEventToJSValue);
374 auto onChange = EventMarker([executionContext = args.GetExecutionContext(), func = std::move(changeHandler)](
375 const BaseEventInfo* info) {
376 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
377 auto swiperInfo = TypeInfoHelper::DynamicCast<SwiperChangeEvent>(info);
378 if (!swiperInfo) {
379 LOGE("HandleChangeEvent swiperInfo == nullptr");
380 return;
381 }
382 ACE_SCORING_EVENT("Swiper.OnChange");
383 func->Execute(*swiperInfo);
384 });
385 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
386 auto swiper = AceType::DynamicCast<OHOS::Ace::SwiperComponent>(component);
387 if (swiper) {
388 swiper->SetChangeEventId(onChange);
389 }
390 }
391 args.ReturnSelf();
392 }
393
SetOnClick(const JSCallbackInfo & args)394 void JSSwiper::SetOnClick(const JSCallbackInfo& args)
395 {
396 if (args[0]->IsFunction()) {
397 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
398 auto swiper = AceType::DynamicCast<OHOS::Ace::SwiperComponent>(component);
399 if (swiper) {
400 swiper->SetClickEventId(JSInteractableView::GetClickEventMarker(args));
401 }
402 }
403 args.SetReturnValue(args.This());
404 }
405
InitIndicatorStyle()406 RefPtr<OHOS::Ace::SwiperIndicator> JSSwiper::InitIndicatorStyle()
407 {
408 auto indicator = AceType::MakeRefPtr<OHOS::Ace::SwiperIndicator>();
409 auto indicatorTheme = GetTheme<SwiperIndicatorTheme>();
410 if (indicatorTheme) {
411 indicator->InitStyle(indicatorTheme);
412 }
413 return indicator;
414 }
415
SetWidth(const JSCallbackInfo & info)416 void JSSwiper::SetWidth(const JSCallbackInfo& info)
417 {
418 if (info.Length() < 1) {
419 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
420 return;
421 }
422
423 SetWidth(info[0]);
424 }
425
SetWidth(const JSRef<JSVal> & jsValue)426 void JSSwiper::SetWidth(const JSRef<JSVal>& jsValue)
427 {
428 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
429 auto swiper = AceType::DynamicCast<OHOS::Ace::SwiperComponent>(component);
430 if (swiper) {
431 JSViewAbstract::JsWidth(jsValue);
432 if (swiper->GetMainSwiperSize() == MainSwiperSize::MAX ||
433 swiper->GetMainSwiperSize() == MainSwiperSize::MAX_Y) {
434 swiper->SetMainSwiperSize(MainSwiperSize::MAX);
435 } else {
436 swiper->SetMainSwiperSize(MainSwiperSize::MAX_X);
437 }
438 }
439 }
440
SetHeight(const JSCallbackInfo & info)441 void JSSwiper::SetHeight(const JSCallbackInfo& info)
442 {
443 if (info.Length() < 1) {
444 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
445 return;
446 }
447
448 SetHeight(info[0]);
449 }
450
SetHeight(const JSRef<JSVal> & jsValue)451 void JSSwiper::SetHeight(const JSRef<JSVal>& jsValue)
452 {
453 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
454 auto swiper = AceType::DynamicCast<OHOS::Ace::SwiperComponent>(component);
455 if (swiper) {
456 JSViewAbstract::JsHeight(jsValue);
457 if (swiper->GetMainSwiperSize() == MainSwiperSize::MAX ||
458 swiper->GetMainSwiperSize() == MainSwiperSize::MAX_X) {
459 swiper->SetMainSwiperSize(MainSwiperSize::MAX);
460 } else {
461 swiper->SetMainSwiperSize(MainSwiperSize::MAX_Y);
462 }
463 }
464 }
465
SetSize(const JSCallbackInfo & info)466 void JSSwiper::SetSize(const JSCallbackInfo& info)
467 {
468 if (info.Length() < 1) {
469 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
470 return;
471 }
472
473 if (!info[0]->IsObject()) {
474 LOGE("arg is not Object or String.");
475 return;
476 }
477
478 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
479 SetWidth(sizeObj->GetProperty("width"));
480 SetHeight(sizeObj->GetProperty("height"));
481 }
482
JSBind(BindingTarget globalObj)483 void JSSwiperController::JSBind(BindingTarget globalObj)
484 {
485 JSClass<JSSwiperController>::Declare("SwiperController");
486 JSClass<JSSwiperController>::CustomMethod("showNext", &JSSwiperController::ShowNext);
487 JSClass<JSSwiperController>::CustomMethod("finishAnimation", &JSSwiperController::FinishAnimation);
488 JSClass<JSSwiperController>::CustomMethod("showPrevious", &JSSwiperController::ShowPrevious);
489 JSClass<JSSwiperController>::Bind(globalObj, JSSwiperController::Constructor, JSSwiperController::Destructor);
490 }
491
Constructor(const JSCallbackInfo & args)492 void JSSwiperController::Constructor(const JSCallbackInfo& args)
493 {
494 auto scroller = Referenced::MakeRefPtr<JSSwiperController>();
495 scroller->IncRefCount();
496 args.SetReturnValue(Referenced::RawPtr(scroller));
497 }
498
Destructor(JSSwiperController * scroller)499 void JSSwiperController::Destructor(JSSwiperController* scroller)
500 {
501 if (scroller != nullptr) {
502 scroller->DecRefCount();
503 }
504 }
505
FinishAnimation(const JSCallbackInfo & args)506 void JSSwiperController::FinishAnimation(const JSCallbackInfo& args)
507 {
508 if (args[0]->IsFunction()) {
509 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(args[0]));
510 auto eventMarker = EventMarker([execCtx = args.GetExecutionContext(), func = std::move(jsFunc)]() {
511 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
512 ACE_SCORING_EVENT("Swiper.finishAnimation");
513 func->Execute();
514 });
515 if (controller_) {
516 controller_->SetFinishCallback(eventMarker);
517 }
518 }
519 if (controller_) {
520 controller_->FinishAnimation();
521 }
522 args.ReturnSelf();
523 }
524
525 } // namespace OHOS::Ace::Framework
526