1 /*
2  * Copyright (c) 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 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_marquee_bridge.h"
16 
17 #include "base/geometry/dimension.h"
18 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
19 #include "core/components/common/properties/text_style.h"
20 
21 static const std::string DEFAULT_FONT_WEIGHT = "400";
22 static const std::vector<OHOS::Ace::MarqueeUpdateStrategy> MARQUEE_UPDATE_STRATEGYS = {
23     OHOS::Ace::MarqueeUpdateStrategy::DEFAULT, OHOS::Ace::MarqueeUpdateStrategy::PRESERVE_POSITION
24 };
25 
26 namespace OHOS::Ace::NG {
27 namespace {
28 constexpr int32_t DEFAULT_MARQUEE_LOOP = -1;
SetMarqueeScrollAmount(const EcmaVM * vm,const Local<JSValueRef> & jsVal,ArkUINodeHandle nativeNode)29 void SetMarqueeScrollAmount(const EcmaVM* vm, const Local<JSValueRef>& jsVal, ArkUINodeHandle nativeNode)
30 {
31     if (jsVal->IsNumber()) {
32         bool isNumber = false;
33         auto step = jsVal->GetValueDouble(isNumber);
34         if (GreatNotEqual(step, 0.0)) {
35             double stepOpt = Dimension(step, DimensionUnit::VP).ConvertToPx();
36             GetArkUINodeModifiers()->getMarqueeModifier()->setMarqueeScrollAmount(nativeNode, stepOpt);
37             return;
38         }
39     }
40     GetArkUINodeModifiers()->getMarqueeModifier()->resetMarqueeScrollAmount(nativeNode);
41 }
42 
SetMarqueeLoop(const EcmaVM * vm,const Local<JSValueRef> & jsVal,ArkUINodeHandle nativeNode)43 void SetMarqueeLoop(const EcmaVM* vm, const Local<JSValueRef>& jsVal, ArkUINodeHandle nativeNode)
44 {
45     if (jsVal->IsNumber()) {
46         int32_t loopOpt = 0;
47         bool isNumber = false;
48         auto loopDouble = jsVal->GetValueDouble(isNumber);
49         int32_t loop = DEFAULT_MARQUEE_LOOP;
50         if (GreatNotEqual(loopDouble, 0.0)) {
51             loop = static_cast<int32_t>(loopDouble);
52             if (loop == std::numeric_limits<int32_t>::max() || loop < 0) {
53                 loop = DEFAULT_MARQUEE_LOOP;
54             }
55         }
56         loopOpt = loop;
57         GetArkUINodeModifiers()->getMarqueeModifier()->setMarqueeLoop(nativeNode, loopOpt);
58         return;
59     }
60     GetArkUINodeModifiers()->getMarqueeModifier()->resetMarqueeLoop(nativeNode);
61 }
62 } // namespace
63 
SetAllowScale(ArkUIRuntimeCallInfo * runtimeCallInfo)64 ArkUINativeModuleValue MarqueeBridge::SetAllowScale(ArkUIRuntimeCallInfo* runtimeCallInfo)
65 {
66     EcmaVM* vm = runtimeCallInfo->GetVM();
67     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
68     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
69     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
70     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
71     bool allowScale = secondArg->ToBoolean(vm)->Value();
72     GetArkUINodeModifiers()->getMarqueeModifier()->setMarqueeAllowScale(nativeNode, allowScale);
73     return panda::JSValueRef::Undefined(vm);
74 }
75 
ResetAllowScale(ArkUIRuntimeCallInfo * runtimeCallInfo)76 ArkUINativeModuleValue MarqueeBridge::ResetAllowScale(ArkUIRuntimeCallInfo* runtimeCallInfo)
77 {
78     EcmaVM* vm = runtimeCallInfo->GetVM();
79     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
80     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
81     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
82     GetArkUINodeModifiers()->getMarqueeModifier()->resetMarqueeAllowScale(nativeNode);
83     return panda::JSValueRef::Undefined(vm);
84 }
85 
SetFontWeight(ArkUIRuntimeCallInfo * runtimeCallInfo)86 ArkUINativeModuleValue MarqueeBridge::SetFontWeight(ArkUIRuntimeCallInfo* runtimeCallInfo)
87 {
88     EcmaVM* vm = runtimeCallInfo->GetVM();
89     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
90     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
91     Local<JSValueRef> weightArg = runtimeCallInfo->GetCallArgRef(1);
92     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
93     std::string weight = DEFAULT_FONT_WEIGHT;
94     if (!weightArg->IsNull()) {
95         if (weightArg->IsNumber()) {
96             weight = std::to_string(weightArg->Int32Value(vm));
97         } else if (weightArg->IsString(vm)) {
98             weight = weightArg->ToString(vm)->ToString(vm);
99         }
100     }
101     GetArkUINodeModifiers()->getMarqueeModifier()->setMarqueeFontWeight(nativeNode, weight.c_str());
102     return panda::JSValueRef::Undefined(vm);
103 }
104 
ResetFontWeight(ArkUIRuntimeCallInfo * runtimeCallInfo)105 ArkUINativeModuleValue MarqueeBridge::ResetFontWeight(ArkUIRuntimeCallInfo* runtimeCallInfo)
106 {
107     EcmaVM* vm = runtimeCallInfo->GetVM();
108     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
109     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
110     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
111     GetArkUINodeModifiers()->getMarqueeModifier()->resetMarqueeFontWeight(nativeNode);
112     return panda::JSValueRef::Undefined(vm);
113 }
114 
SetFontFamily(ArkUIRuntimeCallInfo * runtimeCallInfo)115 ArkUINativeModuleValue MarqueeBridge::SetFontFamily(ArkUIRuntimeCallInfo* runtimeCallInfo)
116 {
117     EcmaVM* vm = runtimeCallInfo->GetVM();
118     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
119     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
120     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
121     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
122     if (!secondArg->IsString(vm)) {
123         return panda::JSValueRef::Undefined(vm);
124     }
125     std::string families = secondArg->ToString(vm)->ToString(vm);
126     GetArkUINodeModifiers()->getMarqueeModifier()->setMarqueeFontFamily(nativeNode, families.c_str());
127     return panda::JSValueRef::Undefined(vm);
128 }
129 
ResetFontFamily(ArkUIRuntimeCallInfo * runtimeCallInfo)130 ArkUINativeModuleValue MarqueeBridge::ResetFontFamily(ArkUIRuntimeCallInfo* runtimeCallInfo)
131 {
132     EcmaVM* vm = runtimeCallInfo->GetVM();
133     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
134     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
135     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
136     GetArkUINodeModifiers()->getMarqueeModifier()->resetMarqueeFontFamily(nativeNode);
137     return panda::JSValueRef::Undefined(vm);
138 }
139 
SetFontSize(ArkUIRuntimeCallInfo * runtimeCallInfo)140 ArkUINativeModuleValue MarqueeBridge::SetFontSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
141 {
142     EcmaVM* vm = runtimeCallInfo->GetVM();
143     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
144     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
145     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
146     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
147     CalcDimension fontSize;
148     if (!ArkTSUtils::ParseJsDimensionFp(vm, secondArg, fontSize) || fontSize.IsNegative() ||
149         fontSize.Unit() == DimensionUnit::PERCENT) {
150         GetArkUINodeModifiers()->getMarqueeModifier()->resetMarqueeFontSize(nativeNode);
151     } else {
152         GetArkUINodeModifiers()->getMarqueeModifier()->setMarqueeFontSize(
153             nativeNode, fontSize.Value(), static_cast<int>(fontSize.Unit()));
154     }
155     return panda::JSValueRef::Undefined(vm);
156 }
157 
ResetFontSize(ArkUIRuntimeCallInfo * runtimeCallInfo)158 ArkUINativeModuleValue MarqueeBridge::ResetFontSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
159 {
160     EcmaVM* vm = runtimeCallInfo->GetVM();
161     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
162     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
163     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
164     GetArkUINodeModifiers()->getMarqueeModifier()->resetMarqueeFontSize(nativeNode);
165     return panda::JSValueRef::Undefined(vm);
166 }
167 
SetFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)168 ArkUINativeModuleValue MarqueeBridge::SetFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
169 {
170     EcmaVM* vm = runtimeCallInfo->GetVM();
171     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
172     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
173     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
174     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
175     Color color;
176     if (!ArkTSUtils::ParseJsColorAlpha(vm, secondArg, color)) {
177         GetArkUINodeModifiers()->getMarqueeModifier()->resetMarqueeFontColor(nativeNode);
178     } else {
179         GetArkUINodeModifiers()->getMarqueeModifier()->setMarqueeFontColor(nativeNode, color.GetValue());
180     }
181     return panda::JSValueRef::Undefined(vm);
182 }
183 
ResetFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)184 ArkUINativeModuleValue MarqueeBridge::ResetFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
185 {
186     EcmaVM* vm = runtimeCallInfo->GetVM();
187     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
188     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
189     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
190     GetArkUINodeModifiers()->getMarqueeModifier()->resetMarqueeFontColor(nativeNode);
191     return panda::JSValueRef::Undefined(vm);
192 }
193 
SetMarqueeUpdateStrategy(ArkUIRuntimeCallInfo * runtimeCallInfo)194 ArkUINativeModuleValue MarqueeBridge::SetMarqueeUpdateStrategy(ArkUIRuntimeCallInfo* runtimeCallInfo)
195 {
196     EcmaVM* vm = runtimeCallInfo->GetVM();
197     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
198     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
199     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
200     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
201     auto value = secondArg->ToString(vm)->ToString(vm);
202     static const LinearMapNode<MarqueeUpdateStrategy> marqueeUpdateStrategyTable[] = {
203         { "default", MarqueeUpdateStrategy::DEFAULT },
204         { "preserve_position", MarqueeUpdateStrategy::PRESERVE_POSITION },
205     };
206     auto marqueeUpdateStrategyIter =
207         BinarySearchFindIndex(marqueeUpdateStrategyTable, ArraySize(marqueeUpdateStrategyTable), value.c_str());
208     if (marqueeUpdateStrategyIter != -1) {
209         GetArkUINodeModifiers()->getMarqueeModifier()->setMarqueeUpdateStrategy(nativeNode, marqueeUpdateStrategyIter);
210     } else {
211         GetArkUINodeModifiers()->getMarqueeModifier()->resetMarqueeUpdateStrategy(nativeNode);
212     }
213     return panda::JSValueRef::Undefined(vm);
214 }
215 
ResetMarqueeUpdateStrategy(ArkUIRuntimeCallInfo * runtimeCallInfo)216 ArkUINativeModuleValue MarqueeBridge::ResetMarqueeUpdateStrategy(ArkUIRuntimeCallInfo* runtimeCallInfo)
217 {
218     EcmaVM* vm = runtimeCallInfo->GetVM();
219     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
220     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
221     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
222     GetArkUINodeModifiers()->getMarqueeModifier()->resetMarqueeUpdateStrategy(nativeNode);
223     return panda::JSValueRef::Undefined(vm);
224 }
225 
SetMarqueeOnStart(ArkUIRuntimeCallInfo * runtimeCallInfo)226 ArkUINativeModuleValue MarqueeBridge::SetMarqueeOnStart(ArkUIRuntimeCallInfo* runtimeCallInfo)
227 {
228     EcmaVM *vm = runtimeCallInfo->GetVM();
229     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
230     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
231     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
232     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
233     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
234         GetArkUINodeModifiers()->getMarqueeModifier()->resetMarqueeOnStart(nativeNode);
235         return panda::JSValueRef::Undefined(vm);
236     }
237     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
238     CHECK_NULL_RETURN(frameNode, panda::NativePointerRef::New(vm, nullptr));
239     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
240     std::function<void(void)> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)]() {
241         panda::LocalScope pandaScope(vm);
242         panda::TryCatch trycatch(vm);
243         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
244         func->Call(vm, func.ToLocal(), nullptr, 0);
245     };
246     GetArkUINodeModifiers()->getMarqueeModifier()->setMarqueeOnStart(nativeNode, reinterpret_cast<void*>(&callback));
247     return panda::JSValueRef::Undefined(vm);
248 }
249 
ResetMarqueeOnStart(ArkUIRuntimeCallInfo * runtimeCallInfo)250 ArkUINativeModuleValue MarqueeBridge::ResetMarqueeOnStart(ArkUIRuntimeCallInfo* runtimeCallInfo)
251 {
252     EcmaVM* vm = runtimeCallInfo->GetVM();
253     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
254     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
255     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
256     GetArkUINodeModifiers()->getMarqueeModifier()->resetMarqueeOnStart(nativeNode);
257     return panda::JSValueRef::Undefined(vm);
258 }
259 
SetMarqueeOnBounce(ArkUIRuntimeCallInfo * runtimeCallInfo)260 ArkUINativeModuleValue MarqueeBridge::SetMarqueeOnBounce(ArkUIRuntimeCallInfo* runtimeCallInfo)
261 {
262     EcmaVM *vm = runtimeCallInfo->GetVM();
263     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
264     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
265     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
266     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
267     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
268         GetArkUINodeModifiers()->getMarqueeModifier()->resetMarqueeOnBounce(nativeNode);
269         return panda::JSValueRef::Undefined(vm);
270     }
271     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
272     CHECK_NULL_RETURN(frameNode, panda::NativePointerRef::New(vm, nullptr));
273     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
274     std::function<void(void)> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)]() {
275         panda::LocalScope pandaScope(vm);
276         panda::TryCatch trycatch(vm);
277         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
278         func->Call(vm, func.ToLocal(), nullptr, 0);
279     };
280     GetArkUINodeModifiers()->getMarqueeModifier()->setMarqueeOnBounce(nativeNode, reinterpret_cast<void*>(&callback));
281     return panda::JSValueRef::Undefined(vm);
282 }
283 
ResetMarqueeOnBounce(ArkUIRuntimeCallInfo * runtimeCallInfo)284 ArkUINativeModuleValue MarqueeBridge::ResetMarqueeOnBounce(ArkUIRuntimeCallInfo* runtimeCallInfo)
285 {
286     EcmaVM* vm = runtimeCallInfo->GetVM();
287     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
288     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
289     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
290     GetArkUINodeModifiers()->getMarqueeModifier()->resetMarqueeOnBounce(nativeNode);
291     return panda::JSValueRef::Undefined(vm);
292 }
293 
SetMarqueeOnFinish(ArkUIRuntimeCallInfo * runtimeCallInfo)294 ArkUINativeModuleValue MarqueeBridge::SetMarqueeOnFinish(ArkUIRuntimeCallInfo* runtimeCallInfo)
295 {
296     EcmaVM *vm = runtimeCallInfo->GetVM();
297     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
298     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
299     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
300     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
301     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
302         GetArkUINodeModifiers()->getMarqueeModifier()->resetMarqueeOnFinish(nativeNode);
303         return panda::JSValueRef::Undefined(vm);
304     }
305     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
306     CHECK_NULL_RETURN(frameNode, panda::NativePointerRef::New(vm, nullptr));
307     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
308     std::function<void(void)> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)]() {
309         panda::LocalScope pandaScope(vm);
310         panda::TryCatch trycatch(vm);
311         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
312         func->Call(vm, func.ToLocal(), nullptr, 0);
313     };
314     GetArkUINodeModifiers()->getMarqueeModifier()->setMarqueeOnFinish(nativeNode, reinterpret_cast<void*>(&callback));
315     return panda::JSValueRef::Undefined(vm);
316 }
317 
ResetMarqueeOnFinish(ArkUIRuntimeCallInfo * runtimeCallInfo)318 ArkUINativeModuleValue MarqueeBridge::ResetMarqueeOnFinish(ArkUIRuntimeCallInfo* runtimeCallInfo)
319 {
320     EcmaVM* vm = runtimeCallInfo->GetVM();
321     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
322     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
323     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
324     GetArkUINodeModifiers()->getMarqueeModifier()->resetMarqueeOnFinish(nativeNode);
325     return panda::JSValueRef::Undefined(vm);
326 }
327 
SetInitialize(ArkUIRuntimeCallInfo * runtimeCallInfo)328 ArkUINativeModuleValue MarqueeBridge::SetInitialize(ArkUIRuntimeCallInfo* runtimeCallInfo)
329 {
330     EcmaVM* vm = runtimeCallInfo->GetVM();
331     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
332     Local<JSValueRef> nodeVal = runtimeCallInfo->GetCallArgRef(0);
333     Local<JSValueRef> startVal = runtimeCallInfo->GetCallArgRef(1);
334     Local<JSValueRef> stepVal = runtimeCallInfo->GetCallArgRef(2);
335     Local<JSValueRef> loopVal = runtimeCallInfo->GetCallArgRef(3);
336     Local<JSValueRef> fromStartVal = runtimeCallInfo->GetCallArgRef(4);
337     Local<JSValueRef> srcVal = runtimeCallInfo->GetCallArgRef(5);
338     auto nativeNode = nodePtr(nodeVal->ToNativePointer(vm)->Value());
339     bool fromStart = fromStartVal->IsBoolean() ? fromStartVal->ToBoolean(vm)->Value() : true;
340     SetMarqueeScrollAmount(vm, stepVal, nativeNode);
341     SetMarqueeLoop(vm, loopVal, nativeNode);
342     GetArkUINodeModifiers()->getMarqueeModifier()->setMarqueePlayerStatus(
343         nativeNode, startVal->IsBoolean() ? startVal->ToBoolean(vm)->Value() : false);
344     GetArkUINodeModifiers()->getMarqueeModifier()->setMarqueeDirection(nativeNode,
345         fromStart ? static_cast<int32_t>(MarqueeDirection::LEFT) : static_cast<int32_t>(MarqueeDirection::RIGHT));
346     if (srcVal->IsString(vm)) {
347         GetArkUINodeModifiers()->getMarqueeModifier()->setMarqueeSrcValue(
348             nativeNode, srcVal->ToString(vm)->ToString(vm).c_str());
349     } else {
350         GetArkUINodeModifiers()->getMarqueeModifier()->resetMarqueeSrcValue(nativeNode);
351     }
352     return panda::JSValueRef::Undefined(vm);
353 }
354 } // namespace OHOS::Ace::NG