• 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_swiper.h"
17 
18 #include <algorithm>
19 #include <cstdint>
20 #include <iterator>
21 
22 #include "base/log/ace_scoring_log.h"
23 #include "base/utils/utils.h"
24 #include "bridge/common/utils/utils.h"
25 #include "bridge/declarative_frontend/ark_theme/theme_apply/js_swiper_theme.h"
26 #include "bridge/declarative_frontend/ark_theme/theme_apply/js_theme_utils.h"
27 #include "bridge/declarative_frontend/engine/functions/js_click_function.h"
28 #include "bridge/declarative_frontend/engine/functions/js_swiper_function.h"
29 #include "bridge/declarative_frontend/engine/jsi/js_ui_index.h"
30 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
31 #include "bridge/declarative_frontend/jsview/models/swiper_model_impl.h"
32 #include "bridge/declarative_frontend/view_stack_processor.h"
33 #include "bridge/js_frontend/engine/jsi/js_value.h"
34 #include "core/animation/curve.h"
35 #include "core/components/common/layout/constants.h"
36 #include "core/components/common/properties/scroll_bar.h"
37 #include "core/components/swiper/swiper_component.h"
38 #include "core/components/swiper/swiper_indicator_theme.h"
39 #include "core/components_ng/base/view_stack_processor.h"
40 #include "core/components_ng/pattern/scrollable/scrollable_properties.h"
41 #include "core/components_ng/pattern/swiper/swiper_content_transition_proxy.h"
42 #include "core/components_ng/pattern/swiper/swiper_model.h"
43 #include "core/components_ng/pattern/swiper/swiper_model_ng.h"
44 
45 namespace OHOS::Ace {
46 namespace {
47 constexpr float ARROW_SIZE_COEFFICIENT = 0.75f;
48 constexpr int32_t DEFAULT_CUSTOM_ANIMATION_TIMEOUT = 0;
49 const auto DEFAULT_CURVE = AceType::MakeRefPtr<InterpolatingSpring>(-1, 1, 328, 34);
50 } // namespace
51 std::unique_ptr<SwiperModel> SwiperModel::instance_ = nullptr;
52 std::mutex SwiperModel::mutex_;
53 
GetInstance()54 SwiperModel* SwiperModel::GetInstance()
55 {
56     if (!instance_) {
57         std::lock_guard<std::mutex> lock(mutex_);
58         if (!instance_) {
59 #ifdef NG_BUILD
60             instance_.reset(new NG::SwiperModelNG());
61 #else
62             if (Container::IsCurrentUseNewPipeline()) {
63                 instance_.reset(new NG::SwiperModelNG());
64             } else {
65                 instance_.reset(new Framework::SwiperModelImpl());
66             }
67 #endif
68         }
69     }
70     return instance_.get();
71 }
72 
73 } // namespace OHOS::Ace
74 namespace OHOS::Ace::Framework {
75 WeakPtr<JSIndicatorController> JSSwiper::jSIndicatorController_;
76 namespace {
77 
78 const std::vector<EdgeEffect> EDGE_EFFECT = { EdgeEffect::SPRING, EdgeEffect::FADE, EdgeEffect::NONE };
79 const std::vector<SwiperDisplayMode> DISPLAY_MODE = { SwiperDisplayMode::STRETCH, SwiperDisplayMode::AUTO_LINEAR };
80 const std::vector<SwiperIndicatorType> INDICATOR_TYPE = { SwiperIndicatorType::DOT, SwiperIndicatorType::DIGIT };
81 const std::vector<SwiperAnimationMode> SWIPER_ANIMATION_MODE = { SwiperAnimationMode::NO_ANIMATION,
82     SwiperAnimationMode::DEFAULT_ANIMATION, SwiperAnimationMode::FAST_ANIMATION };
83 const static int32_t DEFAULT_INTERVAL = 3000;
84 const static int32_t DEFAULT_DURATION = 400;
85 const static int32_t DEFAULT_DISPLAY_COUNT = 1;
86 const static int32_t DEFAULT_CACHED_COUNT = 1;
87 
SwiperChangeEventToJSValue(const SwiperChangeEvent & eventInfo)88 JSRef<JSVal> SwiperChangeEventToJSValue(const SwiperChangeEvent& eventInfo)
89 {
90     return JSRef<JSVal>::Make(ToJSValue(eventInfo.GetIndex()));
91 }
92 
93 } // namespace
94 
Create(const JSCallbackInfo & info)95 void JSSwiper::Create(const JSCallbackInfo& info)
96 {
97     auto controller = SwiperModel::GetInstance()->Create();
98 
99     if (info.Length() > 0 && info[0]->IsObject()) {
100         auto* jsController = JSRef<JSObject>::Cast(info[0])->Unwrap<JSSwiperController>();
101         if (jsController) {
102             jsController->SetInstanceId(Container::CurrentId());
103             jsController->SetController(controller);
104         }
105     }
106 
107     JSSwiperTheme::ApplyThemeInConstructor();
108 }
109 
JsRemoteMessage(const JSCallbackInfo & info)110 void JSSwiper::JsRemoteMessage(const JSCallbackInfo& info)
111 {
112     RemoteCallback remoteCallback;
113     JSInteractableView::JsRemoteMessage(info, remoteCallback);
114 
115     SwiperModel::GetInstance()->SetRemoteMessageEventId(std::move(remoteCallback));
116 }
117 
JSBind(BindingTarget globalObj)118 void JSSwiper::JSBind(BindingTarget globalObj)
119 {
120     JsSwiperContentTransitionProxy::JSBind(globalObj);
121     JSClass<JSSwiper>::Declare("Swiper");
122     MethodOptions opt = MethodOptions::NONE;
123     JSClass<JSSwiper>::StaticMethod("create", &JSSwiper::Create, opt);
124     JSClass<JSSwiper>::StaticMethod("indicatorInteractive", &JSSwiper::SetIndicatorInteractive, opt);
125     JSClass<JSSwiper>::StaticMethod("autoPlay", &JSSwiper::SetAutoPlay, opt);
126     JSClass<JSSwiper>::StaticMethod("duration", &JSSwiper::SetDuration, opt);
127     JSClass<JSSwiper>::StaticMethod("index", &JSSwiper::SetIndex, opt);
128     JSClass<JSSwiper>::StaticMethod("interval", &JSSwiper::SetInterval, opt);
129     JSClass<JSSwiper>::StaticMethod("loop", &JSSwiper::SetLoop, opt);
130     JSClass<JSSwiper>::StaticMethod("vertical", &JSSwiper::SetVertical, opt);
131     JSClass<JSSwiper>::StaticMethod("indicator", &JSSwiper::SetIndicator, opt);
132     JSClass<JSSwiper>::StaticMethod("displayMode", &JSSwiper::SetDisplayMode);
133     JSClass<JSSwiper>::StaticMethod("effectMode", &JSSwiper::SetEffectMode);
134     JSClass<JSSwiper>::StaticMethod("displayCount", &JSSwiper::SetDisplayCount);
135     JSClass<JSSwiper>::StaticMethod("itemSpace", &JSSwiper::SetItemSpace);
136     JSClass<JSSwiper>::StaticMethod("prevMargin", &JSSwiper::SetPreviousMargin);
137     JSClass<JSSwiper>::StaticMethod("nextMargin", &JSSwiper::SetNextMargin);
138     JSClass<JSSwiper>::StaticMethod("cachedCount", &JSSwiper::SetCachedCount);
139     JSClass<JSSwiper>::StaticMethod("curve", &JSSwiper::SetCurve);
140     JSClass<JSSwiper>::StaticMethod("onChange", &JSSwiper::SetOnChange);
141     JSClass<JSSwiper>::StaticMethod("onAnimationStart", &JSSwiper::SetOnAnimationStart);
142     JSClass<JSSwiper>::StaticMethod("onAnimationEnd", &JSSwiper::SetOnAnimationEnd);
143     JSClass<JSSwiper>::StaticMethod("onGestureSwipe", &JSSwiper::SetOnGestureSwipe);
144     JSClass<JSSwiper>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
145     JSClass<JSSwiper>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
146     JSClass<JSSwiper>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
147     JSClass<JSSwiper>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
148     JSClass<JSSwiper>::StaticMethod("remoteMessage", &JSSwiper::JsRemoteMessage);
149     JSClass<JSSwiper>::StaticMethod("onClick", &JSSwiper::SetOnClick);
150     JSClass<JSSwiper>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
151     JSClass<JSSwiper>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
152     JSClass<JSSwiper>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
153     JSClass<JSSwiper>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
154     JSClass<JSSwiper>::StaticMethod("indicatorStyle", &JSSwiper::SetIndicatorStyle);
155     JSClass<JSSwiper>::StaticMethod("enabled", &JSSwiper::SetEnabled);
156     JSClass<JSSwiper>::StaticMethod("disableSwipe", &JSSwiper::SetDisableSwipe);
157     JSClass<JSSwiper>::StaticMethod("height", &JSSwiper::SetHeight);
158     JSClass<JSSwiper>::StaticMethod("width", &JSSwiper::SetWidth);
159     JSClass<JSSwiper>::StaticMethod("size", &JSSwiper::SetSize);
160     JSClass<JSSwiper>::StaticMethod("displayArrow", &JSSwiper::SetDisplayArrow);
161     JSClass<JSSwiper>::StaticMethod("nestedScroll", &JSSwiper::SetNestedScroll);
162     JSClass<JSSwiper>::StaticMethod("customContentTransition", &JSSwiper::SetCustomContentTransition);
163     JSClass<JSSwiper>::StaticMethod("onContentDidScroll", &JSSwiper::SetOnContentDidScroll);
164     JSClass<JSSwiper>::StaticMethod("pageFlipMode", &JSSwiper::SetPageFlipMode);
165     JSClass<JSSwiper>::StaticMethod("onContentWillScroll", &JSSwiper::SetOnContentWillScroll);
166     JSClass<JSSwiper>::InheritAndBind<JSContainerBase>(globalObj);
167 }
168 
SetIndicatorInteractive(const JSCallbackInfo & info)169 void JSSwiper::SetIndicatorInteractive(const JSCallbackInfo& info)
170 {
171     if (info.Length() < 1) {
172         return;
173     }
174 
175     if (info[0]->IsBoolean()) {
176         SwiperModel::GetInstance()->SetIndicatorInteractive(info[0]->ToBoolean());
177     } else {
178         SwiperModel::GetInstance()->SetIndicatorInteractive(true);
179     }
180 }
181 
SetAutoPlay(bool autoPlay)182 void JSSwiper::SetAutoPlay(bool autoPlay)
183 {
184     SwiperModel::GetInstance()->SetAutoPlay(autoPlay);
185 }
186 
SetEnabled(const JSCallbackInfo & info)187 void JSSwiper::SetEnabled(const JSCallbackInfo& info)
188 {
189     JSViewAbstract::JsEnabled(info);
190     if (info.Length() < 1) {
191         return;
192     }
193 
194     if (!info[0]->IsBoolean()) {
195         return;
196     }
197 
198     SwiperModel::GetInstance()->SetEnabled(info[0]->ToBoolean());
199 }
200 
SetDisableSwipe(bool disableSwipe)201 void JSSwiper::SetDisableSwipe(bool disableSwipe)
202 {
203     SwiperModel::GetInstance()->SetDisableSwipe(disableSwipe);
204 }
205 
SetEffectMode(const JSCallbackInfo & info)206 void JSSwiper::SetEffectMode(const JSCallbackInfo& info)
207 {
208     if (info.Length() < 1) {
209         return;
210     }
211 
212     if (!info[0]->IsNumber()) {
213         return;
214     }
215 
216     auto edgeEffect = info[0]->ToNumber<int32_t>();
217     if (edgeEffect < 0 || edgeEffect >= static_cast<int32_t>(EDGE_EFFECT.size())) {
218         return;
219     }
220 
221     SwiperModel::GetInstance()->SetEdgeEffect(EDGE_EFFECT[edgeEffect]);
222 }
223 
SetDisplayCount(const JSCallbackInfo & info)224 void JSSwiper::SetDisplayCount(const JSCallbackInfo& info)
225 {
226     if (info.Length() < 1) {
227         return;
228     }
229 
230     if (info.Length() == 2) {
231         if (info[1]->IsBoolean()) {
232             SwiperModel::GetInstance()->SetSwipeByGroup(info[1]->ToBoolean());
233         } else {
234             SwiperModel::GetInstance()->SetSwipeByGroup(false);
235         }
236     }
237 
238     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
239         if (info[0]->IsString() && info[0]->ToString() == "auto") {
240             SwiperModel::GetInstance()->SetDisplayMode(SwiperDisplayMode::AUTO_LINEAR);
241             SwiperModel::GetInstance()->ResetDisplayCount();
242         } else if (info[0]->IsNumber() && info[0]->ToNumber<int32_t>() > 0) {
243             SwiperModel::GetInstance()->SetDisplayCount(info[0]->ToNumber<int32_t>());
244         } else if (info[0]->IsObject()) {
245             JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
246             auto minSizeParam = jsObj->GetProperty("minSize");
247             if (minSizeParam->IsNull()) {
248                 return;
249             }
250             CalcDimension minSizeValue;
251             if (!ParseJsDimensionVp(minSizeParam, minSizeValue)) {
252                 SwiperModel::GetInstance()->SetMinSize(0.0_vp);
253                 return;
254             }
255             SwiperModel::GetInstance()->SetMinSize(minSizeValue);
256         } else {
257             SwiperModel::GetInstance()->SetDisplayCount(DEFAULT_DISPLAY_COUNT);
258         }
259 
260         return;
261     }
262 
263     if (info[0]->IsString() && info[0]->ToString() == "auto") {
264         SwiperModel::GetInstance()->SetDisplayMode(SwiperDisplayMode::AUTO_LINEAR);
265         SwiperModel::GetInstance()->ResetDisplayCount();
266     } else if (info[0]->IsNumber()) {
267         SwiperModel::GetInstance()->SetDisplayCount(info[0]->ToNumber<int32_t>());
268     }
269 }
270 
SetDuration(const JSCallbackInfo & info)271 void JSSwiper::SetDuration(const JSCallbackInfo& info)
272 {
273     int32_t duration = DEFAULT_DURATION;
274 
275     if (info.Length() < 1) { // user do not set any value
276         return;
277     }
278 
279     // undefined value turn to default 400
280     if (!info[0]->IsUndefined() && info[0]->IsNumber()) {
281         duration = info[0]->ToNumber<int32_t>();
282         if (duration < 0) {
283             duration = DEFAULT_DURATION;
284         }
285     }
286 
287     SwiperModel::GetInstance()->SetDuration(duration);
288 }
289 
ParseSwiperIndexObject(const JSCallbackInfo & args,const JSRef<JSVal> & changeEventVal)290 void ParseSwiperIndexObject(const JSCallbackInfo& args, const JSRef<JSVal>& changeEventVal)
291 {
292     CHECK_NULL_VOID(changeEventVal->IsFunction());
293 
294     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
295     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
296     auto onIndex = [execCtx = args.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
297                        const BaseEventInfo* info) {
298         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
299         ACE_SCORING_EVENT("Swiper.onChangeEvent");
300         PipelineContext::SetCallBackNode(node);
301         const auto* swiperInfo = TypeInfoHelper::DynamicCast<SwiperChangeEvent>(info);
302         if (!swiperInfo) {
303             return;
304         }
305         auto newJSVal = JSRef<JSVal>::Make(ToJSValue(swiperInfo->GetIndex()));
306         func->ExecuteJS(1, &newJSVal);
307     };
308     SwiperModel::GetInstance()->SetOnChangeEvent(std::move(onIndex));
309 }
310 
SetIndex(const JSCallbackInfo & info)311 void JSSwiper::SetIndex(const JSCallbackInfo& info)
312 {
313     auto length = info.Length();
314     if (length < 1 || length > 2) {
315         return;
316     }
317 
318     int32_t index = 0;
319     auto jsIndex = info[0];
320     if (length > 0 && jsIndex->IsNumber()) {
321         index = jsIndex->ToNumber<int32_t>();
322     }
323 
324     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
325         index = index < 0 ? 0 : index;
326     }
327 
328     if (index < 0) {
329         return;
330     }
331     SwiperModel::GetInstance()->SetIndex(index);
332 
333     if (length > 1 && info[1]->IsFunction()) {
334         ParseSwiperIndexObject(info, info[1]);
335     }
336 }
337 
SetInterval(const JSCallbackInfo & info)338 void JSSwiper::SetInterval(const JSCallbackInfo& info)
339 {
340     int32_t interval = DEFAULT_INTERVAL;
341 
342     if (info.Length() < 1) { // user do not set any value
343         return;
344     }
345 
346     // undefined value turn to default 3000
347     if (!info[0]->IsUndefined() && info[0]->IsNumber()) {
348         interval = info[0]->ToNumber<int32_t>();
349         if (interval < 0) {
350             interval = DEFAULT_INTERVAL;
351         }
352     }
353 
354     SwiperModel::GetInstance()->SetAutoPlayInterval(interval);
355 }
356 
SetLoop(const JSCallbackInfo & info)357 void JSSwiper::SetLoop(const JSCallbackInfo& info)
358 {
359     if (info.Length() < 1) {
360         return;
361     }
362 
363     if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
364         SwiperModel::GetInstance()->SetLoop(info[0]->ToBoolean());
365         return;
366     }
367 
368     if (info[0]->IsBoolean()) {
369         SwiperModel::GetInstance()->SetLoop(info[0]->ToBoolean());
370     } else {
371         SwiperModel::GetInstance()->SetLoop(true);
372     }
373 }
374 
SetVertical(bool isVertical)375 void JSSwiper::SetVertical(bool isVertical)
376 {
377     SwiperModel::GetInstance()->SetDirection(isVertical ? Axis::VERTICAL : Axis::HORIZONTAL);
378 }
379 
GetFontContent(const JSRef<JSVal> & font,bool isSelected,SwiperDigitalParameters & digitalParameters)380 void JSSwiper::GetFontContent(const JSRef<JSVal>& font, bool isSelected, SwiperDigitalParameters& digitalParameters)
381 {
382     JSRef<JSObject> obj = JSRef<JSObject>::Cast(font);
383     JSRef<JSVal> size = obj->GetProperty("size");
384     auto pipelineContext = PipelineBase::GetCurrentContext();
385     CHECK_NULL_VOID(pipelineContext);
386     auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
387     CHECK_NULL_VOID(swiperIndicatorTheme);
388     // set font size, unit FP
389     CalcDimension fontSize;
390     if (!size->IsUndefined() && !size->IsNull() && ParseJsDimensionFp(size, fontSize)) {
391         if (LessOrEqual(fontSize.Value(), 0.0) || LessOrEqual(size->ToNumber<double>(), 0.0) ||
392             fontSize.Unit() == DimensionUnit::PERCENT) {
393             fontSize = swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetFontSize();
394         }
395     } else {
396         fontSize = swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetFontSize();
397     }
398     if (isSelected) {
399         digitalParameters.selectedFontSize = fontSize;
400     } else {
401         digitalParameters.fontSize = fontSize;
402     }
403     JSRef<JSVal> weight = obj->GetProperty("weight");
404     if (!weight->IsNull()) {
405         std::string weightValue;
406         if (weight->IsNumber()) {
407             weightValue = std::to_string(weight->ToNumber<int32_t>());
408         } else {
409             ParseJsString(weight, weightValue);
410         }
411         if (isSelected) {
412             digitalParameters.selectedFontWeight = ConvertStrToFontWeight(weightValue);
413         } else {
414             digitalParameters.fontWeight = ConvertStrToFontWeight(weightValue);
415         }
416     } else {
417         if (isSelected) {
418             digitalParameters.selectedFontWeight = swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetFontWeight();
419         } else {
420             digitalParameters.fontWeight = swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetFontWeight();
421         }
422     }
423 }
424 
SetIsIndicatorCustomSize(const Dimension & dimPosition,bool parseOk)425 void JSSwiper::SetIsIndicatorCustomSize(const Dimension& dimPosition, bool parseOk)
426 {
427     if (parseOk && dimPosition > 0.0_vp) {
428         SwiperModel::GetInstance()->SetIsIndicatorCustomSize(true);
429     } else {
430         SwiperModel::GetInstance()->SetIsIndicatorCustomSize(false);
431     }
432 }
433 
ParseIndicatorDimension(const JSRef<JSVal> & value)434 std::optional<Dimension> JSSwiper::ParseIndicatorDimension(const JSRef<JSVal>& value)
435 {
436     std::optional<Dimension> indicatorDimension;
437     if (value->IsUndefined()) {
438         return indicatorDimension;
439     }
440     CalcDimension dimPosition;
441     auto parseOk = ParseJsDimensionVp(value, dimPosition);
442     indicatorDimension = parseOk && dimPosition.ConvertToPx() >= 0.0f ? dimPosition : 0.0_vp;
443     return indicatorDimension;
444 }
445 
GetDotIndicatorInfo(const JSRef<JSObject> & obj)446 SwiperParameters JSSwiper::GetDotIndicatorInfo(const JSRef<JSObject>& obj)
447 {
448     JSRef<JSVal> leftValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT_VALUE));
449     JSRef<JSVal> topValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP_VALUE));
450     JSRef<JSVal> rightValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT_VALUE));
451     JSRef<JSVal> bottomValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM_VALUE));
452     JSRef<JSVal> startValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::START_VALUE));
453     JSRef<JSVal> endValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::END_VALUE));
454     JSRef<JSVal> itemWidthValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::ITEM_WIDTH_VALUE));
455     JSRef<JSVal> itemHeightValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::ITEM_HEIGHT_VALUE));
456     JSRef<JSVal> selectedItemWidthValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::SELECTED_ITEM_WIDTH_VALUE));
457     JSRef<JSVal> selectedItemHeightValue =
458         obj->GetProperty(static_cast<int32_t>(ArkUIIndex::SELECTED_ITEM_HEIGHT_VALUE));
459     JSRef<JSVal> maskValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::MASK_VALUE));
460     JSRef<JSVal> colorValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR_VALUE));
461     JSRef<JSVal> selectedColorValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::SELECTED_COLOR_VALUE));
462     auto pipelineContext = PipelineBase::GetCurrentContext();
463     CHECK_NULL_RETURN(pipelineContext, SwiperParameters());
464     auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
465     CHECK_NULL_RETURN(swiperIndicatorTheme, SwiperParameters());
466     SwiperParameters swiperParameters;
467     swiperParameters.dimLeft = ParseIndicatorDimension(leftValue);
468     swiperParameters.dimTop = ParseIndicatorDimension(topValue);
469     swiperParameters.dimRight = ParseIndicatorDimension(rightValue);
470     swiperParameters.dimBottom = ParseIndicatorDimension(bottomValue);
471     CalcDimension dimStart;
472     CalcDimension dimEnd;
473     std::optional<Dimension> indicatorDimension;
474     swiperParameters.dimStart =  ParseLengthMetricsToDimension(startValue, dimStart) ? dimStart : indicatorDimension;
475     swiperParameters.dimEnd =  ParseLengthMetricsToDimension(endValue, dimEnd) ? dimEnd : indicatorDimension;
476 
477     CalcDimension dimPosition;
478     bool parseItemWOk =
479         ParseJsDimensionVp(itemWidthValue, dimPosition) && (dimPosition.Unit() != DimensionUnit::PERCENT);
480     auto defaultSize = swiperIndicatorTheme->GetSize();
481     swiperParameters.itemWidth = parseItemWOk && dimPosition > 0.0_vp ? dimPosition : defaultSize;
482     bool parseItemHOk =
483         ParseJsDimensionVp(itemHeightValue, dimPosition) && (dimPosition.Unit() != DimensionUnit::PERCENT);
484     swiperParameters.itemHeight = parseItemHOk && dimPosition > 0.0_vp ? dimPosition : defaultSize;
485     bool parseSelectedItemWOk =
486         ParseJsDimensionVp(selectedItemWidthValue, dimPosition) && (dimPosition.Unit() != DimensionUnit::PERCENT);
487     swiperParameters.selectedItemWidth = parseSelectedItemWOk && dimPosition > 0.0_vp ? dimPosition : defaultSize;
488     bool parseSelectedItemHOk =
489         ParseJsDimensionVp(selectedItemHeightValue, dimPosition) && (dimPosition.Unit() != DimensionUnit::PERCENT);
490     swiperParameters.selectedItemHeight = parseSelectedItemHOk && dimPosition > 0.0_vp ? dimPosition : defaultSize;
491     SwiperModel::GetInstance()->SetIsIndicatorCustomSize(
492         parseSelectedItemWOk || parseSelectedItemHOk || parseItemWOk || parseItemHOk);
493     if (maskValue->IsBoolean()) {
494         auto mask = maskValue->ToBoolean();
495         swiperParameters.maskValue = mask;
496     }
497     Color colorVal;
498     auto parseOk = ParseJsColor(colorValue, colorVal);
499     swiperParameters.colorVal = parseOk ? colorVal : swiperIndicatorTheme->GetColor();
500     parseOk = ParseJsColor(selectedColorValue, colorVal);
501     swiperParameters.selectedColorVal = parseOk ? colorVal : swiperIndicatorTheme->GetSelectedColor();
502 
503     JSRef<JSVal> maxDisplayCountVal = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::MAX_DISPLAY_COUNT_VALUE));
504     if (!maxDisplayCountVal->IsUndefined()) {
505         uint32_t result = 0;
506         auto setMaxDisplayCountVal = ParseJsInteger(maxDisplayCountVal, result);
507         swiperParameters.maxDisplayCountVal = setMaxDisplayCountVal && result > 0 ? result : 0;
508     }
509     return swiperParameters;
510 }
511 
ParseLengthMetricsToDimension(const JSRef<JSVal> & jsValue,CalcDimension & result)512 bool JSSwiper::ParseLengthMetricsToDimension(const JSRef<JSVal>& jsValue, CalcDimension& result)
513 {
514     if (jsValue->IsNumber()) {
515         result = CalcDimension(jsValue->ToNumber<double>(), DimensionUnit::VP);
516         return true;
517     }
518     if (jsValue->IsString()) {
519         auto value = jsValue->ToString();
520         StringUtils::StringToCalcDimensionNG(value, result, false, DimensionUnit::VP);
521         return true;
522     }
523     if (jsValue->IsObject()) {
524         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
525         double value = jsObj->GetProperty("value")->ToNumber<double>();
526         auto unit = static_cast<DimensionUnit>(jsObj->GetProperty("unit")->ToNumber<int32_t>());
527         result = CalcDimension(value, unit);
528         return true;
529     }
530     if (jsValue->IsNull()) {
531         result = CalcDimension(0.0f, DimensionUnit::VP);
532         return true;
533     }
534 
535     return false;
536 }
537 
GetDigitIndicatorInfo(const JSRef<JSObject> & obj)538 SwiperDigitalParameters JSSwiper::GetDigitIndicatorInfo(const JSRef<JSObject>& obj)
539 {
540     JSRef<JSVal> dotLeftValue = obj->GetProperty("leftValue");
541     JSRef<JSVal> dotTopValue = obj->GetProperty("topValue");
542     JSRef<JSVal> dotRightValue = obj->GetProperty("rightValue");
543     JSRef<JSVal> dotBottomValue = obj->GetProperty("bottomValue");
544     JSRef<JSVal> startValue = obj->GetProperty("startValue");
545     JSRef<JSVal> endValue = obj->GetProperty("endValue");
546     JSRef<JSVal> fontColorValue = obj->GetProperty("fontColorValue");
547     JSRef<JSVal> selectedFontColorValue = obj->GetProperty("selectedFontColorValue");
548     JSRef<JSVal> digitFontValue = obj->GetProperty("digitFontValue");
549     JSRef<JSVal> selectedDigitFontValue = obj->GetProperty("selectedDigitFontValue");
550     auto pipelineContext = PipelineBase::GetCurrentContext();
551     CHECK_NULL_RETURN(pipelineContext, SwiperDigitalParameters());
552     auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
553     CHECK_NULL_RETURN(swiperIndicatorTheme, SwiperDigitalParameters());
554     SwiperDigitalParameters digitalParameters;
555     digitalParameters.dimLeft = ParseIndicatorDimension(dotLeftValue);
556     digitalParameters.dimTop = ParseIndicatorDimension(dotTopValue);
557     digitalParameters.dimRight = ParseIndicatorDimension(dotRightValue);
558     digitalParameters.dimBottom = ParseIndicatorDimension(dotBottomValue);
559     std::optional<Dimension> indicatorDimension;
560     CalcDimension dimStart;
561     CalcDimension dimEnd;
562     digitalParameters.dimStart =  ParseLengthMetricsToDimension(startValue, dimStart) ? dimStart : indicatorDimension;
563     digitalParameters.dimEnd =  ParseLengthMetricsToDimension(endValue, dimEnd) ? dimEnd : indicatorDimension;
564 
565     Color fontColor;
566     auto parseOk = JSViewAbstract::ParseJsColor(fontColorValue, fontColor);
567     digitalParameters.fontColor =
568         parseOk ? fontColor : swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetTextColor();
569     parseOk = JSViewAbstract::ParseJsColor(selectedFontColorValue, fontColor);
570     digitalParameters.selectedFontColor =
571         parseOk ? fontColor : swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetTextColor();
572     if (!digitFontValue->IsNull() && digitFontValue->IsObject()) {
573         GetFontContent(digitFontValue, false, digitalParameters);
574     }
575     if (!selectedDigitFontValue->IsNull() && selectedDigitFontValue->IsObject()) {
576         GetFontContent(selectedDigitFontValue, true, digitalParameters);
577     }
578     return digitalParameters;
579 }
580 
GetArrowInfo(const JSRef<JSObject> & obj,SwiperArrowParameters & swiperArrowParameters)581 bool JSSwiper::GetArrowInfo(const JSRef<JSObject>& obj, SwiperArrowParameters& swiperArrowParameters)
582 {
583     auto isShowBackgroundValue = obj->GetProperty("showBackground");
584     auto isSidebarMiddleValue = obj->GetProperty("isSidebarMiddle");
585     auto backgroundSizeValue = obj->GetProperty("backgroundSize");
586     auto backgroundColorValue = obj->GetProperty("backgroundColor");
587     auto arrowSizeValue = obj->GetProperty("arrowSize");
588     auto arrowColorValue = obj->GetProperty("arrowColor");
589     auto pipelineContext = PipelineBase::GetCurrentContext();
590     CHECK_NULL_RETURN(pipelineContext, false);
591     auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
592     CHECK_NULL_RETURN(swiperIndicatorTheme, false);
593     swiperArrowParameters.isShowBackground = isShowBackgroundValue->IsBoolean()
594                                                  ? isShowBackgroundValue->ToBoolean()
595                                                  : swiperIndicatorTheme->GetIsShowArrowBackground();
596     swiperArrowParameters.isSidebarMiddle = isSidebarMiddleValue->IsBoolean()
597                                                 ? isSidebarMiddleValue->ToBoolean()
598                                                 : swiperIndicatorTheme->GetIsSidebarMiddle();
599     bool parseOk = false;
600     CalcDimension dimension;
601     Color color;
602     if (swiperArrowParameters.isSidebarMiddle.value()) {
603         parseOk = ParseJsDimensionVp(backgroundSizeValue, dimension);
604         swiperArrowParameters.backgroundSize =
605             parseOk && GreatNotEqual(dimension.ConvertToVp(), 0.0) && !(dimension.Unit() == DimensionUnit::PERCENT)
606                 ? dimension
607                 : swiperIndicatorTheme->GetBigArrowBackgroundSize();
608         parseOk = ParseJsColor(backgroundColorValue, color);
609         swiperArrowParameters.backgroundColor = parseOk ? color : swiperIndicatorTheme->GetBigArrowBackgroundColor();
610         if (swiperArrowParameters.isShowBackground.value()) {
611             swiperArrowParameters.arrowSize = swiperArrowParameters.backgroundSize.value() * ARROW_SIZE_COEFFICIENT;
612         } else {
613             parseOk = ParseJsDimensionVpNG(arrowSizeValue, dimension);
614             swiperArrowParameters.arrowSize =
615                 parseOk && GreatNotEqual(dimension.ConvertToVp(), 0.0) && !(dimension.Unit() == DimensionUnit::PERCENT)
616                     ? dimension
617                     : swiperIndicatorTheme->GetBigArrowSize();
618             swiperArrowParameters.backgroundSize = swiperArrowParameters.arrowSize;
619         }
620         parseOk = ParseJsColor(arrowColorValue, color);
621         swiperArrowParameters.arrowColor = parseOk ? color : swiperIndicatorTheme->GetBigArrowColor();
622     } else {
623         parseOk = ParseJsDimensionVp(backgroundSizeValue, dimension);
624         swiperArrowParameters.backgroundSize =
625             parseOk && GreatNotEqual(dimension.ConvertToVp(), 0.0) && !(dimension.Unit() == DimensionUnit::PERCENT)
626                 ? dimension
627                 : swiperIndicatorTheme->GetSmallArrowBackgroundSize();
628         parseOk = ParseJsColor(backgroundColorValue, color);
629         swiperArrowParameters.backgroundColor = parseOk ? color : swiperIndicatorTheme->GetSmallArrowBackgroundColor();
630         if (swiperArrowParameters.isShowBackground.value()) {
631             swiperArrowParameters.arrowSize = swiperArrowParameters.backgroundSize.value() * ARROW_SIZE_COEFFICIENT;
632         } else {
633             parseOk = ParseJsDimensionVpNG(arrowSizeValue, dimension);
634             swiperArrowParameters.arrowSize =
635                 parseOk && GreatNotEqual(dimension.ConvertToVp(), 0.0) && !(dimension.Unit() == DimensionUnit::PERCENT)
636                     ? dimension
637                     : swiperIndicatorTheme->GetSmallArrowSize();
638             swiperArrowParameters.backgroundSize = swiperArrowParameters.arrowSize;
639         }
640         parseOk = ParseJsColor(arrowColorValue, color);
641         swiperArrowParameters.arrowColor = parseOk ? color : swiperIndicatorTheme->GetSmallArrowColor();
642     }
643     return true;
644 }
645 
SetDisplayArrow(const JSCallbackInfo & info)646 void JSSwiper::SetDisplayArrow(const JSCallbackInfo& info)
647 {
648     if (info[0]->IsEmpty() || info[0]->IsUndefined()) {
649         SwiperModel::GetInstance()->SetDisplayArrow(false);
650         return;
651     }
652     if (info.Length() > 0 && info[0]->IsObject()) {
653         auto obj = JSRef<JSObject>::Cast(info[0]);
654         SwiperArrowParameters swiperArrowParameters;
655         if (!GetArrowInfo(obj, swiperArrowParameters)) {
656             SwiperModel::GetInstance()->SetDisplayArrow(false);
657             return;
658         }
659         JSSwiperTheme::ApplyThemeToDisplayArrow(swiperArrowParameters, obj);
660         SwiperModel::GetInstance()->SetArrowStyle(swiperArrowParameters);
661         SwiperModel::GetInstance()->SetDisplayArrow(true);
662     } else if (info[0]->IsBoolean()) {
663         if (info[0]->ToBoolean()) {
664             auto pipelineContext = PipelineBase::GetCurrentContext();
665             CHECK_NULL_VOID(pipelineContext);
666             auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
667             CHECK_NULL_VOID(swiperIndicatorTheme);
668             SwiperArrowParameters swiperArrowParameters;
669             swiperArrowParameters.isShowBackground = swiperIndicatorTheme->GetIsShowArrowBackground();
670             swiperArrowParameters.isSidebarMiddle = swiperIndicatorTheme->GetIsSidebarMiddle();
671             swiperArrowParameters.backgroundSize = swiperIndicatorTheme->GetSmallArrowBackgroundSize();
672             swiperArrowParameters.backgroundColor = swiperIndicatorTheme->GetSmallArrowBackgroundColor();
673             swiperArrowParameters.arrowSize = swiperIndicatorTheme->GetSmallArrowSize();
674             swiperArrowParameters.arrowColor = swiperIndicatorTheme->GetSmallArrowColor();
675             JSSwiperTheme::ApplyThemeToDisplayArrowForce(swiperArrowParameters);
676             SwiperModel::GetInstance()->SetArrowStyle(swiperArrowParameters);
677             SwiperModel::GetInstance()->SetDisplayArrow(true);
678         } else {
679             SwiperModel::GetInstance()->SetDisplayArrow(false);
680             return;
681         }
682     } else {
683         SwiperModel::GetInstance()->SetDisplayArrow(false);
684         return;
685     }
686     if (info.Length() > 1 && info[1]->IsBoolean()) {
687         SwiperModel::GetInstance()->SetHoverShow(info[1]->ToBoolean());
688     } else {
689         SwiperModel::GetInstance()->SetHoverShow(false);
690     }
691 }
692 
SetIndicatorController(const JSCallbackInfo & info)693 void JSSwiper::SetIndicatorController(const JSCallbackInfo& info)
694 {
695     if (info.Length() < 1 || !info[0]->IsObject()) {
696         return;
697     }
698 
699     auto* jsIndicatorController = JSRef<JSObject>::Cast(info[0])->Unwrap<JSIndicatorController>();
700     if (!jsIndicatorController) {
701         return;
702     }
703     jSIndicatorController_ = jsIndicatorController;
704     SwiperModel::GetInstance()->SetBindIndicator(true);
705     WeakPtr<NG::UINode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
706     jsIndicatorController->SetSwiperNode(targetNode);
707 }
708 
ResetSwiperNode()709 void JSSwiper::ResetSwiperNode()
710 {
711     if (jSIndicatorController_.Upgrade()) {
712         jSIndicatorController_.Upgrade()->ResetSwiperNode();
713     }
714 }
715 
SetIndicator(const JSCallbackInfo & info)716 void JSSwiper::SetIndicator(const JSCallbackInfo& info)
717 {
718     if (info.Length() < 1) {
719         return;
720     }
721 
722     if (info[0]->IsEmpty()) {
723         SwiperModel::GetInstance()->SetShowIndicator(true);
724         return;
725     }
726     SwiperModel::GetInstance()->SetBindIndicator(false);
727     if (info[0]->IsObject()) {
728         auto obj = JSRef<JSObject>::Cast(info[0]);
729         SwiperModel::GetInstance()->SetIndicatorIsBoolean(false);
730         ResetSwiperNode();
731 
732         JSRef<JSVal> typeParam = obj->GetProperty("type");
733         if (typeParam->IsString()) {
734             auto type = typeParam->ToString();
735             if (type == "DigitIndicator") {
736                 SwiperDigitalParameters digitalParameters = GetDigitIndicatorInfo(obj);
737                 JSSwiperTheme::ApplyThemeToDigitIndicator(digitalParameters, obj);
738                 SwiperModel::GetInstance()->SetDigitIndicatorStyle(digitalParameters);
739                 SwiperModel::GetInstance()->SetIndicatorType(SwiperIndicatorType::DIGIT);
740             } else {
741                 SwiperParameters swiperParameters = GetDotIndicatorInfo(obj);
742                 JSSwiperTheme::ApplyThemeToDotIndicator(swiperParameters, obj);
743                 SwiperModel::GetInstance()->SetDotIndicatorStyle(swiperParameters);
744                 SwiperModel::GetInstance()->SetIndicatorType(SwiperIndicatorType::DOT);
745             }
746         } else if (typeParam->IsUndefined()) {
747             SetIndicatorController(info);
748         } else {
749             SwiperParameters swiperParameters = GetDotIndicatorInfo(obj);
750             JSSwiperTheme::ApplyThemeToDotIndicatorForce(swiperParameters);
751             SwiperModel::GetInstance()->SetDotIndicatorStyle(swiperParameters);
752             SwiperModel::GetInstance()->SetIndicatorType(SwiperIndicatorType::DOT);
753         }
754     } else {
755         SwiperParameters swiperParameters = GetDotIndicatorInfo(JSRef<JSObject>::New());
756         JSSwiperTheme::ApplyThemeToDotIndicatorForce(swiperParameters);
757         SwiperModel::GetInstance()->SetDotIndicatorStyle(swiperParameters);
758         SwiperModel::GetInstance()->SetIndicatorType(SwiperIndicatorType::DOT);
759     }
760     if (info[0]->IsBoolean()) {
761         bool showIndicator = false;
762         ParseJsBool(info[0], showIndicator);
763         SwiperModel::GetInstance()->SetShowIndicator(showIndicator);
764     } else {
765         SwiperModel::GetInstance()->SetShowIndicator(true);
766     }
767 }
768 
SetIndicatorStyle(const JSCallbackInfo & info)769 void JSSwiper::SetIndicatorStyle(const JSCallbackInfo& info)
770 {
771     SwiperParameters swiperParameters;
772     if (info[0]->IsObject()) {
773         JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
774         JSRef<JSVal> leftValue = obj->GetProperty("left");
775         JSRef<JSVal> topValue = obj->GetProperty("top");
776         JSRef<JSVal> rightValue = obj->GetProperty("right");
777         JSRef<JSVal> bottomValue = obj->GetProperty("bottom");
778         JSRef<JSVal> sizeValue = obj->GetProperty("size");
779         JSRef<JSVal> maskValue = obj->GetProperty("mask");
780         JSRef<JSVal> colorValue = obj->GetProperty("color");
781         JSRef<JSVal> selectedColorValue = obj->GetProperty("selectedColor");
782         auto pipelineContext = PipelineBase::GetCurrentContext();
783         CHECK_NULL_VOID(pipelineContext);
784         auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
785         CHECK_NULL_VOID(swiperIndicatorTheme);
786         swiperParameters.dimLeft = ParseIndicatorDimension(leftValue);
787         swiperParameters.dimTop = ParseIndicatorDimension(topValue);
788         swiperParameters.dimRight = ParseIndicatorDimension(rightValue);
789         swiperParameters.dimBottom = ParseIndicatorDimension(bottomValue);
790         CalcDimension dimPosition;
791         auto parseOk = ParseJsDimensionVp(sizeValue, dimPosition) && (dimPosition.Unit() != DimensionUnit::PERCENT);
792         SetIsIndicatorCustomSize(dimPosition, parseOk);
793         swiperParameters.itemWidth = parseOk && dimPosition > 0.0_vp ? dimPosition : swiperIndicatorTheme->GetSize();
794         swiperParameters.itemHeight = parseOk && dimPosition > 0.0_vp ? dimPosition : swiperIndicatorTheme->GetSize();
795         swiperParameters.selectedItemWidth =
796             parseOk && dimPosition > 0.0_vp ? dimPosition : swiperIndicatorTheme->GetSize();
797         swiperParameters.selectedItemHeight =
798             parseOk && dimPosition > 0.0_vp ? dimPosition : swiperIndicatorTheme->GetSize();
799         if (maskValue->IsBoolean()) {
800             auto mask = maskValue->ToBoolean();
801             swiperParameters.maskValue = mask;
802         }
803         Color colorVal;
804         parseOk = ParseJsColor(colorValue, colorVal);
805         swiperParameters.colorVal = parseOk ? colorVal : swiperIndicatorTheme->GetColor();
806         parseOk = ParseJsColor(selectedColorValue, colorVal);
807         swiperParameters.selectedColorVal = parseOk ? colorVal : swiperIndicatorTheme->GetSelectedColor();
808     }
809     SwiperModel::GetInstance()->SetDotIndicatorStyle(swiperParameters);
810     info.ReturnSelf();
811 }
812 
SetItemSpace(const JSCallbackInfo & info)813 void JSSwiper::SetItemSpace(const JSCallbackInfo& info)
814 {
815     if (info.Length() < 1) {
816         return;
817     }
818 
819     CalcDimension value;
820     if (!ParseJsDimensionVp(info[0], value) || LessNotEqual(value.Value(), 0.0)) {
821         value.SetValue(0.0);
822     }
823 
824     SwiperModel::GetInstance()->SetItemSpace(value);
825 }
826 
SetPreviousMargin(const JSCallbackInfo & info)827 void JSSwiper::SetPreviousMargin(const JSCallbackInfo& info)
828 {
829     if (info.Length() < 1) {
830         return;
831     }
832 
833     CalcDimension value;
834     bool ignoreBlank = false;
835     if (!ParseJsDimensionVp(info[0], value) || info[0]->IsNull() || info[0]->IsUndefined() ||
836         LessNotEqual(value.Value(), 0.0)) {
837         value.SetValue(0.0);
838     }
839     if (info.Length() > 1 && info[1]->IsBoolean()) {
840         ignoreBlank = info[1]->ToBoolean();
841     }
842     SwiperModel::GetInstance()->SetPreviousMargin(value, ignoreBlank);
843 }
844 
SetNextMargin(const JSCallbackInfo & info)845 void JSSwiper::SetNextMargin(const JSCallbackInfo& info)
846 {
847     if (info.Length() < 1) {
848         return;
849     }
850 
851     CalcDimension value;
852     bool ignoreBlank = false;
853     if (!ParseJsDimensionVp(info[0], value) || info[0]->IsNull() || info[0]->IsUndefined() ||
854         LessNotEqual(value.Value(), 0.0)) {
855         value.SetValue(0.0);
856     }
857     if (info.Length() > 1 && info[1]->IsBoolean()) {
858         ignoreBlank = info[1]->ToBoolean();
859     }
860     SwiperModel::GetInstance()->SetNextMargin(value, ignoreBlank);
861 }
862 
SetDisplayMode(int32_t index)863 void JSSwiper::SetDisplayMode(int32_t index)
864 {
865     if (index < 0 || index >= static_cast<int32_t>(DISPLAY_MODE.size())) {
866         return;
867     }
868 
869     SwiperModel::GetInstance()->SetDisplayMode(DISPLAY_MODE[index]);
870 }
871 
SetCachedCount(const JSCallbackInfo & info)872 void JSSwiper::SetCachedCount(const JSCallbackInfo& info)
873 {
874     if (info.Length() < 1) {
875         return;
876     }
877 
878     int32_t cachedCount = DEFAULT_CACHED_COUNT;
879     if (!info[0]->IsUndefined() && info[0]->IsNumber()) {
880         cachedCount = info[0]->ToNumber<int32_t>();
881         if (cachedCount < 0) {
882             cachedCount = DEFAULT_CACHED_COUNT;
883         }
884     }
885     SwiperModel::GetInstance()->SetCachedCount(cachedCount);
886 
887     auto isShown = info.Length() > 1 && info[1]->IsBoolean() && info[1]->ToBoolean();
888     SwiperModel::GetInstance()->SetCachedIsShown(isShown);
889 }
890 
SetCurve(const JSCallbackInfo & info)891 void JSSwiper::SetCurve(const JSCallbackInfo& info)
892 {
893     RefPtr<Curve> curve = DEFAULT_CURVE;
894     if (info[0]->IsString()) {
895         curve = CreateCurve(info[0]->ToString(), false);
896         if (!curve) {
897             curve = DEFAULT_CURVE;
898         }
899     } else if (info[0]->IsObject()) {
900         auto object = JSRef<JSObject>::Cast(info[0]);
901         std::function<float(float)> customCallBack = nullptr;
902         JSRef<JSVal> onCallBack = object->GetProperty("__curveCustomFunc");
903         if (onCallBack->IsFunction()) {
904             RefPtr<JsFunction> jsFuncCallBack =
905                 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onCallBack));
906             customCallBack = [func = std::move(jsFuncCallBack), id = Container::CurrentId()](float time) -> float {
907                 ContainerScope scope(id);
908                 JSRef<JSVal> params[1];
909                 params[0] = JSRef<JSVal>::Make(ToJSValue(time));
910                 auto result = func->ExecuteJS(1, params);
911                 auto resultValue = result->IsNumber() ? result->ToNumber<float>() : 1.0f;
912                 return resultValue;
913             };
914         }
915         auto jsCurveString = object->GetProperty("__curveString");
916         if (jsCurveString->IsString()) {
917             auto aniTimFunc = jsCurveString->ToString();
918             if (aniTimFunc == DOM_ANIMATION_TIMING_FUNCTION_CUSTOM && customCallBack) {
919                 curve = CreateCurve(customCallBack);
920             } else if (aniTimFunc != DOM_ANIMATION_TIMING_FUNCTION_CUSTOM) {
921                 curve = CreateCurve(aniTimFunc);
922             }
923         }
924     }
925     SwiperModel::GetInstance()->SetCurve(curve);
926 }
927 
SetOnChange(const JSCallbackInfo & info)928 void JSSwiper::SetOnChange(const JSCallbackInfo& info)
929 {
930     if (!info[0]->IsFunction()) {
931         return;
932     }
933 
934     auto changeHandler = AceType::MakeRefPtr<JsEventFunction<SwiperChangeEvent, 1>>(
935         JSRef<JSFunc>::Cast(info[0]), SwiperChangeEventToJSValue);
936     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
937     auto onChange = [executionContext = info.GetExecutionContext(), func = std::move(changeHandler), node = targetNode](
938                         const BaseEventInfo* info) {
939         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
940         const auto* swiperInfo = TypeInfoHelper::DynamicCast<SwiperChangeEvent>(info);
941         if (!swiperInfo) {
942             TAG_LOGW(AceLogTag::ACE_SWIPER, "Swiper onChange callback execute failed.");
943             return;
944         }
945         ACE_SCORING_EVENT("Swiper.OnChange");
946         PipelineContext::SetCallBackNode(node);
947         func->Execute(*swiperInfo);
948     };
949 
950     SwiperModel::GetInstance()->SetOnChange(std::move(onChange));
951 }
952 
SetOnAnimationStart(const JSCallbackInfo & info)953 void JSSwiper::SetOnAnimationStart(const JSCallbackInfo& info)
954 {
955     if (!info[0]->IsFunction()) {
956         return;
957     }
958 
959     if (Container::IsCurrentUseNewPipeline()) {
960         auto animationStartHandler = AceType::MakeRefPtr<JsSwiperFunction>(JSRef<JSFunc>::Cast(info[0]));
961         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
962         auto onAnimationStart = [executionContext = info.GetExecutionContext(), func = std::move(animationStartHandler),
963                                     node = targetNode](
964                                     int32_t index, int32_t targetIndex, const AnimationCallbackInfo& info) {
965             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
966             ACE_SCORING_EVENT("Swiper.onAnimationStart");
967             PipelineContext::SetCallBackNode(node);
968             func->Execute(index, targetIndex, info);
969         };
970 
971         SwiperModel::GetInstance()->SetOnAnimationStart(std::move(onAnimationStart));
972         return;
973     }
974 
975     auto animationStartHandler = AceType::MakeRefPtr<JsEventFunction<SwiperChangeEvent, 1>>(
976         JSRef<JSFunc>::Cast(info[0]), SwiperChangeEventToJSValue);
977     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
978     auto onAnimationStart = [executionContext = info.GetExecutionContext(), func = std::move(animationStartHandler),
979                                 node = targetNode](const BaseEventInfo* info) {
980         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
981         const auto* swiperInfo = TypeInfoHelper::DynamicCast<SwiperChangeEvent>(info);
982         if (!swiperInfo) {
983             TAG_LOGW(AceLogTag::ACE_SWIPER, "Swiper onAnimationStart callback execute failed.");
984             return;
985         }
986         ACE_SCORING_EVENT("Swiper.onAnimationStart");
987         PipelineContext::SetCallBackNode(node);
988         func->Execute(*swiperInfo);
989     };
990 
991     SwiperModel::GetInstance()->SetOnAnimationStart(std::move(onAnimationStart));
992 }
993 
SetOnAnimationEnd(const JSCallbackInfo & info)994 void JSSwiper::SetOnAnimationEnd(const JSCallbackInfo& info)
995 {
996     if (!info[0]->IsFunction()) {
997         return;
998     }
999 
1000     if (Container::IsCurrentUseNewPipeline()) {
1001         auto animationEndHandler = AceType::MakeRefPtr<JsSwiperFunction>(JSRef<JSFunc>::Cast(info[0]));
1002         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1003         auto onAnimationEnd = [executionContext = info.GetExecutionContext(), func = std::move(animationEndHandler),
1004                                   node = targetNode](int32_t index, const AnimationCallbackInfo& info) {
1005             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
1006             ACE_SCORING_EVENT("Swiper.onAnimationEnd");
1007             PipelineContext::SetCallBackNode(node);
1008             func->Execute(index, info);
1009         };
1010 
1011         SwiperModel::GetInstance()->SetOnAnimationEnd(std::move(onAnimationEnd));
1012         return;
1013     }
1014 
1015     auto animationEndHandler = AceType::MakeRefPtr<JsEventFunction<SwiperChangeEvent, 1>>(
1016         JSRef<JSFunc>::Cast(info[0]), SwiperChangeEventToJSValue);
1017     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1018     auto onAnimationEnd = [executionContext = info.GetExecutionContext(), func = std::move(animationEndHandler),
1019                               node = targetNode](const BaseEventInfo* info) {
1020         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
1021         const auto* swiperInfo = TypeInfoHelper::DynamicCast<SwiperChangeEvent>(info);
1022         if (!swiperInfo) {
1023             TAG_LOGW(AceLogTag::ACE_SWIPER, "Swiper onAnimationEnd callback execute failed.");
1024             return;
1025         }
1026         ACE_SCORING_EVENT("Swiper.onAnimationEnd");
1027         PipelineContext::SetCallBackNode(node);
1028         func->Execute(*swiperInfo);
1029     };
1030 
1031     SwiperModel::GetInstance()->SetOnAnimationEnd(std::move(onAnimationEnd));
1032 }
1033 
SetOnGestureSwipe(const JSCallbackInfo & info)1034 void JSSwiper::SetOnGestureSwipe(const JSCallbackInfo& info)
1035 {
1036     if (!info[0]->IsFunction()) {
1037         return;
1038     }
1039 
1040     auto gestureSwipeHandler = AceType::MakeRefPtr<JsSwiperFunction>(JSRef<JSFunc>::Cast(info[0]));
1041     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1042     auto onGestureSwipe = [executionContext = info.GetExecutionContext(), func = std::move(gestureSwipeHandler),
1043                               node = targetNode](int32_t index, const AnimationCallbackInfo& info) {
1044         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
1045         ACE_SCORING_EVENT("Swiper.onGestureSwipe");
1046         PipelineContext::SetCallBackNode(node);
1047         func->Execute(index, info);
1048     };
1049 
1050     SwiperModel::GetInstance()->SetOnGestureSwipe(std::move(onGestureSwipe));
1051 }
1052 
SetOnClick(const JSCallbackInfo & info)1053 void JSSwiper::SetOnClick(const JSCallbackInfo& info)
1054 {
1055     if (Container::IsCurrentUseNewPipeline()) {
1056         JSInteractableView::JsOnClick(info);
1057         return;
1058     }
1059 
1060     if (!info[0]->IsFunction()) {
1061         return;
1062     }
1063 
1064     RefPtr<JsClickFunction> jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
1065     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1066     auto onClick = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc), node = targetNode](
1067                        const BaseEventInfo* info, const RefPtr<V2::InspectorFunctionImpl>& impl) {
1068         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1069         const auto* clickInfo = TypeInfoHelper::DynamicCast<ClickInfo>(info);
1070         auto newInfo = *clickInfo;
1071         if (impl) {
1072             impl->UpdateEventInfo(newInfo);
1073         }
1074         ACE_SCORING_EVENT("onClick");
1075         PipelineContext::SetCallBackNode(node);
1076         func->Execute(newInfo);
1077     };
1078 
1079     SwiperModel::GetInstance()->SetOnClick(onClick);
1080 }
1081 
SetWidth(const JSCallbackInfo & info)1082 void JSSwiper::SetWidth(const JSCallbackInfo& info)
1083 {
1084     if (info.Length() < 1) {
1085         return;
1086     }
1087 
1088     SetWidth(info[0]);
1089 }
1090 
SetWidth(const JSRef<JSVal> & jsValue)1091 void JSSwiper::SetWidth(const JSRef<JSVal>& jsValue)
1092 {
1093     if (Container::IsCurrentUseNewPipeline()) {
1094         JSViewAbstract::JsWidth(jsValue);
1095         return;
1096     }
1097 
1098     JSViewAbstract::JsWidth(jsValue);
1099     SwiperModel::GetInstance()->SetMainSwiperSizeWidth();
1100 }
1101 
SetHeight(const JSRef<JSVal> & jsValue)1102 void JSSwiper::SetHeight(const JSRef<JSVal>& jsValue)
1103 {
1104     if (Container::IsCurrentUseNewPipeline()) {
1105         JSViewAbstract::JsHeight(jsValue);
1106         return;
1107     }
1108 
1109     JSViewAbstract::JsHeight(jsValue);
1110     SwiperModel::GetInstance()->SetMainSwiperSizeHeight();
1111 }
1112 
SetHeight(const JSCallbackInfo & info)1113 void JSSwiper::SetHeight(const JSCallbackInfo& info)
1114 {
1115     if (info.Length() < 1) {
1116         return;
1117     }
1118 
1119     SetHeight(info[0]);
1120 }
1121 
SetSize(const JSCallbackInfo & info)1122 void JSSwiper::SetSize(const JSCallbackInfo& info)
1123 {
1124     if (info.Length() < 1) {
1125         return;
1126     }
1127 
1128     if (!info[0]->IsObject()) {
1129         return;
1130     }
1131 
1132     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
1133     SetWidth(sizeObj->GetProperty("width"));
1134     SetHeight(sizeObj->GetProperty("height"));
1135 }
1136 
JSBind(BindingTarget globalObj)1137 void JSSwiperController::JSBind(BindingTarget globalObj)
1138 {
1139     JSClass<JSSwiperController>::Declare("SwiperController");
1140     JSClass<JSSwiperController>::CustomMethod("swipeTo", &JSSwiperController::SwipeTo);
1141     JSClass<JSSwiperController>::CustomMethod("showNext", &JSSwiperController::ShowNext);
1142     JSClass<JSSwiperController>::CustomMethod("showPrevious", &JSSwiperController::ShowPrevious);
1143     JSClass<JSSwiperController>::CustomMethod("changeIndex", &JSSwiperController::ChangeIndex);
1144     JSClass<JSSwiperController>::CustomMethod("finishAnimation", &JSSwiperController::FinishAnimation);
1145     JSClass<JSSwiperController>::CustomMethod("preloadItems", &JSSwiperController::PreloadItems);
1146     JSClass<JSSwiperController>::Bind(globalObj, JSSwiperController::Constructor, JSSwiperController::Destructor);
1147 }
1148 
Constructor(const JSCallbackInfo & args)1149 void JSSwiperController::Constructor(const JSCallbackInfo& args)
1150 {
1151     auto scroller = Referenced::MakeRefPtr<JSSwiperController>();
1152     scroller->IncRefCount();
1153     args.SetReturnValue(Referenced::RawPtr(scroller));
1154 }
1155 
Destructor(JSSwiperController * scroller)1156 void JSSwiperController::Destructor(JSSwiperController* scroller)
1157 {
1158     if (scroller != nullptr) {
1159         scroller->DecRefCount();
1160     }
1161 }
1162 
ChangeIndex(const JSCallbackInfo & args)1163 void JSSwiperController::ChangeIndex(const JSCallbackInfo& args)
1164 {
1165     if (!controller_) {
1166         return;
1167     }
1168     if (args.Length() < 1 || !args[0]->IsNumber()) {
1169         return;
1170     }
1171     int32_t index = args[0]->ToNumber<int32_t>();
1172     if (args.Length() > 1 && args[1]->IsNumber()) {
1173         int32_t animationMode = args[1]->ToNumber<int32_t>();
1174         if (animationMode < 0 || animationMode >= static_cast<int32_t>(SWIPER_ANIMATION_MODE.size())) {
1175             animationMode = 0;
1176         }
1177         controller_->ChangeIndex(index, SWIPER_ANIMATION_MODE[animationMode]);
1178         return;
1179     }
1180     bool useAnimation = false;
1181     if (args.Length() > 1 && args[1]->IsBoolean()) {
1182         useAnimation = args[1]->ToBoolean();
1183     }
1184     controller_->ChangeIndex(index, useAnimation);
1185 }
1186 
FinishAnimation(const JSCallbackInfo & args)1187 void JSSwiperController::FinishAnimation(const JSCallbackInfo& args)
1188 {
1189     ContainerScope scope(instanceId_);
1190     if (!controller_) {
1191         return;
1192     }
1193 
1194     if (args.Length() > 0 && args[0]->IsFunction()) {
1195         RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(args[0]));
1196         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1197         auto onFinish = [execCtx = args.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1198             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1199             ACE_SCORING_EVENT("Swiper.finishAnimation");
1200             PipelineContext::SetCallBackNode(node);
1201             func->Execute();
1202         };
1203 
1204         controller_->SetFinishCallback(onFinish);
1205         controller_->FinishAnimation();
1206         return;
1207     }
1208 
1209     controller_->FinishAnimation();
1210 }
1211 
PreloadItems(const JSCallbackInfo & args)1212 void JSSwiperController::PreloadItems(const JSCallbackInfo& args)
1213 {
1214     ContainerScope scope(instanceId_);
1215     if (!controller_) {
1216         return;
1217     }
1218 
1219     if (args.Length() != 2 || !args[0]->IsArray() || !args[1]->IsFunction()) {
1220         return;
1221     }
1222 
1223     auto indexArray = JSRef<JSArray>::Cast(args[0]);
1224     size_t size = indexArray->Length();
1225     std::set<int32_t> indexSet;
1226     for (size_t i = 0; i < size; i++) {
1227         int32_t index = -1;
1228         JSViewAbstract::ParseJsInt32(indexArray->GetValueAt(i), index);
1229         indexSet.emplace(index);
1230     }
1231 
1232     RefPtr<JsSwiperFunction> jsFunc = AceType::MakeRefPtr<JsSwiperFunction>(JSRef<JSFunc>::Cast(args[1]));
1233     auto onPreloadFinish =
1234         [execCtx = args.GetExecutionContext(), func = std::move(jsFunc)](int32_t errorCode, std::string message) {
1235             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1236             ACE_SCORING_EVENT("Swiper.preloadItems");
1237             TAG_LOGD(AceLogTag::ACE_SWIPER, "SwiperController preloadItems callback execute.");
1238             func->Execute(errorCode);
1239         };
1240 
1241     controller_->SetPreloadFinishCallback(onPreloadFinish);
1242     controller_->PreloadItems(indexSet);
1243 }
1244 
SetNestedScroll(const JSCallbackInfo & args)1245 void JSSwiper::SetNestedScroll(const JSCallbackInfo& args)
1246 {
1247     // default value
1248     NestedScrollOptions nestedOpt = {
1249         .forward = NestedScrollMode::SELF_ONLY,
1250         .backward = NestedScrollMode::SELF_ONLY,
1251     };
1252     if (args.Length() < 1 || !args[0]->IsNumber()) {
1253         SwiperModel::GetInstance()->SetNestedScroll(nestedOpt);
1254         return;
1255     }
1256     int32_t value = -1;
1257     JSViewAbstract::ParseJsInt32(args[0], value);
1258     auto mode = static_cast<NestedScrollMode>(value);
1259     if (mode < NestedScrollMode::SELF_ONLY || mode > NestedScrollMode::SELF_FIRST) {
1260         SwiperModel::GetInstance()->SetNestedScroll(nestedOpt);
1261         return;
1262     }
1263     nestedOpt.forward = mode;
1264     nestedOpt.backward = mode;
1265     SwiperModel::GetInstance()->SetNestedScroll(nestedOpt);
1266     args.ReturnSelf();
1267 }
1268 
SetCustomContentTransition(const JSCallbackInfo & info)1269 void JSSwiper::SetCustomContentTransition(const JSCallbackInfo& info)
1270 {
1271     if (info.Length() < 1 || !info[0]->IsObject()) {
1272         return;
1273     }
1274 
1275     SwiperContentAnimatedTransition transitionInfo;
1276     auto transitionObj = JSRef<JSObject>::Cast(info[0]);
1277     JSRef<JSVal> timeoutProperty = transitionObj->GetProperty("timeout");
1278     if (timeoutProperty->IsNumber()) {
1279         auto timeout = timeoutProperty->ToNumber<int32_t>();
1280         transitionInfo.timeout = timeout < 0 ? DEFAULT_CUSTOM_ANIMATION_TIMEOUT : timeout;
1281     } else {
1282         transitionInfo.timeout = DEFAULT_CUSTOM_ANIMATION_TIMEOUT;
1283     }
1284 
1285     JSRef<JSVal> transition = transitionObj->GetProperty("transition");
1286     if (transition->IsFunction()) {
1287         auto jsOnTransition = AceType::MakeRefPtr<JsSwiperFunction>(JSRef<JSFunc>::Cast(transition));
1288         auto onTransition = [execCtx = info.GetExecutionContext(), func = std::move(jsOnTransition)](
1289                                 const RefPtr<SwiperContentTransitionProxy>& proxy) {
1290             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1291             ACE_SCORING_EVENT("Swiper.customContentTransition");
1292             func->Execute(proxy);
1293         };
1294         transitionInfo.transition = std::move(onTransition);
1295     }
1296     SwiperModel::GetInstance()->SetCustomContentTransition(transitionInfo);
1297 }
1298 
SetOnContentDidScroll(const JSCallbackInfo & info)1299 void JSSwiper::SetOnContentDidScroll(const JSCallbackInfo& info)
1300 {
1301     if (info.Length() < 1 || !info[0]->IsFunction()) {
1302         return;
1303     }
1304 
1305     auto contentDidScrollHandler = AceType::MakeRefPtr<JsSwiperFunction>(JSRef<JSFunc>::Cast(info[0]));
1306     auto onContentDidScroll = [execCtx = info.GetExecutionContext(),
1307                                 func = std::move(contentDidScrollHandler)](
1308                                 int32_t selectedIndex, int32_t index, float position, float mainAxisLength) {
1309         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1310         ACE_SCORING_EVENT("Swiper.onContentDidScroll");
1311         func->Execute(selectedIndex, index, position, mainAxisLength);
1312     };
1313     SwiperModel::GetInstance()->SetOnContentDidScroll(std::move(onContentDidScroll));
1314 }
1315 
SetPageFlipMode(const JSCallbackInfo & info)1316 void JSSwiper::SetPageFlipMode(const JSCallbackInfo& info)
1317 {
1318     // default value
1319     int32_t value = 0;
1320     if (info.Length() < 1 || !info[0]->IsNumber()) {
1321         SwiperModel::GetInstance()->SetPageFlipMode(value);
1322         return;
1323     }
1324     JSViewAbstract::ParseJsInt32(info[0], value);
1325     SwiperModel::GetInstance()->SetPageFlipMode(value);
1326 }
1327 
SetOnContentWillScroll(const JSCallbackInfo & info)1328 void JSSwiper::SetOnContentWillScroll(const JSCallbackInfo& info)
1329 {
1330     if (info.Length() < 1) {
1331         return;
1332     }
1333 
1334     if (info[0]->IsUndefined() || info[0]->IsNull()) {
1335         SwiperModel::GetInstance()->SetOnContentWillScroll(nullptr);
1336         return;
1337     }
1338 
1339     if (!info[0]->IsFunction()) {
1340         return;
1341     }
1342 
1343     auto handler = AceType::MakeRefPtr<JsSwiperFunction>(JSRef<JSFunc>::Cast(info[0]));
1344     auto callback = [execCtx = info.GetExecutionContext(), func = std::move(handler)](
1345                         const SwiperContentWillScrollResult& result) -> bool {
1346         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, true);
1347         ACE_SCORING_EVENT("Swiper.onContentWillScroll");
1348         auto ret = func->Execute(result);
1349         if (!ret->IsBoolean()) {
1350             return true;
1351         }
1352         return ret->ToBoolean();
1353     };
1354     SwiperModel::GetInstance()->SetOnContentWillScroll(std::move(callback));
1355 }
1356 } // namespace OHOS::Ace::Framework
1357