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