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