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