• 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/log/event_report.h"
24 #include "base/utils/utils.h"
25 #include "bridge/common/utils/engine_helper.h"
26 #include "bridge/common/utils/utils.h"
27 #include "bridge/declarative_frontend/ark_theme/theme_apply/js_swiper_theme.h"
28 #include "bridge/declarative_frontend/ark_theme/theme_apply/js_theme_utils.h"
29 #include "bridge/declarative_frontend/engine/functions/js_click_function.h"
30 #include "bridge/declarative_frontend/engine/functions/js_event_function.h"
31 #include "bridge/declarative_frontend/engine/functions/js_swiper_function.h"
32 #include "bridge/declarative_frontend/engine/js_converter.h"
33 #include "bridge/declarative_frontend/engine/jsi/js_ui_index.h"
34 #include "bridge/declarative_frontend/jsview/js_indicator.h"
35 #include "bridge/declarative_frontend/jsview/js_utils.h"
36 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
37 #include "bridge/declarative_frontend/jsview/models/swiper_model_impl.h"
38 #include "bridge/declarative_frontend/view_stack_processor.h"
39 #include "bridge/js_frontend/engine/jsi/js_value.h"
40 #include "core/animation/curve.h"
41 #include "core/components/common/layout/constants.h"
42 #include "core/components/common/properties/scroll_bar.h"
43 #include "core/components/swiper/swiper_component.h"
44 #include "core/components/swiper/swiper_indicator_theme.h"
45 #include "core/components_ng/base/view_stack_processor.h"
46 #include "core/components_ng/pattern/scrollable/scrollable_properties.h"
47 #include "core/components_ng/pattern/swiper/swiper_content_transition_proxy.h"
48 #include "core/components_ng/pattern/swiper/swiper_model.h"
49 #include "core/components_ng/pattern/swiper/swiper_model_ng.h"
50 
51 namespace OHOS::Ace {
52 namespace {
53 constexpr float ARROW_SIZE_COEFFICIENT = 0.75f;
54 constexpr int32_t DEFAULT_CUSTOM_ANIMATION_TIMEOUT = 0;
55 const auto DEFAULT_CURVE = AceType::MakeRefPtr<InterpolatingSpring>(-1, 1, 328, 34);
56 constexpr int32_t LENGTH_TWO = 2;
57 } // namespace
58 std::unique_ptr<SwiperModel> SwiperModel::instance_ = nullptr;
59 std::mutex SwiperModel::mutex_;
60 
GetInstance()61 SwiperModel* SwiperModel::GetInstance()
62 {
63     if (!instance_) {
64         std::lock_guard<std::mutex> lock(mutex_);
65         if (!instance_) {
66 #ifdef NG_BUILD
67             instance_.reset(new NG::SwiperModelNG());
68 #else
69             if (Container::IsCurrentUseNewPipeline()) {
70                 instance_.reset(new NG::SwiperModelNG());
71             } else {
72                 instance_.reset(new Framework::SwiperModelImpl());
73             }
74 #endif
75         }
76     }
77     return instance_.get();
78 }
79 
80 } // namespace OHOS::Ace
81 namespace OHOS::Ace::Framework {
82 namespace {
83 
84 const std::vector<EdgeEffect> EDGE_EFFECT = { EdgeEffect::SPRING, EdgeEffect::FADE, EdgeEffect::NONE };
85 const std::vector<SwiperDisplayMode> DISPLAY_MODE = { SwiperDisplayMode::STRETCH, SwiperDisplayMode::AUTO_LINEAR };
86 const std::vector<SwiperIndicatorType> INDICATOR_TYPE = { SwiperIndicatorType::DOT, SwiperIndicatorType::DIGIT };
87 const std::vector<SwiperAnimationMode> SWIPER_ANIMATION_MODE = { SwiperAnimationMode::NO_ANIMATION,
88     SwiperAnimationMode::DEFAULT_ANIMATION, SwiperAnimationMode::FAST_ANIMATION };
89 const static int32_t DEFAULT_INTERVAL = 3000;
90 const static int32_t DEFAULT_DURATION = 400;
91 const static int32_t DEFAULT_DISPLAY_COUNT = 1;
92 const static int32_t DEFAULT_CACHED_COUNT = 1;
93 
SwiperChangeEventToJSValue(const SwiperChangeEvent & eventInfo)94 JSRef<JSVal> SwiperChangeEventToJSValue(const SwiperChangeEvent& eventInfo)
95 {
96     return JSRef<JSVal>::Make(ToJSValue(eventInfo.GetIndex()));
97 }
98 
99 struct SwiperControllerAsyncContext {
100     napi_env env = nullptr;
101     napi_deferred deferred = nullptr;
102 };
103 
CreateErrorValue(napi_env env,int32_t errCode,const std::string & errMsg="")104 napi_value CreateErrorValue(napi_env env, int32_t errCode, const std::string& errMsg = "")
105 {
106     napi_value code = nullptr;
107     std::string codeStr = std::to_string(errCode);
108     napi_create_string_utf8(env, codeStr.c_str(), codeStr.length(), &code);
109     napi_value msg = nullptr;
110     napi_create_string_utf8(env, errMsg.c_str(), errMsg.length(), &msg);
111     napi_value error = nullptr;
112     napi_create_error(env, code, msg, &error);
113     return error;
114 }
115 
HandleDeferred(const shared_ptr<SwiperControllerAsyncContext> & asyncContext,int32_t errorCode,std::string message)116 void HandleDeferred(
117     const shared_ptr<SwiperControllerAsyncContext>& asyncContext, int32_t errorCode, std::string message)
118 {
119     auto env = asyncContext->env;
120     CHECK_NULL_VOID(env);
121     auto deferred = asyncContext->deferred;
122     CHECK_NULL_VOID(deferred);
123 
124     napi_handle_scope scope = nullptr;
125     auto status = napi_open_handle_scope(env, &scope);
126     if (status != napi_ok) {
127         return;
128     }
129 
130     napi_value result = nullptr;
131     if (errorCode == ERROR_CODE_NO_ERROR) {
132         napi_get_null(env, &result);
133         napi_resolve_deferred(env, deferred, result);
134     } else {
135         result = CreateErrorValue(env, errorCode, message);
136         napi_reject_deferred(env, deferred, result);
137     }
138     napi_close_handle_scope(env, scope);
139 }
140 
ReturnPromise(const JSCallbackInfo & info,napi_value result)141 void ReturnPromise(const JSCallbackInfo& info, napi_value result)
142 {
143     CHECK_NULL_VOID(result);
144     auto jsPromise = JsConverter::ConvertNapiValueToJsVal(result);
145     if (!jsPromise->IsObject()) {
146         return;
147     }
148     info.SetReturnValue(JSRef<JSObject>::Cast(jsPromise));
149 }
150 } // namespace
151 
Create(const JSCallbackInfo & info)152 void JSSwiper::Create(const JSCallbackInfo& info)
153 {
154     auto controller = SwiperModel::GetInstance()->Create();
155 
156     if (info.Length() > 0 && info[0]->IsObject()) {
157         auto* jsController = JSRef<JSObject>::Cast(info[0])->Unwrap<JSSwiperController>();
158         if (jsController) {
159             jsController->SetInstanceId(Container::CurrentId());
160             jsController->SetController(controller);
161         }
162     }
163 
164     JSSwiperTheme::ApplyThemeInConstructor();
165 }
166 
JsRemoteMessage(const JSCallbackInfo & info)167 void JSSwiper::JsRemoteMessage(const JSCallbackInfo& info)
168 {
169     RemoteCallback remoteCallback;
170     JSInteractableView::JsRemoteMessage(info, remoteCallback);
171 
172     SwiperModel::GetInstance()->SetRemoteMessageEventId(std::move(remoteCallback));
173 }
174 
JSBind(BindingTarget globalObj)175 void JSSwiper::JSBind(BindingTarget globalObj)
176 {
177     JsSwiperContentTransitionProxy::JSBind(globalObj);
178     JSClass<JSSwiper>::Declare("Swiper");
179     MethodOptions opt = MethodOptions::NONE;
180     JSClass<JSSwiper>::StaticMethod("create", &JSSwiper::Create, opt);
181     JSClass<JSSwiper>::StaticMethod("indicatorInteractive", &JSSwiper::SetIndicatorInteractive, opt);
182     JSClass<JSSwiper>::StaticMethod("autoPlay", &JSSwiper::SetAutoPlay, opt);
183     JSClass<JSSwiper>::StaticMethod("duration", &JSSwiper::SetDuration, opt);
184     JSClass<JSSwiper>::StaticMethod("index", &JSSwiper::SetIndex, opt);
185     JSClass<JSSwiper>::StaticMethod("interval", &JSSwiper::SetInterval, opt);
186     JSClass<JSSwiper>::StaticMethod("loop", &JSSwiper::SetLoop, opt);
187     JSClass<JSSwiper>::StaticMethod("vertical", &JSSwiper::SetVertical, opt);
188     JSClass<JSSwiper>::StaticMethod("indicator", &JSSwiper::SetIndicator, opt);
189     JSClass<JSSwiper>::StaticMethod("displayMode", &JSSwiper::SetDisplayMode);
190     JSClass<JSSwiper>::StaticMethod("effectMode", &JSSwiper::SetEffectMode);
191     JSClass<JSSwiper>::StaticMethod("displayCount", &JSSwiper::SetDisplayCount);
192     JSClass<JSSwiper>::StaticMethod("itemSpace", &JSSwiper::SetItemSpace);
193     JSClass<JSSwiper>::StaticMethod("prevMargin", &JSSwiper::SetPreviousMargin);
194     JSClass<JSSwiper>::StaticMethod("nextMargin", &JSSwiper::SetNextMargin);
195     JSClass<JSSwiper>::StaticMethod("cachedCount", &JSSwiper::SetCachedCount);
196     JSClass<JSSwiper>::StaticMethod("curve", &JSSwiper::SetCurve);
197     JSClass<JSSwiper>::StaticMethod("onChange", &JSSwiper::SetOnChange);
198     JSClass<JSSwiper>::StaticMethod("onUnselected", &JSSwiper::SetOnUnselected);
199     JSClass<JSSwiper>::StaticMethod("onAnimationStart", &JSSwiper::SetOnAnimationStart);
200     JSClass<JSSwiper>::StaticMethod("onAnimationEnd", &JSSwiper::SetOnAnimationEnd);
201     JSClass<JSSwiper>::StaticMethod("onGestureSwipe", &JSSwiper::SetOnGestureSwipe);
202     JSClass<JSSwiper>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
203     JSClass<JSSwiper>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
204     JSClass<JSSwiper>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
205     JSClass<JSSwiper>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
206     JSClass<JSSwiper>::StaticMethod("remoteMessage", &JSSwiper::JsRemoteMessage);
207     JSClass<JSSwiper>::StaticMethod("onClick", &JSSwiper::SetOnClick);
208     JSClass<JSSwiper>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
209     JSClass<JSSwiper>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
210     JSClass<JSSwiper>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
211     JSClass<JSSwiper>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
212     JSClass<JSSwiper>::StaticMethod("indicatorStyle", &JSSwiper::SetIndicatorStyle);
213     JSClass<JSSwiper>::StaticMethod("enabled", &JSSwiper::SetEnabled);
214     JSClass<JSSwiper>::StaticMethod("disableSwipe", &JSSwiper::SetDisableSwipe);
215     JSClass<JSSwiper>::StaticMethod("height", &JSSwiper::SetHeight);
216     JSClass<JSSwiper>::StaticMethod("width", &JSSwiper::SetWidth);
217     JSClass<JSSwiper>::StaticMethod("size", &JSSwiper::SetSize);
218     JSClass<JSSwiper>::StaticMethod("displayArrow", &JSSwiper::SetDisplayArrow);
219     JSClass<JSSwiper>::StaticMethod("nestedScroll", &JSSwiper::SetNestedScroll);
220     JSClass<JSSwiper>::StaticMethod("customContentTransition", &JSSwiper::SetCustomContentTransition);
221     JSClass<JSSwiper>::StaticMethod("onContentDidScroll", &JSSwiper::SetOnContentDidScroll);
222     JSClass<JSSwiper>::StaticMethod("pageFlipMode", &JSSwiper::SetPageFlipMode);
223     JSClass<JSSwiper>::StaticMethod("onContentWillScroll", &JSSwiper::SetOnContentWillScroll);
224     JSClass<JSSwiper>::StaticMethod("onSelected", &JSSwiper::SetOnSelected);
225     JSClass<JSSwiper>::StaticMethod("maintainVisibleContentPosition", &JSSwiper::SetMaintainVisibleContentPosition);
226     JSClass<JSSwiper>::StaticMethod("onScrollStateChanged", &JSSwiper::SetOnScrollStateChanged);
227     JSClass<JSSwiper>::InheritAndBind<JSContainerBase>(globalObj);
228 }
229 
SetIndicatorInteractive(const JSCallbackInfo & info)230 void JSSwiper::SetIndicatorInteractive(const JSCallbackInfo& info)
231 {
232     if (info.Length() < 1) {
233         return;
234     }
235 
236     if (info[0]->IsBoolean()) {
237         SwiperModel::GetInstance()->SetIndicatorInteractive(info[0]->ToBoolean());
238     } else {
239         SwiperModel::GetInstance()->SetIndicatorInteractive(true);
240     }
241 }
242 
SetAutoPlay(const JSCallbackInfo & info)243 void JSSwiper::SetAutoPlay(const JSCallbackInfo& info)
244 {
245     if (info.Length() < 1) {
246         return;
247     }
248     bool autoPlay = false;
249     if (info[0]->IsBoolean()) {
250         autoPlay = info[0]->ToBoolean();
251     }
252     SwiperModel::GetInstance()->SetAutoPlay(autoPlay);
253     SwiperAutoPlayOptions swiperAutoPlayOptions;
254     if (info.Length() > 1 && info[1]->IsObject()) {
255         auto obj = JSRef<JSObject>::Cast(info[1]);
256         GetAutoPlayOptionsInfo(obj, swiperAutoPlayOptions);
257     }
258 
259     SwiperModel::GetInstance()->SetAutoPlayOptions(swiperAutoPlayOptions);
260 }
261 
SetEnabled(const JSCallbackInfo & info)262 void JSSwiper::SetEnabled(const JSCallbackInfo& info)
263 {
264     JSViewAbstract::JsEnabled(info);
265     if (info.Length() < 1) {
266         return;
267     }
268 
269     if (!info[0]->IsBoolean()) {
270         return;
271     }
272 
273     SwiperModel::GetInstance()->SetEnabled(info[0]->ToBoolean());
274 }
275 
SetDisableSwipe(bool disableSwipe)276 void JSSwiper::SetDisableSwipe(bool disableSwipe)
277 {
278     SwiperModel::GetInstance()->SetDisableSwipe(disableSwipe);
279 }
280 
SetEffectMode(const JSCallbackInfo & info)281 void JSSwiper::SetEffectMode(const JSCallbackInfo& info)
282 {
283     if (info.Length() < 1) {
284         return;
285     }
286 
287     if (!info[0]->IsNumber()) {
288         return;
289     }
290 
291     auto edgeEffect = info[0]->ToNumber<int32_t>();
292     if (edgeEffect < 0 || edgeEffect >= static_cast<int32_t>(EDGE_EFFECT.size())) {
293         return;
294     }
295 
296     SwiperModel::GetInstance()->SetEdgeEffect(EDGE_EFFECT[edgeEffect]);
297 }
298 
SetDisplayCount(const JSCallbackInfo & info)299 void JSSwiper::SetDisplayCount(const JSCallbackInfo& info)
300 {
301     if (info.Length() < 1) {
302         return;
303     }
304 
305     if (info.Length() == 2) {
306         if (info[1]->IsBoolean()) {
307             SwiperModel::GetInstance()->SetSwipeByGroup(info[1]->ToBoolean());
308         } else {
309             SwiperModel::GetInstance()->SetSwipeByGroup(false);
310         }
311     }
312 
313     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
314         if (info[0]->IsString() && info[0]->ToString() == "auto") {
315             SwiperModel::GetInstance()->SetDisplayMode(SwiperDisplayMode::AUTO_LINEAR);
316             SwiperModel::GetInstance()->ResetDisplayCount();
317             SwiperModel::GetInstance()->ResetMinSize();
318         } else if (info[0]->IsNumber() && info[0]->ToNumber<int32_t>() > 0) {
319             SwiperModel::GetInstance()->SetDisplayCount(info[0]->ToNumber<int32_t>());
320         } else if (info[0]->IsObject()) {
321             JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
322             auto minSizeParam = jsObj->GetProperty("minSize");
323             if (minSizeParam->IsNull()) {
324                 return;
325             }
326             CalcDimension minSizeValue;
327             if (!ParseJsDimensionVp(minSizeParam, minSizeValue)) {
328                 SwiperModel::GetInstance()->SetMinSize(0.0_vp);
329                 return;
330             }
331             SwiperModel::GetInstance()->SetMinSize(minSizeValue);
332             SwiperModel::GetInstance()->ResetDisplayCount();
333             SwiperModel::GetInstance()->ResetDisplayMode();
334         } else {
335             SwiperModel::GetInstance()->SetDisplayCount(DEFAULT_DISPLAY_COUNT);
336         }
337 
338         return;
339     }
340 
341     if (info[0]->IsString() && info[0]->ToString() == "auto") {
342         SwiperModel::GetInstance()->SetDisplayMode(SwiperDisplayMode::AUTO_LINEAR);
343         SwiperModel::GetInstance()->ResetDisplayCount();
344     } else if (info[0]->IsNumber()) {
345         SwiperModel::GetInstance()->SetDisplayCount(info[0]->ToNumber<int32_t>());
346     }
347 }
348 
SetDuration(const JSCallbackInfo & info)349 void JSSwiper::SetDuration(const JSCallbackInfo& info)
350 {
351     int32_t duration = DEFAULT_DURATION;
352 
353     if (info.Length() < 1) { // user do not set any value
354         return;
355     }
356 
357     // undefined value turn to default 400
358     if (!info[0]->IsUndefined() && info[0]->IsNumber()) {
359         duration = info[0]->ToNumber<int32_t>();
360         if (duration < 0) {
361             duration = DEFAULT_DURATION;
362         }
363     }
364 
365     SwiperModel::GetInstance()->SetDuration(duration);
366 }
367 
ParseSwiperIndexObject(const JSCallbackInfo & args,const JSRef<JSVal> & changeEventVal)368 void ParseSwiperIndexObject(const JSCallbackInfo& args, const JSRef<JSVal>& changeEventVal)
369 {
370     CHECK_NULL_VOID(changeEventVal->IsFunction());
371 
372     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
373     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
374     auto onIndex = [execCtx = args.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
375                        const BaseEventInfo* info) {
376         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
377         ACE_SCORING_EVENT("Swiper.onChangeEvent");
378         PipelineContext::SetCallBackNode(node);
379         const auto* swiperInfo = TypeInfoHelper::DynamicCast<SwiperChangeEvent>(info);
380         if (!swiperInfo) {
381             return;
382         }
383         auto newJSVal = JSRef<JSVal>::Make(ToJSValue(swiperInfo->GetIndex()));
384         func->ExecuteJS(1, &newJSVal);
385     };
386     SwiperModel::GetInstance()->SetOnChangeEvent(std::move(onIndex));
387 }
388 
SetIndex(const JSCallbackInfo & info)389 void JSSwiper::SetIndex(const JSCallbackInfo& info)
390 {
391     auto length = info.Length();
392     if (length < 1 || length > 2) {
393         return;
394     }
395     int32_t index = 0;
396     auto jsIndex = info[0];
397     if (jsIndex->IsObject()) {
398         JSRef<JSObject> obj = JSRef<JSObject>::Cast(jsIndex);
399         jsIndex = obj->GetProperty("value");
400         auto changeEventVal = obj->GetProperty("$value");
401         ParseSwiperIndexObject(info, changeEventVal);
402     }
403 
404     if (length > 0 && jsIndex->IsNumber()) {
405         index = jsIndex->ToNumber<int32_t>();
406     }
407 
408     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
409         index = index < 0 ? 0 : index;
410     }
411 
412     if (index < 0) {
413         return;
414     }
415     SwiperModel::GetInstance()->SetIndex(index);
416 
417     if (length > 1 && info[1]->IsFunction()) {
418         ParseSwiperIndexObject(info, info[1]);
419     }
420 }
421 
SetInterval(const JSCallbackInfo & info)422 void JSSwiper::SetInterval(const JSCallbackInfo& info)
423 {
424     int32_t interval = DEFAULT_INTERVAL;
425 
426     if (info.Length() < 1) { // user do not set any value
427         return;
428     }
429 
430     // undefined value turn to default 3000
431     if (!info[0]->IsUndefined() && info[0]->IsNumber()) {
432         interval = info[0]->ToNumber<int32_t>();
433         if (interval < 0) {
434             interval = DEFAULT_INTERVAL;
435         }
436     }
437 
438     SwiperModel::GetInstance()->SetAutoPlayInterval(interval);
439 }
440 
SetLoop(const JSCallbackInfo & info)441 void JSSwiper::SetLoop(const JSCallbackInfo& info)
442 {
443     if (info.Length() < 1) {
444         return;
445     }
446 
447     if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
448         SwiperModel::GetInstance()->SetLoop(info[0]->ToBoolean());
449         return;
450     }
451 
452     if (info[0]->IsBoolean()) {
453         SwiperModel::GetInstance()->SetLoop(info[0]->ToBoolean());
454     } else {
455         SwiperModel::GetInstance()->SetLoop(true);
456     }
457 }
458 
SetVertical(bool isVertical)459 void JSSwiper::SetVertical(bool isVertical)
460 {
461     SwiperModel::GetInstance()->SetDirection(isVertical ? Axis::VERTICAL : Axis::HORIZONTAL);
462 }
463 
GetFontContent(const JSRef<JSVal> & font,bool isSelected,SwiperDigitalParameters & digitalParameters)464 void JSSwiper::GetFontContent(const JSRef<JSVal>& font, bool isSelected, SwiperDigitalParameters& digitalParameters)
465 {
466     JSRef<JSObject> obj = JSRef<JSObject>::Cast(font);
467     JSRef<JSVal> size = obj->GetProperty("size");
468     auto pipelineContext = PipelineBase::GetCurrentContext();
469     CHECK_NULL_VOID(pipelineContext);
470     auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
471     CHECK_NULL_VOID(swiperIndicatorTheme);
472     // set font size, unit FP
473     CalcDimension fontSize;
474     RefPtr<ResourceObject> resObj;
475     if (!size->IsUndefined() && !size->IsNull() && ParseJsDimensionFp(size, fontSize, resObj)) {
476         if (LessOrEqual(fontSize.Value(), 0.0) || LessOrEqual(size->ToNumber<double>(), 0.0) ||
477             fontSize.Unit() == DimensionUnit::PERCENT) {
478             fontSize = swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetFontSize();
479         }
480     } else {
481         fontSize = swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetFontSize();
482     }
483     if (SystemProperties::ConfigChangePerform()) {
484         if (isSelected) {
485             digitalParameters.resourceSelectedFontSizeValueObject = resObj;
486         } else {
487             digitalParameters.resourceFontSizeValueObject = resObj;
488         }
489     }
490     if (isSelected) {
491         digitalParameters.selectedFontSize = fontSize;
492     } else {
493         digitalParameters.fontSize = fontSize;
494     }
495     JSRef<JSVal> weight = obj->GetProperty("weight");
496     if (!weight->IsNull()) {
497         std::string weightValue;
498         if (weight->IsNumber()) {
499             weightValue = std::to_string(weight->ToNumber<int32_t>());
500         } else {
501             ParseJsString(weight, weightValue);
502         }
503         if (isSelected) {
504             digitalParameters.selectedFontWeight = ConvertStrToFontWeight(weightValue);
505         } else {
506             digitalParameters.fontWeight = ConvertStrToFontWeight(weightValue);
507         }
508     } else {
509         if (isSelected) {
510             digitalParameters.selectedFontWeight = swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetFontWeight();
511         } else {
512             digitalParameters.fontWeight = swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetFontWeight();
513         }
514     }
515 }
516 
SetIsIndicatorCustomSize(const Dimension & dimPosition,bool parseOk)517 void JSSwiper::SetIsIndicatorCustomSize(const Dimension& dimPosition, bool parseOk)
518 {
519     if (parseOk && dimPosition > 0.0_vp) {
520         SwiperModel::GetInstance()->SetIsIndicatorCustomSize(true);
521     } else {
522         SwiperModel::GetInstance()->SetIsIndicatorCustomSize(false);
523     }
524 }
525 
ParseIndicatorDimension(const JSRef<JSVal> & value)526 std::optional<Dimension> JSSwiper::ParseIndicatorDimension(const JSRef<JSVal>& value)
527 {
528     std::optional<Dimension> indicatorDimension;
529     if (value->IsUndefined()) {
530         return indicatorDimension;
531     }
532     CalcDimension dimPosition;
533     auto parseOk = ParseJsDimensionVp(value, dimPosition);
534     indicatorDimension = parseOk && dimPosition.ConvertToPx() >= 0.0f ? dimPosition : 0.0_vp;
535     return indicatorDimension;
536 }
537 
ParseIndicatorDimension(const JSRef<JSVal> & value,RefPtr<ResourceObject> & resObj)538 std::optional<Dimension> JSSwiper::ParseIndicatorDimension(const JSRef<JSVal>& value, RefPtr<ResourceObject>& resObj)
539 {
540     std::optional<Dimension> indicatorDimension;
541     if (value->IsUndefined()) {
542         return indicatorDimension;
543     }
544     CalcDimension dimPosition;
545     auto parseOk = ParseJsDimensionVp(value, dimPosition, resObj);
546     indicatorDimension = parseOk && dimPosition.ConvertToPx() >= 0.0f ? dimPosition : 0.0_vp;
547     return indicatorDimension;
548 }
549 
ParseIndicatorBottom(const JSRef<JSVal> & bottomValue,bool hasIgnoreSize,RefPtr<ResourceObject> & resObj)550 std::optional<Dimension> JSSwiper::ParseIndicatorBottom(const JSRef<JSVal>& bottomValue, bool hasIgnoreSize,
551     RefPtr<ResourceObject>& resObj)
552 {
553     std::optional<Dimension> bottom;
554     if (bottomValue->IsUndefined()) {
555         return bottom;
556     }
557     if (!hasIgnoreSize) {
558         bottom = ParseIndicatorDimension(bottomValue, resObj);
559         return bottom;
560     } else {
561         CalcDimension dimBottom;
562         bool parseOk = ParseLengthMetricsToDimension(bottomValue, dimBottom, resObj);
563         if (!parseOk) {
564             bottom = ParseIndicatorDimension(bottomValue, resObj);
565             return bottom;
566         }
567         dimBottom = parseOk && dimBottom.ConvertToPx() >= 0.0f ? dimBottom : 0.0_vp;
568         return dimBottom;
569     }
570 }
571 
GetDotIndicatorInfo(const JSRef<JSObject> & obj)572 SwiperParameters JSSwiper::GetDotIndicatorInfo(const JSRef<JSObject>& obj)
573 {
574     JSRef<JSVal> leftValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT_VALUE));
575     JSRef<JSVal> topValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP_VALUE));
576     JSRef<JSVal> rightValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT_VALUE));
577     JSRef<JSVal> bottomValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM_VALUE));
578     JSRef<JSVal> startValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::START_VALUE));
579     JSRef<JSVal> endValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::END_VALUE));
580     JSRef<JSVal> itemWidthValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::ITEM_WIDTH_VALUE));
581     JSRef<JSVal> itemHeightValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::ITEM_HEIGHT_VALUE));
582     JSRef<JSVal> selectedItemWidthValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::SELECTED_ITEM_WIDTH_VALUE));
583     JSRef<JSVal> selectedItemHeightValue =
584         obj->GetProperty(static_cast<int32_t>(ArkUIIndex::SELECTED_ITEM_HEIGHT_VALUE));
585     JSRef<JSVal> spaceValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::SPACE_VALUE));
586     JSRef<JSVal> ignoreSizeValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::IGNORE_SIZE_VALUE));
587     JSRef<JSVal> setIgnoreSizeValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::SET_IGNORE_SIZE_VALUE));
588 
589     auto pipelineContext = PipelineBase::GetCurrentContext();
590     CHECK_NULL_RETURN(pipelineContext, SwiperParameters());
591     auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
592     CHECK_NULL_RETURN(swiperIndicatorTheme, SwiperParameters());
593     SwiperParameters swiperParameters;
594     RefPtr<ResourceObject> resLeftObj;
595     RefPtr<ResourceObject> resTopObj;
596     RefPtr<ResourceObject> resRightObj;
597     RefPtr<ResourceObject> resBottomObj;
598     swiperParameters.dimLeft = ParseIndicatorDimension(leftValue, resLeftObj);
599     swiperParameters.dimTop = ParseIndicatorDimension(topValue, resTopObj);
600     swiperParameters.dimRight = ParseIndicatorDimension(rightValue, resRightObj);
601     auto hasIgnoreSizeValue = false;
602 
603     if (setIgnoreSizeValue->IsBoolean()) {
604         hasIgnoreSizeValue = setIgnoreSizeValue->ToBoolean();
605         swiperParameters.setIgnoreSizeValue = hasIgnoreSizeValue;
606     }
607 
608     if (ignoreSizeValue->IsBoolean()) {
609         auto ignoreSize = ignoreSizeValue->ToBoolean();
610         swiperParameters.ignoreSizeValue = ignoreSize;
611     }
612     swiperParameters.dimBottom = ParseIndicatorBottom(bottomValue, hasIgnoreSizeValue, resBottomObj);
613     CalcDimension dimStart;
614     CalcDimension dimEnd;
615     CalcDimension dimSpace;
616 
617     std::optional<Dimension> indicatorDimension;
618     swiperParameters.dimStart =  ParseLengthMetricsToDimension(startValue, dimStart) ? dimStart : indicatorDimension;
619     swiperParameters.dimEnd =  ParseLengthMetricsToDimension(endValue, dimEnd) ? dimEnd : indicatorDimension;
620 
621     auto parseSpaceOk = ParseSpace(spaceValue, dimSpace) &&
622         (dimSpace.Unit() !=  DimensionUnit::PERCENT) ;
623     auto defalutSpace = swiperIndicatorTheme->GetIndicatorDotItemSpace();
624     swiperParameters.dimSpace =  (parseSpaceOk && !(dimSpace < 0.0_vp)) ? dimSpace : defalutSpace;
625     bool ignoreSize = ignoreSizeValue->IsBoolean() ? ignoreSizeValue->ToBoolean() : false;
626     swiperParameters.ignoreSizeValue = ignoreSize;
627 
628     CalcDimension dimPosition;
629     RefPtr<ResourceObject> resItemWidthObj;
630     RefPtr<ResourceObject> resItemHeightObj;
631     RefPtr<ResourceObject> resSelectedItemWidthObj;
632     RefPtr<ResourceObject> resSelectedItemHeightObj;
633     bool parseItemWOk = ParseJsDimensionVp(itemWidthValue, dimPosition, resItemWidthObj) &&
634         (dimPosition.Unit() != DimensionUnit::PERCENT);
635     auto defaultSize = swiperIndicatorTheme->GetSize();
636     swiperParameters.itemWidth = parseItemWOk && dimPosition > 0.0_vp ? dimPosition : defaultSize;
637     bool parseItemHOk = ParseJsDimensionVp(itemHeightValue, dimPosition, resItemHeightObj) &&
638         (dimPosition.Unit() != DimensionUnit::PERCENT);
639     swiperParameters.itemHeight = parseItemHOk && dimPosition > 0.0_vp ? dimPosition : defaultSize;
640     bool parseSelectedItemWOk = ParseJsDimensionVp(selectedItemWidthValue, dimPosition, resSelectedItemWidthObj) &&
641         (dimPosition.Unit() != DimensionUnit::PERCENT);
642     swiperParameters.selectedItemWidth = parseSelectedItemWOk && dimPosition > 0.0_vp ? dimPosition : defaultSize;
643     bool parseSelectedItemHOk = ParseJsDimensionVp(selectedItemHeightValue, dimPosition, resSelectedItemHeightObj) &&
644         (dimPosition.Unit() != DimensionUnit::PERCENT);
645     swiperParameters.selectedItemHeight = parseSelectedItemHOk && dimPosition > 0.0_vp ? dimPosition : defaultSize;
646     if (SystemProperties::ConfigChangePerform()) {
647         swiperParameters.resourceDimLeftValueObject = resLeftObj;
648         swiperParameters.resourceDimTopValueObject = resTopObj;
649         swiperParameters.resourceDimRightValueObject = resRightObj;
650         swiperParameters.resourceDimBottomValueObject = resBottomObj;
651         swiperParameters.resourceItemWidthValueObject = resItemWidthObj;
652         swiperParameters.resourceItemHeightValueObject = resItemHeightObj;
653         swiperParameters.resourceSelectedItemWidthValueObject = resSelectedItemWidthObj;
654         swiperParameters.resourceSelectedItemHeightValueObject = resSelectedItemHeightObj;
655     }
656     SwiperModel::GetInstance()->SetIsIndicatorCustomSize(
657         parseSelectedItemWOk || parseSelectedItemHOk || parseItemWOk || parseItemHOk);
658     SetDotIndicatorInfo(obj, swiperParameters, swiperIndicatorTheme);
659     return swiperParameters;
660 }
SetDotIndicatorInfo(const JSRef<JSObject> & obj,SwiperParameters & swiperParameters,const RefPtr<SwiperIndicatorTheme> & swiperIndicatorTheme)661 void JSSwiper::SetDotIndicatorInfo(const JSRef<JSObject>& obj, SwiperParameters& swiperParameters,
662     const RefPtr<SwiperIndicatorTheme>& swiperIndicatorTheme)
663 {
664     JSRef<JSVal> maskValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::MASK_VALUE));
665     JSRef<JSVal> colorValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR_VALUE));
666     JSRef<JSVal> selectedColorValue = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::SELECTED_COLOR_VALUE));
667     JSRef<JSVal> maxDisplayCountVal = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::MAX_DISPLAY_COUNT_VALUE));
668     if (maskValue->IsBoolean()) {
669         auto mask = maskValue->ToBoolean();
670         swiperParameters.maskValue = mask;
671     }
672     Color colorVal;
673     RefPtr<ResourceObject> resColorObj;
674     RefPtr<ResourceObject> resSelectedColorObj;
675     auto parseOk = ParseJsColor(colorValue, colorVal, resColorObj);
676     swiperParameters.colorVal = parseOk ? (swiperParameters.parametersByUser.insert("colorVal"), colorVal)
677         : swiperIndicatorTheme->GetColor();
678     parseOk = ParseJsColor(selectedColorValue, colorVal, resSelectedColorObj);
679     swiperParameters.selectedColorVal = parseOk
680         ? (swiperParameters.parametersByUser.insert("selectedColorVal"), colorVal)
681         : swiperIndicatorTheme->GetSelectedColor();
682     if (SystemProperties::ConfigChangePerform()) {
683         swiperParameters.resourceColorValueObject = resColorObj;
684         swiperParameters.resourceSelectedColorValueObject = resSelectedColorObj;
685     }
686     if (maxDisplayCountVal->IsUndefined()) {
687         return;
688     }
689     uint32_t result = 0;
690     auto setMaxDisplayCountVal = ParseJsInteger(maxDisplayCountVal, result);
691     swiperParameters.maxDisplayCountVal = setMaxDisplayCountVal && result > 0 ? result : 0;
692 }
ParseLengthMetricsToDimension(const JSRef<JSVal> & jsValue,CalcDimension & result)693 bool JSSwiper::ParseLengthMetricsToDimension(const JSRef<JSVal>& jsValue, CalcDimension& result)
694 {
695     if (jsValue->IsNumber()) {
696         result = CalcDimension(jsValue->ToNumber<double>(), DimensionUnit::VP);
697         return true;
698     }
699     if (jsValue->IsString()) {
700         auto value = jsValue->ToString();
701         StringUtils::StringToCalcDimensionNG(value, result, false, DimensionUnit::VP);
702         return true;
703     }
704     if (jsValue->IsObject()) {
705         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
706         double value = jsObj->GetProperty("value")->ToNumber<double>();
707         auto unit = static_cast<DimensionUnit>(jsObj->GetProperty("unit")->ToNumber<int32_t>());
708         result = CalcDimension(value, unit);
709         return true;
710     }
711     if (jsValue->IsNull()) {
712         result = CalcDimension(0.0f, DimensionUnit::VP);
713         return true;
714     }
715 
716     return false;
717 }
718 
ParseLengthMetricsToDimension(const JSRef<JSVal> & jsValue,CalcDimension & result,RefPtr<ResourceObject> & resourceObj)719 bool JSSwiper::ParseLengthMetricsToDimension(const JSRef<JSVal>& jsValue, CalcDimension& result,
720     RefPtr<ResourceObject>& resourceObj)
721 {
722     if (jsValue->IsNumber()) {
723         result = CalcDimension(jsValue->ToNumber<double>(), DimensionUnit::VP);
724         return true;
725     }
726     if (jsValue->IsString()) {
727         auto value = jsValue->ToString();
728         StringUtils::StringToCalcDimensionNG(value, result, false, DimensionUnit::VP);
729         return true;
730     }
731     if (jsValue->IsObject()) {
732         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
733         auto valObj = jsObj->GetProperty("value");
734         if (valObj->IsUndefined() || valObj->IsNull()) {
735             return false;
736         }
737         double value = valObj->ToNumber<double>();
738         auto unit = static_cast<DimensionUnit>(jsObj->GetProperty("unit")->ToNumber<int32_t>());
739         result = CalcDimension(value, unit);
740         auto jsRes = jsObj->GetProperty("res");
741         if (SystemProperties::ConfigChangePerform() && !jsRes->IsUndefined() &&
742             !jsRes->IsNull() && jsRes->IsObject()) {
743             JSRef<JSObject> resObj = JSRef<JSObject>::Cast(jsRes);
744             JSViewAbstract::CompleteResourceObject(resObj);
745             resourceObj = JSViewAbstract::GetResourceObject(resObj);
746         }
747         return true;
748     }
749     if (jsValue->IsNull()) {
750         result = CalcDimension(0.0f, DimensionUnit::VP);
751         return true;
752     }
753 
754     return false;
755 }
756 
ParseSpace(const JSRef<JSVal> & jsValue,CalcDimension & result)757 bool JSSwiper::ParseSpace(const JSRef<JSVal>& jsValue, CalcDimension& result)
758 {
759     if (jsValue->IsNumber()) {
760         result = CalcDimension(jsValue->ToNumber<double>(), DimensionUnit::VP);
761         return true;
762     }
763     if (jsValue->IsString()) {
764         auto value = jsValue->ToString();
765         StringUtils::StringToCalcDimensionNG(value, result, false, DimensionUnit::VP);
766         return true;
767     }
768     if (jsValue->IsObject()) {
769         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
770         double value = jsObj->GetProperty("value")->ToNumber<double>();
771         auto unit = static_cast<DimensionUnit>(jsObj->GetProperty("unit")->ToNumber<int32_t>());
772         result = CalcDimension(value, unit);
773         return true;
774     }
775 
776     return false;
777 }
778 
GetDigitIndicatorInfo(const JSRef<JSObject> & obj)779 SwiperDigitalParameters JSSwiper::GetDigitIndicatorInfo(const JSRef<JSObject>& obj)
780 {
781     JSRef<JSVal> dotLeftValue = obj->GetProperty("leftValue");
782     JSRef<JSVal> dotTopValue = obj->GetProperty("topValue");
783     JSRef<JSVal> dotRightValue = obj->GetProperty("rightValue");
784     JSRef<JSVal> dotBottomValue = obj->GetProperty("bottomValue");
785     JSRef<JSVal> startValue = obj->GetProperty("startValue");
786     JSRef<JSVal> endValue = obj->GetProperty("endValue");
787     JSRef<JSVal> fontColorValue = obj->GetProperty("fontColorValue");
788     JSRef<JSVal> selectedFontColorValue = obj->GetProperty("selectedFontColorValue");
789     JSRef<JSVal> digitFontValue = obj->GetProperty("digitFontValue");
790     JSRef<JSVal> selectedDigitFontValue = obj->GetProperty("selectedDigitFontValue");
791     JSRef<JSVal> ignoreSizeValue = obj->GetProperty("ignoreSizeValue");
792     JSRef<JSVal> setIgnoreSizeValue = obj->GetProperty("setIgnoreSizeValue");
793     auto pipelineContext = PipelineBase::GetCurrentContext();
794     CHECK_NULL_RETURN(pipelineContext, SwiperDigitalParameters());
795     auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
796     CHECK_NULL_RETURN(swiperIndicatorTheme, SwiperDigitalParameters());
797     SwiperDigitalParameters digitalParameters;
798     RefPtr<ResourceObject> resLeftObj;
799     RefPtr<ResourceObject> resTopObj;
800     RefPtr<ResourceObject> resRightObj;
801     RefPtr<ResourceObject> resBottomObj;
802     digitalParameters.dimLeft = ParseIndicatorDimension(dotLeftValue, resLeftObj);
803     digitalParameters.dimTop = ParseIndicatorDimension(dotTopValue, resTopObj);
804     digitalParameters.dimRight = ParseIndicatorDimension(dotRightValue, resRightObj);
805     bool hasIgnoreSizeValue = setIgnoreSizeValue->IsBoolean() ? setIgnoreSizeValue->ToBoolean() : false;
806     auto bottom = ParseIndicatorBottom(dotBottomValue, hasIgnoreSizeValue, resBottomObj);
807     digitalParameters.dimBottom = bottom;
808     std::optional<Dimension> indicatorDimension;
809     CalcDimension dimStart;
810     CalcDimension dimEnd;
811     digitalParameters.dimStart =  ParseLengthMetricsToDimension(startValue, dimStart) ? dimStart : indicatorDimension;
812     digitalParameters.dimEnd =  ParseLengthMetricsToDimension(endValue, dimEnd) ? dimEnd : indicatorDimension;
813 
814     if (ignoreSizeValue->IsBoolean()) {
815         auto ignoreSize = ignoreSizeValue->ToBoolean();
816         digitalParameters.ignoreSizeValue = ignoreSize;
817     } else {
818         digitalParameters.ignoreSizeValue = false;
819     }
820 
821     Color fontColor;
822     RefPtr<ResourceObject> resFontColorObj;
823     RefPtr<ResourceObject> resSelectedFontColorObj;
824     auto parseOk = JSViewAbstract::ParseJsColor(fontColorValue, fontColor, resFontColorObj);
825     digitalParameters.fontColor =
826         parseOk ? (digitalParameters.parametersByUser.insert("fontColor"), fontColor)
827         : swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetTextColor();
828     parseOk = JSViewAbstract::ParseJsColor(selectedFontColorValue, fontColor, resSelectedFontColorObj);
829     digitalParameters.selectedFontColor =
830         parseOk ? (digitalParameters.parametersByUser.insert("selectedFontColor"), fontColor)
831         : swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetTextColor();
832     if (SystemProperties::ConfigChangePerform()) {
833         digitalParameters.resourceDimLeftValueObject = resLeftObj;
834         digitalParameters.resourceDimTopValueObject = resTopObj;
835         digitalParameters.resourceDimRightValueObject = resRightObj;
836         digitalParameters.resourceDimBottomValueObject = resBottomObj;
837         digitalParameters.resourceFontColorValueObject = resFontColorObj;
838         digitalParameters.resourceSelectedFontColorValueObject = resSelectedFontColorObj;
839     }
840     if (!digitFontValue->IsNull() && digitFontValue->IsObject()) {
841         GetFontContent(digitFontValue, false, digitalParameters);
842     }
843     if (!selectedDigitFontValue->IsNull() && selectedDigitFontValue->IsObject()) {
844         GetFontContent(selectedDigitFontValue, true, digitalParameters);
845     }
846     return digitalParameters;
847 }
848 
GetArrowInfo(const JSRef<JSObject> & obj,SwiperArrowParameters & swiperArrowParameters)849 bool JSSwiper::GetArrowInfo(const JSRef<JSObject>& obj, SwiperArrowParameters& swiperArrowParameters)
850 {
851     auto isShowBackgroundValue = obj->GetProperty("showBackground");
852     auto isSidebarMiddleValue = obj->GetProperty("isSidebarMiddle");
853     auto backgroundSizeValue = obj->GetProperty("backgroundSize");
854     auto backgroundColorValue = obj->GetProperty("backgroundColor");
855     auto arrowSizeValue = obj->GetProperty("arrowSize");
856     auto arrowColorValue = obj->GetProperty("arrowColor");
857     auto pipelineContext = PipelineBase::GetCurrentContext();
858     CHECK_NULL_RETURN(pipelineContext, false);
859     auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
860     CHECK_NULL_RETURN(swiperIndicatorTheme, false);
861     swiperArrowParameters.isShowBackground = isShowBackgroundValue->IsBoolean()
862                                                  ? isShowBackgroundValue->ToBoolean()
863                                                  : swiperIndicatorTheme->GetIsShowArrowBackground();
864     swiperArrowParameters.isSidebarMiddle = isSidebarMiddleValue->IsBoolean()
865                                                 ? isSidebarMiddleValue->ToBoolean()
866                                                 : swiperIndicatorTheme->GetIsSidebarMiddle();
867     bool parseOk = false;
868     CalcDimension dimension;
869     Color color;
870     RefPtr<ResourceObject> resBackgroundSizeObj;
871     RefPtr<ResourceObject> resBackgroundColorObj;
872     RefPtr<ResourceObject> resArrowSizeObj;
873     RefPtr<ResourceObject> resArrowColorObj;
874     if (swiperArrowParameters.isSidebarMiddle.value()) {
875         parseOk = ParseJsDimensionVp(backgroundSizeValue, dimension, resBackgroundSizeObj);
876         swiperArrowParameters.backgroundSize =
877             parseOk && GreatNotEqual(dimension.ConvertToVp(), 0.0) && !(dimension.Unit() == DimensionUnit::PERCENT)
878                 ? dimension
879                 : swiperIndicatorTheme->GetBigArrowBackgroundSize();
880         parseOk = ParseJsColor(backgroundColorValue, color, resBackgroundColorObj);
881         swiperArrowParameters.backgroundColor = parseOk
882             ? (swiperArrowParameters.parametersByUser.insert("backgroundColor"), color)
883             : swiperIndicatorTheme->GetBigArrowBackgroundColor();
884         if (swiperArrowParameters.isShowBackground.value()) {
885             swiperArrowParameters.arrowSize = swiperArrowParameters.backgroundSize.value() * ARROW_SIZE_COEFFICIENT;
886         } else {
887             parseOk = ParseJsDimensionVpNG(arrowSizeValue, dimension, resArrowSizeObj);
888             swiperArrowParameters.arrowSize =
889                 parseOk && GreatNotEqual(dimension.ConvertToVp(), 0.0) && !(dimension.Unit() == DimensionUnit::PERCENT)
890                     ? dimension
891                     : swiperIndicatorTheme->GetBigArrowSize();
892             swiperArrowParameters.backgroundSize = swiperArrowParameters.arrowSize;
893         }
894         parseOk = ParseJsColor(arrowColorValue, color, resArrowColorObj);
895         swiperArrowParameters.arrowColor = parseOk
896             ? (swiperArrowParameters.parametersByUser.insert("arrowColor"), color)
897             : swiperIndicatorTheme->GetBigArrowColor();
898     } else {
899         parseOk = ParseJsDimensionVp(backgroundSizeValue, dimension, resBackgroundSizeObj);
900         swiperArrowParameters.backgroundSize =
901             parseOk && GreatNotEqual(dimension.ConvertToVp(), 0.0) && !(dimension.Unit() == DimensionUnit::PERCENT)
902                 ? dimension
903                 : swiperIndicatorTheme->GetSmallArrowBackgroundSize();
904         parseOk = ParseJsColor(backgroundColorValue, color, resBackgroundColorObj);
905         swiperArrowParameters.backgroundColor = parseOk
906             ? (swiperArrowParameters.parametersByUser.insert("backgroundColor"), color)
907             : swiperIndicatorTheme->GetSmallArrowBackgroundColor();
908         if (swiperArrowParameters.isShowBackground.value()) {
909             swiperArrowParameters.arrowSize = swiperArrowParameters.backgroundSize.value() * ARROW_SIZE_COEFFICIENT;
910         } else {
911             parseOk = ParseJsDimensionVpNG(arrowSizeValue, dimension, resArrowSizeObj);
912             swiperArrowParameters.arrowSize =
913                 parseOk && GreatNotEqual(dimension.ConvertToVp(), 0.0) && !(dimension.Unit() == DimensionUnit::PERCENT)
914                     ? dimension
915                     : swiperIndicatorTheme->GetSmallArrowSize();
916             swiperArrowParameters.backgroundSize = swiperArrowParameters.arrowSize;
917         }
918         parseOk = ParseJsColor(arrowColorValue, color, resArrowColorObj);
919         swiperArrowParameters.arrowColor = parseOk
920            ? (swiperArrowParameters.parametersByUser.insert("arrowColor"), color)
921            : swiperIndicatorTheme->GetSmallArrowColor();
922     }
923     if (SystemProperties::ConfigChangePerform()) {
924         swiperArrowParameters.resourceBackgroundSizeValueObject = resBackgroundSizeObj;
925         swiperArrowParameters.resourceBackgroundColorValueObject = resBackgroundColorObj;
926         swiperArrowParameters.resourceArrowSizeValueObject = resArrowSizeObj;
927         swiperArrowParameters.resourceArrowColorValueObject = resArrowColorObj;
928     }
929     return true;
930 }
931 
SetDisplayArrow(const JSCallbackInfo & info)932 void JSSwiper::SetDisplayArrow(const JSCallbackInfo& info)
933 {
934     if (info[0]->IsEmpty() || info[0]->IsUndefined()) {
935         SwiperModel::GetInstance()->SetDisplayArrow(false);
936         return;
937     }
938     if (info.Length() > 0 && info[0]->IsObject()) {
939         auto obj = JSRef<JSObject>::Cast(info[0]);
940         SwiperArrowParameters swiperArrowParameters;
941         if (!GetArrowInfo(obj, swiperArrowParameters)) {
942             SwiperModel::GetInstance()->SetDisplayArrow(false);
943             return;
944         }
945         JSSwiperTheme::ApplyThemeToDisplayArrow(swiperArrowParameters, obj);
946         SwiperModel::GetInstance()->SetArrowStyle(swiperArrowParameters);
947         SwiperModel::GetInstance()->SetDisplayArrow(true);
948     } else if (info[0]->IsBoolean()) {
949         if (info[0]->ToBoolean()) {
950             auto pipelineContext = PipelineBase::GetCurrentContext();
951             CHECK_NULL_VOID(pipelineContext);
952             auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
953             CHECK_NULL_VOID(swiperIndicatorTheme);
954             SwiperArrowParameters swiperArrowParameters;
955             swiperArrowParameters.isShowBackground = swiperIndicatorTheme->GetIsShowArrowBackground();
956             swiperArrowParameters.isSidebarMiddle = swiperIndicatorTheme->GetIsSidebarMiddle();
957             swiperArrowParameters.backgroundSize = swiperIndicatorTheme->GetSmallArrowBackgroundSize();
958             swiperArrowParameters.backgroundColor = swiperIndicatorTheme->GetSmallArrowBackgroundColor();
959             swiperArrowParameters.arrowSize = swiperIndicatorTheme->GetSmallArrowSize();
960             swiperArrowParameters.arrowColor = swiperIndicatorTheme->GetSmallArrowColor();
961             JSSwiperTheme::ApplyThemeToDisplayArrowForce(swiperArrowParameters);
962             SwiperModel::GetInstance()->SetArrowStyle(swiperArrowParameters);
963             SwiperModel::GetInstance()->SetDisplayArrow(true);
964         } else {
965             SwiperModel::GetInstance()->SetDisplayArrow(false);
966             return;
967         }
968     } else {
969         SwiperModel::GetInstance()->SetDisplayArrow(false);
970         return;
971     }
972     if (info.Length() > 1 && info[1]->IsBoolean()) {
973         SwiperModel::GetInstance()->SetHoverShow(info[1]->ToBoolean());
974     } else {
975         SwiperModel::GetInstance()->SetHoverShow(false);
976     }
977 }
978 
SetIndicatorController(const JSCallbackInfo & info)979 void JSSwiper::SetIndicatorController(const JSCallbackInfo& info)
980 {
981     if (info.Length() < 1 || !info[0]->IsObject()) {
982         return;
983     }
984 
985     auto* jsIndicatorController = JSRef<JSObject>::Cast(info[0])->Unwrap<JSIndicatorController>();
986     if (!jsIndicatorController) {
987         return;
988     }
989     SwiperModel::GetInstance()->SetBindIndicator(true);
990     auto targetNode = AceType::Claim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
991     auto resetFunc = jsIndicatorController->SetSwiperNodeBySwiper(targetNode);
992     SwiperModel::GetInstance()->SetIndicatorController(jsIndicatorController);
993     if (resetFunc) {
994         SwiperModel::GetInstance()->SetJSIndicatorController(resetFunc);
995     }
996 }
997 
ResetSwiperNode(const JSCallbackInfo & info)998 void JSSwiper::ResetSwiperNode(const JSCallbackInfo& info)
999 {
1000     JSIndicatorController* jsIndicatorController = SwiperModel::GetInstance()->GetIndicatorController();
1001     JSIndicatorController* controller = nullptr;
1002     if (info.Length() >= 1 && info[0]->IsObject()) {
1003         controller = JSRef<JSObject>::Cast(info[0])->Unwrap<JSIndicatorController>();
1004     }
1005     if (jsIndicatorController && jsIndicatorController != controller) {
1006         jsIndicatorController->ResetSwiperNode();
1007     }
1008 }
1009 
SetIndicator(const JSCallbackInfo & info)1010 void JSSwiper::SetIndicator(const JSCallbackInfo& info)
1011 {
1012     ResetSwiperNode(info);
1013     if (info.Length() < 1) {
1014         return;
1015     }
1016 
1017     if (info[0]->IsEmpty()) {
1018         SwiperModel::GetInstance()->SetShowIndicator(true);
1019         return;
1020     }
1021     SwiperModel::GetInstance()->SetBindIndicator(false);
1022     if (info[0]->IsObject()) {
1023         auto obj = JSRef<JSObject>::Cast(info[0]);
1024         SwiperModel::GetInstance()->SetIndicatorIsBoolean(false);
1025 
1026         JSRef<JSVal> typeParam = obj->GetProperty("type");
1027         if (typeParam->IsString()) {
1028             auto type = typeParam->ToString();
1029             if (type == "DigitIndicator") {
1030                 SwiperDigitalParameters digitalParameters = GetDigitIndicatorInfo(obj);
1031                 JSSwiperTheme::ApplyThemeToDigitIndicator(digitalParameters, obj);
1032                 SwiperModel::GetInstance()->SetDigitIndicatorStyle(digitalParameters);
1033                 SwiperModel::GetInstance()->SetIndicatorType(SwiperIndicatorType::DIGIT);
1034             } else {
1035                 SwiperParameters swiperParameters = GetDotIndicatorInfo(obj);
1036                 JSSwiperTheme::ApplyThemeToDotIndicator(swiperParameters, obj);
1037                 SwiperModel::GetInstance()->SetDotIndicatorStyle(swiperParameters);
1038                 SwiperModel::GetInstance()->SetIndicatorType(SwiperIndicatorType::DOT);
1039             }
1040         } else if (typeParam->IsUndefined()) {
1041             SetIndicatorController(info);
1042         } else {
1043             SwiperParameters swiperParameters = GetDotIndicatorInfo(obj);
1044             JSSwiperTheme::ApplyThemeToDotIndicatorForce(swiperParameters);
1045             SwiperModel::GetInstance()->SetDotIndicatorStyle(swiperParameters);
1046             SwiperModel::GetInstance()->SetIndicatorType(SwiperIndicatorType::DOT);
1047         }
1048     } else {
1049         SwiperParameters swiperParameters = GetDotIndicatorInfo(JSRef<JSObject>::New());
1050         JSSwiperTheme::ApplyThemeToDotIndicatorForce(swiperParameters);
1051         SwiperModel::GetInstance()->SetDotIndicatorStyle(swiperParameters);
1052         SwiperModel::GetInstance()->SetIndicatorType(SwiperIndicatorType::DOT);
1053     }
1054     if (info[0]->IsBoolean()) {
1055         bool showIndicator = false;
1056         ParseJsBool(info[0], showIndicator);
1057         SwiperModel::GetInstance()->SetShowIndicator(showIndicator);
1058     } else {
1059         SwiperModel::GetInstance()->SetShowIndicator(true);
1060     }
1061 }
1062 
SetIndicatorStyle(const JSCallbackInfo & info)1063 void JSSwiper::SetIndicatorStyle(const JSCallbackInfo& info)
1064 {
1065     SwiperParameters swiperParameters;
1066     if (info[0]->IsObject()) {
1067         JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
1068         JSRef<JSVal> leftValue = obj->GetProperty("left");
1069         JSRef<JSVal> topValue = obj->GetProperty("top");
1070         JSRef<JSVal> rightValue = obj->GetProperty("right");
1071         JSRef<JSVal> bottomValue = obj->GetProperty("bottom");
1072         JSRef<JSVal> sizeValue = obj->GetProperty("size");
1073         JSRef<JSVal> maskValue = obj->GetProperty("mask");
1074         JSRef<JSVal> colorValue = obj->GetProperty("color");
1075         JSRef<JSVal> selectedColorValue = obj->GetProperty("selectedColor");
1076         JSRef<JSVal> ignoreSizeValue = obj->GetProperty("ignoreSize");
1077         auto pipelineContext = PipelineBase::GetCurrentContext();
1078         CHECK_NULL_VOID(pipelineContext);
1079         auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
1080         CHECK_NULL_VOID(swiperIndicatorTheme);
1081         RefPtr<ResourceObject> resLeftObj;
1082         RefPtr<ResourceObject> resTopObj;
1083         RefPtr<ResourceObject> resRightObj;
1084         RefPtr<ResourceObject> resBottomObj;
1085         swiperParameters.dimLeft = ParseIndicatorDimension(leftValue, resLeftObj);
1086         swiperParameters.dimTop = ParseIndicatorDimension(topValue, resTopObj);
1087         swiperParameters.dimRight = ParseIndicatorDimension(rightValue, resRightObj);
1088         swiperParameters.dimBottom = ParseIndicatorDimension(bottomValue, resBottomObj);
1089 
1090         CalcDimension dimPosition;
1091         RefPtr<ResourceObject> resItemSizeObj;
1092         auto parseOk = ParseJsDimensionVp(sizeValue, dimPosition, resItemSizeObj) &&
1093             (dimPosition.Unit() != DimensionUnit::PERCENT);
1094         SetIsIndicatorCustomSize(dimPosition, parseOk);
1095         swiperParameters.itemWidth = parseOk && dimPosition > 0.0_vp ? dimPosition : swiperIndicatorTheme->GetSize();
1096         swiperParameters.itemHeight = parseOk && dimPosition > 0.0_vp ? dimPosition : swiperIndicatorTheme->GetSize();
1097         swiperParameters.selectedItemWidth =
1098             parseOk && dimPosition > 0.0_vp ? dimPosition : swiperIndicatorTheme->GetSize();
1099         swiperParameters.selectedItemHeight =
1100             parseOk && dimPosition > 0.0_vp ? dimPosition : swiperIndicatorTheme->GetSize();
1101         if (maskValue->IsBoolean()) {
1102             auto mask = maskValue->ToBoolean();
1103             swiperParameters.maskValue = mask;
1104         }
1105         if (ignoreSizeValue->IsBoolean()) {
1106             auto ignoreSize = ignoreSizeValue->ToBoolean();
1107             swiperParameters.ignoreSizeValue = ignoreSize;
1108         } else {
1109             swiperParameters.ignoreSizeValue = false;
1110         }
1111         Color colorVal;
1112         RefPtr<ResourceObject> resColorObj;
1113         RefPtr<ResourceObject> resSelectedColorObj;
1114         parseOk = ParseJsColor(colorValue, colorVal, resColorObj);
1115         swiperParameters.colorVal = parseOk ?  (swiperParameters.parametersByUser.insert("colorVal"), colorVal)
1116             : swiperIndicatorTheme->GetColor();
1117         parseOk = ParseJsColor(selectedColorValue, colorVal, resSelectedColorObj);
1118         swiperParameters.selectedColorVal = parseOk
1119             ? (swiperParameters.parametersByUser.insert("selectedColorVal"), colorVal)
1120             : swiperIndicatorTheme->GetSelectedColor();
1121         if (SystemProperties::ConfigChangePerform()) {
1122             swiperParameters.resourceDimLeftValueObject = resLeftObj;
1123             swiperParameters.resourceDimTopValueObject = resTopObj;
1124             swiperParameters.resourceDimRightValueObject = resRightObj;
1125             swiperParameters.resourceDimBottomValueObject = resBottomObj;
1126             swiperParameters.resourceColorValueObject = resColorObj;
1127             swiperParameters.resourceSelectedColorValueObject = resSelectedColorObj;
1128             swiperParameters.resourceItemSizeValueObject = resItemSizeObj;
1129         }
1130     }
1131     SwiperModel::GetInstance()->SetDotIndicatorStyle(swiperParameters);
1132     info.ReturnSelf();
1133 }
1134 
SetItemSpace(const JSCallbackInfo & info)1135 void JSSwiper::SetItemSpace(const JSCallbackInfo& info)
1136 {
1137     if (info.Length() < 1) {
1138         return;
1139     }
1140 
1141     CalcDimension value;
1142     if (!ParseJsDimensionVp(info[0], value) || LessNotEqual(value.Value(), 0.0)) {
1143         value.SetValue(0.0);
1144     }
1145 
1146     SwiperModel::GetInstance()->SetItemSpace(value);
1147 }
1148 
SetPreviousMargin(const JSCallbackInfo & info)1149 void JSSwiper::SetPreviousMargin(const JSCallbackInfo& info)
1150 {
1151     if (info.Length() < 1) {
1152         return;
1153     }
1154 
1155     CalcDimension value;
1156     bool ignoreBlank = false;
1157     RefPtr<ResourceObject> resObj;
1158     if (!ParseJsDimensionVp(info[0], value, resObj) || info[0]->IsNull() || info[0]->IsUndefined() ||
1159         LessNotEqual(value.Value(), 0.0)) {
1160         value.SetValue(0.0);
1161     }
1162     if (info.Length() > 1 && info[1]->IsBoolean()) {
1163         ignoreBlank = info[1]->ToBoolean();
1164     }
1165     SwiperModel::GetInstance()->SetPreviousMargin(value, ignoreBlank);
1166     if (SystemProperties::ConfigChangePerform()) {
1167         SwiperModel::GetInstance()->ProcessPreviousMarginWithResourceObj(resObj);
1168     }
1169 }
1170 
SetNextMargin(const JSCallbackInfo & info)1171 void JSSwiper::SetNextMargin(const JSCallbackInfo& info)
1172 {
1173     if (info.Length() < 1) {
1174         return;
1175     }
1176 
1177     CalcDimension value;
1178     bool ignoreBlank = false;
1179     RefPtr<ResourceObject> resObj;
1180     if (!ParseJsDimensionVp(info[0], value, resObj) || info[0]->IsNull() || info[0]->IsUndefined() ||
1181         LessNotEqual(value.Value(), 0.0)) {
1182         value.SetValue(0.0);
1183     }
1184     if (info.Length() > 1 && info[1]->IsBoolean()) {
1185         ignoreBlank = info[1]->ToBoolean();
1186     }
1187     SwiperModel::GetInstance()->SetNextMargin(value, ignoreBlank);
1188     if (SystemProperties::ConfigChangePerform()) {
1189         SwiperModel::GetInstance()->ProcessNextMarginWithResourceObj(resObj);
1190     }
1191 }
1192 
SetDisplayMode(int32_t index)1193 void JSSwiper::SetDisplayMode(int32_t index)
1194 {
1195     if (index < 0 || index >= static_cast<int32_t>(DISPLAY_MODE.size())) {
1196         return;
1197     }
1198 
1199     SwiperModel::GetInstance()->SetDisplayMode(DISPLAY_MODE[index]);
1200 }
1201 
SetCachedCount(const JSCallbackInfo & info)1202 void JSSwiper::SetCachedCount(const JSCallbackInfo& info)
1203 {
1204     if (info.Length() < 1) {
1205         return;
1206     }
1207 
1208     int32_t cachedCount = DEFAULT_CACHED_COUNT;
1209     if (!info[0]->IsUndefined() && info[0]->IsNumber()) {
1210         cachedCount = info[0]->ToNumber<int32_t>();
1211         if (cachedCount < 0) {
1212             cachedCount = DEFAULT_CACHED_COUNT;
1213         }
1214     }
1215     SwiperModel::GetInstance()->SetCachedCount(cachedCount);
1216 
1217     auto isShown = info.Length() > 1 && info[1]->IsBoolean() && info[1]->ToBoolean();
1218     SwiperModel::GetInstance()->SetCachedIsShown(isShown);
1219 }
1220 
SetCurve(const JSCallbackInfo & info)1221 void JSSwiper::SetCurve(const JSCallbackInfo& info)
1222 {
1223     RefPtr<Curve> curve = DEFAULT_CURVE;
1224     if (info[0]->IsString()) {
1225         curve = CreateCurve(info[0]->ToString(), false);
1226         if (!curve) {
1227             curve = DEFAULT_CURVE;
1228         }
1229     } else if (info[0]->IsObject()) {
1230         auto object = JSRef<JSObject>::Cast(info[0]);
1231         std::function<float(float)> customCallBack = nullptr;
1232         JSRef<JSVal> onCallBack = object->GetProperty("__curveCustomFunc");
1233         if (onCallBack->IsFunction()) {
1234             RefPtr<JsFunction> jsFuncCallBack =
1235                 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onCallBack));
1236             customCallBack = [func = std::move(jsFuncCallBack), id = Container::CurrentId()](float time) -> float {
1237                 ContainerScope scope(id);
1238                 JSRef<JSVal> params[1];
1239                 params[0] = JSRef<JSVal>::Make(ToJSValue(time));
1240                 auto result = func->ExecuteJS(1, params);
1241                 auto resultValue = result->IsNumber() ? result->ToNumber<float>() : 1.0f;
1242                 return resultValue;
1243             };
1244         }
1245         auto jsCurveString = object->GetProperty("__curveString");
1246         if (jsCurveString->IsString()) {
1247             auto aniTimFunc = jsCurveString->ToString();
1248             if (aniTimFunc == DOM_ANIMATION_TIMING_FUNCTION_CUSTOM && customCallBack) {
1249                 curve = CreateCurve(customCallBack);
1250             } else if (aniTimFunc != DOM_ANIMATION_TIMING_FUNCTION_CUSTOM) {
1251                 curve = CreateCurve(aniTimFunc);
1252             }
1253         }
1254     }
1255     SwiperModel::GetInstance()->SetCurve(curve);
1256 }
1257 
SetOnChange(const JSCallbackInfo & info)1258 void JSSwiper::SetOnChange(const JSCallbackInfo& info)
1259 {
1260     if (!info[0]->IsFunction()) {
1261         return;
1262     }
1263 
1264     auto changeHandler = AceType::MakeRefPtr<JsEventFunction<SwiperChangeEvent, 1>>(
1265         JSRef<JSFunc>::Cast(info[0]), SwiperChangeEventToJSValue);
1266     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1267     auto onChange = [executionContext = info.GetExecutionContext(), func = std::move(changeHandler), node = targetNode](
1268                         const BaseEventInfo* info) {
1269         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
1270         const auto* swiperInfo = TypeInfoHelper::DynamicCast<SwiperChangeEvent>(info);
1271         if (!swiperInfo) {
1272             TAG_LOGW(AceLogTag::ACE_SWIPER, "Swiper onChange callback execute failed.");
1273             return;
1274         }
1275         ACE_SCORING_EVENT("Swiper.OnChange");
1276         PipelineContext::SetCallBackNode(node);
1277         func->Execute(*swiperInfo);
1278     };
1279 
1280     SwiperModel::GetInstance()->SetOnChange(std::move(onChange));
1281 }
1282 
SetOnUnselected(const JSCallbackInfo & info)1283 void JSSwiper::SetOnUnselected(const JSCallbackInfo& info)
1284 {
1285     if (!info[0]->IsFunction()) {
1286         return;
1287     }
1288     auto unselectedHandler = AceType::MakeRefPtr<JsEventFunction<SwiperChangeEvent, 1>>(
1289         JSRef<JSFunc>::Cast(info[0]), SwiperChangeEventToJSValue);
1290     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1291     auto onUnselected = [executionContext = info.GetExecutionContext(), func = std::move(unselectedHandler),
1292                           node = targetNode](const BaseEventInfo* info) {
1293         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
1294         const auto* swiperInfo = TypeInfoHelper::DynamicCast<SwiperChangeEvent>(info);
1295         if (!swiperInfo) {
1296             TAG_LOGW(AceLogTag::ACE_SWIPER, "Swiper onUnselected callback execute failed.");
1297             return;
1298         }
1299         ACE_SCORING_EVENT("Swiper.onUnselected");
1300         ACE_SCOPED_TRACE("Swiper.onUnselected index %d", swiperInfo->GetIndex());
1301         PipelineContext::SetCallBackNode(node);
1302         func->Execute(*swiperInfo);
1303     };
1304     SwiperModel::GetInstance()->SetOnUnselected(std::move(onUnselected));
1305 }
1306 
SetOnAnimationStart(const JSCallbackInfo & info)1307 void JSSwiper::SetOnAnimationStart(const JSCallbackInfo& info)
1308 {
1309     if (!info[0]->IsFunction()) {
1310         return;
1311     }
1312 
1313     if (Container::IsCurrentUseNewPipeline()) {
1314         auto animationStartHandler = AceType::MakeRefPtr<JsSwiperFunction>(JSRef<JSFunc>::Cast(info[0]));
1315         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1316         auto onAnimationStart = [executionContext = info.GetExecutionContext(), func = std::move(animationStartHandler),
1317                                     node = targetNode](
1318                                     int32_t index, int32_t targetIndex, const AnimationCallbackInfo& info) {
1319             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
1320             ACE_SCORING_EVENT("Swiper.onAnimationStart");
1321             PipelineContext::SetCallBackNode(node);
1322             func->Execute(index, targetIndex, info);
1323         };
1324 
1325         SwiperModel::GetInstance()->SetOnAnimationStart(std::move(onAnimationStart));
1326         return;
1327     }
1328 
1329     auto animationStartHandler = AceType::MakeRefPtr<JsEventFunction<SwiperChangeEvent, 1>>(
1330         JSRef<JSFunc>::Cast(info[0]), SwiperChangeEventToJSValue);
1331     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1332     auto onAnimationStart = [executionContext = info.GetExecutionContext(), func = std::move(animationStartHandler),
1333                                 node = targetNode](const BaseEventInfo* info) {
1334         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
1335         const auto* swiperInfo = TypeInfoHelper::DynamicCast<SwiperChangeEvent>(info);
1336         if (!swiperInfo) {
1337             TAG_LOGW(AceLogTag::ACE_SWIPER, "Swiper onAnimationStart callback execute failed.");
1338             return;
1339         }
1340         ACE_SCORING_EVENT("Swiper.onAnimationStart");
1341         PipelineContext::SetCallBackNode(node);
1342         func->Execute(*swiperInfo);
1343     };
1344 
1345     SwiperModel::GetInstance()->SetOnAnimationStart(std::move(onAnimationStart));
1346 }
1347 
SetOnAnimationEnd(const JSCallbackInfo & info)1348 void JSSwiper::SetOnAnimationEnd(const JSCallbackInfo& info)
1349 {
1350     if (!info[0]->IsFunction()) {
1351         return;
1352     }
1353 
1354     if (Container::IsCurrentUseNewPipeline()) {
1355         auto animationEndHandler = AceType::MakeRefPtr<JsSwiperFunction>(JSRef<JSFunc>::Cast(info[0]));
1356         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1357         auto onAnimationEnd = [executionContext = info.GetExecutionContext(), func = std::move(animationEndHandler),
1358                                   node = targetNode](int32_t index, const AnimationCallbackInfo& info) {
1359             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
1360             ACE_SCORING_EVENT("Swiper.onAnimationEnd");
1361             PipelineContext::SetCallBackNode(node);
1362             func->Execute(index, info);
1363         };
1364 
1365         SwiperModel::GetInstance()->SetOnAnimationEnd(std::move(onAnimationEnd));
1366         return;
1367     }
1368 
1369     auto animationEndHandler = AceType::MakeRefPtr<JsEventFunction<SwiperChangeEvent, 1>>(
1370         JSRef<JSFunc>::Cast(info[0]), SwiperChangeEventToJSValue);
1371     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1372     auto onAnimationEnd = [executionContext = info.GetExecutionContext(), func = std::move(animationEndHandler),
1373                               node = targetNode](const BaseEventInfo* info) {
1374         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
1375         const auto* swiperInfo = TypeInfoHelper::DynamicCast<SwiperChangeEvent>(info);
1376         if (!swiperInfo) {
1377             TAG_LOGW(AceLogTag::ACE_SWIPER, "Swiper onAnimationEnd callback execute failed.");
1378             return;
1379         }
1380         ACE_SCORING_EVENT("Swiper.onAnimationEnd");
1381         PipelineContext::SetCallBackNode(node);
1382         func->Execute(*swiperInfo);
1383     };
1384 
1385     SwiperModel::GetInstance()->SetOnAnimationEnd(std::move(onAnimationEnd));
1386 }
1387 
SetOnGestureSwipe(const JSCallbackInfo & info)1388 void JSSwiper::SetOnGestureSwipe(const JSCallbackInfo& info)
1389 {
1390     if (!info[0]->IsFunction()) {
1391         return;
1392     }
1393 
1394     auto gestureSwipeHandler = AceType::MakeRefPtr<JsSwiperFunction>(JSRef<JSFunc>::Cast(info[0]));
1395     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1396     auto onGestureSwipe = [executionContext = info.GetExecutionContext(), func = std::move(gestureSwipeHandler),
1397                               node = targetNode](int32_t index, const AnimationCallbackInfo& info) {
1398         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
1399         ACE_SCORING_EVENT("Swiper.onGestureSwipe");
1400         PipelineContext::SetCallBackNode(node);
1401         func->Execute(index, info);
1402     };
1403 
1404     SwiperModel::GetInstance()->SetOnGestureSwipe(std::move(onGestureSwipe));
1405 }
1406 
SetOnClick(const JSCallbackInfo & info)1407 void JSSwiper::SetOnClick(const JSCallbackInfo& info)
1408 {
1409     if (Container::IsCurrentUseNewPipeline()) {
1410         JSInteractableView::JsOnClick(info);
1411         return;
1412     }
1413 
1414     if (!info[0]->IsFunction()) {
1415         return;
1416     }
1417 
1418     RefPtr<JsClickFunction> jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
1419     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1420     auto onClick = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc), node = targetNode](
1421                        const BaseEventInfo* info, const RefPtr<V2::InspectorFunctionImpl>& impl) {
1422         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1423         const auto* clickInfo = TypeInfoHelper::DynamicCast<ClickInfo>(info);
1424         if (!clickInfo) {
1425             TAG_LOGW(AceLogTag::ACE_SWIPER, "Swiper onClick callback execute failed.");
1426             return;
1427         }
1428         auto newInfo = *clickInfo;
1429         if (impl) {
1430             impl->UpdateEventInfo(newInfo);
1431         }
1432         ACE_SCORING_EVENT("onClick");
1433         PipelineContext::SetCallBackNode(node);
1434         func->Execute(newInfo);
1435     };
1436 
1437     SwiperModel::GetInstance()->SetOnClick(onClick);
1438 }
1439 
SetWidth(const JSCallbackInfo & info)1440 void JSSwiper::SetWidth(const JSCallbackInfo& info)
1441 {
1442     if (info.Length() < 1) {
1443         return;
1444     }
1445 
1446     SetWidth(info[0]);
1447 }
1448 
SetWidth(const JSRef<JSVal> & jsValue)1449 void JSSwiper::SetWidth(const JSRef<JSVal>& jsValue)
1450 {
1451     if (Container::IsCurrentUseNewPipeline()) {
1452         JSViewAbstract::JsWidth(jsValue);
1453         return;
1454     }
1455 
1456     JSViewAbstract::JsWidth(jsValue);
1457     SwiperModel::GetInstance()->SetMainSwiperSizeWidth();
1458 }
1459 
SetHeight(const JSRef<JSVal> & jsValue)1460 void JSSwiper::SetHeight(const JSRef<JSVal>& jsValue)
1461 {
1462     if (Container::IsCurrentUseNewPipeline()) {
1463         JSViewAbstract::JsHeight(jsValue);
1464         return;
1465     }
1466 
1467     JSViewAbstract::JsHeight(jsValue);
1468     SwiperModel::GetInstance()->SetMainSwiperSizeHeight();
1469 }
1470 
SetHeight(const JSCallbackInfo & info)1471 void JSSwiper::SetHeight(const JSCallbackInfo& info)
1472 {
1473     if (info.Length() < 1) {
1474         return;
1475     }
1476 
1477     SetHeight(info[0]);
1478 }
1479 
SetSize(const JSCallbackInfo & info)1480 void JSSwiper::SetSize(const JSCallbackInfo& info)
1481 {
1482     if (info.Length() < 1) {
1483         return;
1484     }
1485 
1486     if (!info[0]->IsObject()) {
1487         return;
1488     }
1489 
1490     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
1491     SetWidth(sizeObj->GetProperty("width"));
1492     SetHeight(sizeObj->GetProperty("height"));
1493 }
1494 
JSBind(BindingTarget globalObj)1495 void JSSwiperController::JSBind(BindingTarget globalObj)
1496 {
1497     JSClass<JSSwiperController>::Declare("SwiperController");
1498     JSClass<JSSwiperController>::CustomMethod("swipeTo", &JSSwiperController::SwipeTo);
1499     JSClass<JSSwiperController>::CustomMethod("showNext", &JSSwiperController::ShowNext);
1500     JSClass<JSSwiperController>::CustomMethod("showPrevious", &JSSwiperController::ShowPrevious);
1501     JSClass<JSSwiperController>::CustomMethod("changeIndex", &JSSwiperController::ChangeIndex);
1502     JSClass<JSSwiperController>::CustomMethod("finishAnimation", &JSSwiperController::FinishAnimation);
1503     JSClass<JSSwiperController>::CustomMethod("preloadItems", &JSSwiperController::PreloadItems);
1504     JSClass<JSSwiperController>::Bind(globalObj, JSSwiperController::Constructor, JSSwiperController::Destructor);
1505 }
1506 
Constructor(const JSCallbackInfo & args)1507 void JSSwiperController::Constructor(const JSCallbackInfo& args)
1508 {
1509     auto scroller = Referenced::MakeRefPtr<JSSwiperController>();
1510     scroller->IncRefCount();
1511     args.SetReturnValue(Referenced::RawPtr(scroller));
1512 }
1513 
Destructor(JSSwiperController * scroller)1514 void JSSwiperController::Destructor(JSSwiperController* scroller)
1515 {
1516     if (scroller != nullptr) {
1517         scroller->DecRefCount();
1518     }
1519 }
1520 
SwipeTo(const JSCallbackInfo & args)1521 void JSSwiperController::SwipeTo(const JSCallbackInfo& args)
1522 {
1523     ContainerScope scope(instanceId_);
1524     if (args.Length() < 1 || !args[0]->IsNumber()) {
1525         LOGE("Param is not valid");
1526         return;
1527     }
1528     if (controller_) {
1529         controller_->SwipeTo(args[0]->ToNumber<int32_t>());
1530     } else {
1531         EventReport::ReportScrollableErrorEvent(
1532             "Swiper", ScrollableErrorType::CONTROLLER_NOT_BIND, "swipeTo: Swiper controller not bind.");
1533     }
1534 }
1535 
ShowNext(const JSCallbackInfo & args)1536 void JSSwiperController::ShowNext(const JSCallbackInfo& args)
1537 {
1538     ContainerScope scope(instanceId_);
1539     if (controller_) {
1540         controller_->ShowNext();
1541     } else {
1542         EventReport::ReportScrollableErrorEvent(
1543             "Swiper", ScrollableErrorType::CONTROLLER_NOT_BIND, "showNext: Swiper controller not bind.");
1544     }
1545 }
1546 
ShowPrevious(const JSCallbackInfo & args)1547 void JSSwiperController::ShowPrevious(const JSCallbackInfo& args)
1548 {
1549     ContainerScope scope(instanceId_);
1550     if (controller_) {
1551         controller_->ShowPrevious();
1552     } else {
1553         EventReport::ReportScrollableErrorEvent(
1554             "Swiper", ScrollableErrorType::CONTROLLER_NOT_BIND, "showPrevious: Swiper controller not bind.");
1555     }
1556 }
1557 
ChangeIndex(const JSCallbackInfo & args)1558 void JSSwiperController::ChangeIndex(const JSCallbackInfo& args)
1559 {
1560     if (!controller_) {
1561         EventReport::ReportScrollableErrorEvent(
1562             "Swiper", ScrollableErrorType::CONTROLLER_NOT_BIND, "changeIndex: Swiper controller not bind.");
1563         return;
1564     }
1565     if (args.Length() < 1 || !args[0]->IsNumber()) {
1566         return;
1567     }
1568     int32_t index = args[0]->ToNumber<int32_t>();
1569     if (args.Length() > 1 && args[1]->IsNumber()) {
1570         int32_t animationMode = args[1]->ToNumber<int32_t>();
1571         if (animationMode < 0 || animationMode >= static_cast<int32_t>(SWIPER_ANIMATION_MODE.size())) {
1572             animationMode = 0;
1573         }
1574         controller_->ChangeIndex(index, SWIPER_ANIMATION_MODE[animationMode]);
1575         return;
1576     }
1577     bool useAnimation = false;
1578     if (args.Length() > 1 && args[1]->IsBoolean()) {
1579         useAnimation = args[1]->ToBoolean();
1580     }
1581     controller_->ChangeIndex(index, useAnimation);
1582 }
1583 
FinishAnimation(const JSCallbackInfo & args)1584 void JSSwiperController::FinishAnimation(const JSCallbackInfo& args)
1585 {
1586     ContainerScope scope(instanceId_);
1587     if (!controller_) {
1588         EventReport::ReportScrollableErrorEvent(
1589             "Swiper", ScrollableErrorType::CONTROLLER_NOT_BIND, "finishAnimation: Swiper controller not bind.");
1590         return;
1591     }
1592 
1593     if (args.Length() > 0 && args[0]->IsFunction()) {
1594         RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(args[0]));
1595         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1596         auto onFinish = [execCtx = args.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1597             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1598             ACE_SCORING_EVENT("Swiper.finishAnimation");
1599             PipelineContext::SetCallBackNode(node);
1600             TAG_LOGD(AceLogTag::ACE_SWIPER, "SwiperController finishAnimation callback execute.");
1601             func->Execute();
1602         };
1603 
1604         controller_->SetFinishCallback(onFinish);
1605         controller_->FinishAnimation();
1606         return;
1607     }
1608 
1609     controller_->FinishAnimation();
1610 }
1611 
OldPreloadItems(const JSCallbackInfo & args)1612 void JSSwiperController::OldPreloadItems(const JSCallbackInfo& args)
1613 {
1614     ContainerScope scope(instanceId_);
1615     if (!controller_) {
1616         EventReport::ReportScrollableErrorEvent(
1617             "Swiper", ScrollableErrorType::CONTROLLER_NOT_BIND, "preloadItems: Swiper controller not bind.");
1618         return;
1619     }
1620 
1621     if (args.Length() != LENGTH_TWO || !args[0]->IsArray() || !args[1]->IsFunction()) {
1622         return;
1623     }
1624 
1625     auto indexArray = JSRef<JSArray>::Cast(args[0]);
1626     size_t size = indexArray->Length();
1627     std::set<int32_t> indexSet;
1628     for (size_t i = 0; i < size; i++) {
1629         int32_t index = -1;
1630         JSViewAbstract::ParseJsInt32(indexArray->GetValueAt(i), index);
1631         indexSet.emplace(index);
1632     }
1633 
1634     RefPtr<JsSwiperFunction> jsFunc = AceType::MakeRefPtr<JsSwiperFunction>(JSRef<JSFunc>::Cast(args[1]));
1635     auto onPreloadFinish =
1636         [execCtx = args.GetExecutionContext(), func = std::move(jsFunc)](int32_t errorCode, std::string message) {
1637             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1638             ACE_SCORING_EVENT("Swiper.preloadItems");
1639             TAG_LOGI(AceLogTag::ACE_SWIPER, "SwiperController preloadItems callback execute.");
1640             func->Execute(errorCode);
1641         };
1642 
1643     controller_->SetPreloadFinishCallback(onPreloadFinish);
1644     controller_->PreloadItems(indexSet);
1645 }
1646 
NewPreloadItems(const JSCallbackInfo & args)1647 void JSSwiperController::NewPreloadItems(const JSCallbackInfo& args)
1648 {
1649     if (!controller_) {
1650         EventReport::ReportScrollableErrorEvent(
1651             "Swiper", ScrollableErrorType::CONTROLLER_NOT_BIND, "preloadItems: Swiper controller not bind.");
1652         JSException::Throw(ERROR_CODE_NAMED_ROUTE_ERROR, "%s", "Controller not bound to component.");
1653         return;
1654     }
1655 
1656     ContainerScope scope(instanceId_);
1657     auto engine = EngineHelper::GetCurrentEngine();
1658     CHECK_NULL_VOID(engine);
1659     NativeEngine* nativeEngine = engine->GetNativeEngine();
1660     auto env = reinterpret_cast<napi_env>(nativeEngine);
1661     auto asyncContext = std::make_shared<SwiperControllerAsyncContext>();
1662     asyncContext->env = env;
1663     napi_value promise = nullptr;
1664     napi_create_promise(env, &asyncContext->deferred, &promise);
1665     ScopeRAII scopeRaii(env);
1666     std::set<int32_t> indexSet;
1667     if (args.Length() > 0 && args[0]->IsArray()) {
1668         auto indexArray = JSRef<JSArray>::Cast(args[0]);
1669         size_t size = indexArray->Length();
1670         for (size_t i = 0; i < size; i++) {
1671             int32_t index = -1;
1672             JSViewAbstract::ParseJsInt32(indexArray->GetValueAt(i), index);
1673             indexSet.emplace(index);
1674         }
1675     }
1676 
1677     auto onPreloadFinish = [asyncContext](int32_t errorCode, std::string message) {
1678         CHECK_NULL_VOID(asyncContext);
1679         HandleDeferred(asyncContext, errorCode, message);
1680     };
1681     controller_->SetPreloadFinishCallback(onPreloadFinish);
1682     controller_->PreloadItems(indexSet);
1683     ReturnPromise(args, promise);
1684 }
1685 
PreloadItems(const JSCallbackInfo & args)1686 void JSSwiperController::PreloadItems(const JSCallbackInfo& args)
1687 {
1688     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN) && args.Length() == 1) {
1689         NewPreloadItems(args);
1690         return;
1691     }
1692 
1693     OldPreloadItems(args);
1694 }
1695 
SetNestedScroll(const JSCallbackInfo & args)1696 void JSSwiper::SetNestedScroll(const JSCallbackInfo& args)
1697 {
1698     // default value
1699     NestedScrollOptions nestedOpt = {
1700         .forward = NestedScrollMode::SELF_ONLY,
1701         .backward = NestedScrollMode::SELF_ONLY,
1702     };
1703     if (args.Length() < 1 || !args[0]->IsNumber()) {
1704         SwiperModel::GetInstance()->SetNestedScroll(nestedOpt);
1705         return;
1706     }
1707     int32_t value = -1;
1708     JSViewAbstract::ParseJsInt32(args[0], value);
1709     auto mode = static_cast<NestedScrollMode>(value);
1710     if (mode < NestedScrollMode::SELF_ONLY || mode > NestedScrollMode::SELF_FIRST) {
1711         SwiperModel::GetInstance()->SetNestedScroll(nestedOpt);
1712         return;
1713     }
1714     nestedOpt.forward = mode;
1715     nestedOpt.backward = mode;
1716     SwiperModel::GetInstance()->SetNestedScroll(nestedOpt);
1717     args.ReturnSelf();
1718 }
1719 
SetCustomContentTransition(const JSCallbackInfo & info)1720 void JSSwiper::SetCustomContentTransition(const JSCallbackInfo& info)
1721 {
1722     if (info.Length() < 1 || !info[0]->IsObject()) {
1723         return;
1724     }
1725 
1726     SwiperContentAnimatedTransition transitionInfo;
1727     auto transitionObj = JSRef<JSObject>::Cast(info[0]);
1728     JSRef<JSVal> timeoutProperty = transitionObj->GetProperty("timeout");
1729     if (timeoutProperty->IsNumber()) {
1730         auto timeout = timeoutProperty->ToNumber<int32_t>();
1731         transitionInfo.timeout = timeout < 0 ? DEFAULT_CUSTOM_ANIMATION_TIMEOUT : timeout;
1732     } else {
1733         transitionInfo.timeout = DEFAULT_CUSTOM_ANIMATION_TIMEOUT;
1734     }
1735 
1736     JSRef<JSVal> transition = transitionObj->GetProperty("transition");
1737     if (transition->IsFunction()) {
1738         auto jsOnTransition = AceType::MakeRefPtr<JsSwiperFunction>(JSRef<JSFunc>::Cast(transition));
1739         auto onTransition = [execCtx = info.GetExecutionContext(), func = std::move(jsOnTransition)](
1740                                 const RefPtr<SwiperContentTransitionProxy>& proxy) {
1741             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1742             ACE_SCORING_EVENT("Swiper.customContentTransition");
1743             func->Execute(proxy);
1744         };
1745         transitionInfo.transition = std::move(onTransition);
1746     }
1747     SwiperModel::GetInstance()->SetCustomContentTransition(transitionInfo);
1748 }
1749 
SetOnContentDidScroll(const JSCallbackInfo & info)1750 void JSSwiper::SetOnContentDidScroll(const JSCallbackInfo& info)
1751 {
1752     if (info.Length() < 1 || !info[0]->IsFunction()) {
1753         return;
1754     }
1755 
1756     auto contentDidScrollHandler = AceType::MakeRefPtr<JsSwiperFunction>(JSRef<JSFunc>::Cast(info[0]));
1757     auto onContentDidScroll = [execCtx = info.GetExecutionContext(),
1758                                 func = std::move(contentDidScrollHandler)](
1759                                 int32_t selectedIndex, int32_t index, float position, float mainAxisLength) {
1760         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1761         ACE_SCORING_EVENT("Swiper.onContentDidScroll");
1762         func->Execute(selectedIndex, index, position, mainAxisLength);
1763     };
1764     SwiperModel::GetInstance()->SetOnContentDidScroll(std::move(onContentDidScroll));
1765 }
1766 
SetOnContentWillScroll(const JSCallbackInfo & info)1767 void JSSwiper::SetOnContentWillScroll(const JSCallbackInfo& info)
1768 {
1769     if (info.Length() < 1) {
1770         return;
1771     }
1772 
1773     if (info[0]->IsUndefined() || info[0]->IsNull()) {
1774         SwiperModel::GetInstance()->SetOnContentWillScroll(nullptr);
1775         return;
1776     }
1777 
1778     if (!info[0]->IsFunction()) {
1779         return;
1780     }
1781 
1782     auto handler = AceType::MakeRefPtr<JsSwiperFunction>(JSRef<JSFunc>::Cast(info[0]));
1783     auto callback = [execCtx = info.GetExecutionContext(), func = std::move(handler)](
1784                         const SwiperContentWillScrollResult& result) -> bool {
1785         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, true);
1786         ACE_SCORING_EVENT("Swiper.onContentWillScroll");
1787         auto ret = func->Execute(result);
1788         if (!ret->IsBoolean()) {
1789             return true;
1790         }
1791         return ret->ToBoolean();
1792     };
1793     SwiperModel::GetInstance()->SetOnContentWillScroll(std::move(callback));
1794 }
1795 
SetPageFlipMode(const JSCallbackInfo & info)1796 void JSSwiper::SetPageFlipMode(const JSCallbackInfo& info)
1797 {
1798     // default value
1799     int32_t value = 0;
1800     if (info.Length() < 1 || !info[0]->IsNumber()) {
1801         SwiperModel::GetInstance()->SetPageFlipMode(value);
1802         return;
1803     }
1804     JSViewAbstract::ParseJsInt32(info[0], value);
1805     SwiperModel::GetInstance()->SetPageFlipMode(value);
1806 }
1807 
GetAutoPlayOptionsInfo(const JSRef<JSObject> & obj,SwiperAutoPlayOptions & swiperAutoPlayOptions)1808 void JSSwiper::GetAutoPlayOptionsInfo(const JSRef<JSObject>& obj, SwiperAutoPlayOptions& swiperAutoPlayOptions)
1809 {
1810     auto stopWhenTouched = obj->GetProperty("stopWhenTouched");
1811     if (stopWhenTouched->IsBoolean()) {
1812         swiperAutoPlayOptions.stopWhenTouched = stopWhenTouched->ToBoolean();
1813     }
1814 }
1815 
SetOnSelected(const JSCallbackInfo & info)1816 void JSSwiper::SetOnSelected(const JSCallbackInfo& info)
1817 {
1818     if (!info[0]->IsFunction()) {
1819         return;
1820     }
1821     auto selectedHandler = AceType::MakeRefPtr<JsEventFunction<SwiperChangeEvent, 1>>(
1822         JSRef<JSFunc>::Cast(info[0]), SwiperChangeEventToJSValue);
1823     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1824     auto onSelected = [executionContext = info.GetExecutionContext(), func = std::move(selectedHandler),
1825                           node = targetNode](const BaseEventInfo* info) {
1826         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
1827         const auto* swiperInfo = TypeInfoHelper::DynamicCast<SwiperChangeEvent>(info);
1828         if (!swiperInfo) {
1829             TAG_LOGW(AceLogTag::ACE_SWIPER, "Swiper onSelected callback execute failed.");
1830             return;
1831         }
1832         ACE_SCORING_EVENT("Swiper.onSelected");
1833         ACE_SCOPED_TRACE("Swiper.onSelected index %d", swiperInfo->GetIndex());
1834         PipelineContext::SetCallBackNode(node);
1835         func->Execute(*swiperInfo);
1836     };
1837     SwiperModel::GetInstance()->SetOnSelected(std::move(onSelected));
1838 }
1839 
SetMaintainVisibleContentPosition(const JSCallbackInfo & info)1840 void JSSwiper::SetMaintainVisibleContentPosition(const JSCallbackInfo& info)
1841 {
1842     if (!info[0]->IsBoolean()) {
1843         SwiperModel::GetInstance()->SetMaintainVisibleContentPosition(false);
1844         return;
1845     }
1846 
1847     SwiperModel::GetInstance()->SetMaintainVisibleContentPosition(info[0]->ToBoolean());
1848 }
SetOnScrollStateChanged(const JSCallbackInfo & info)1849 void JSSwiper::SetOnScrollStateChanged(const JSCallbackInfo& info)
1850 {
1851     if (!info[0]->IsFunction()) {
1852         return;
1853     }
1854     auto scrollStateHandler = AceType::MakeRefPtr<JsEventFunction<SwiperChangeEvent, 1>>(
1855         JSRef<JSFunc>::Cast(info[0]), SwiperChangeEventToJSValue);
1856     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1857     auto onScrollStateChanged = [executionContext = info.GetExecutionContext(), func = std::move(scrollStateHandler),
1858                           node = targetNode](const BaseEventInfo* info) {
1859         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
1860         const auto* scrollStateInfo = TypeInfoHelper::DynamicCast<SwiperChangeEvent>(info);
1861         if (!scrollStateInfo) {
1862             TAG_LOGW(AceLogTag::ACE_SWIPER, "scrollStateInfo invalid, OnScrollStateChanged failed.");
1863             return;
1864         }
1865         PipelineContext::SetCallBackNode(node);
1866         func->Execute(*scrollStateInfo);
1867     };
1868     SwiperModel::GetInstance()->SetOnScrollStateChanged(std::move(onScrollStateChanged));
1869 }
1870 } // namespace OHOS::Ace::Framework
1871