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_text_timer_bridge.h"
16 #include "base/utils/string_utils.h"
17 #include "base/utils/utils.h"
18 #include "frameworks/base/geometry/calc_dimension.h"
19 #include "frameworks/base/geometry/dimension.h"
20 #include "frameworks/bridge/declarative_frontend/engine/jsi/jsi_value_conversions.h"
21 #include "frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
22 #include "frameworks/bridge/declarative_frontend/jsview/js_texttimer.h"
23 #include "core/components/declaration/texttimer/texttimer_declaration.h"
24 #include "core/components_ng/base/frame_node.h"
25 #include "core/components_ng/pattern/texttimer/text_timer_model_ng.h"
26 
27 namespace OHOS::Ace::NG {
28 namespace {
29 constexpr int32_t NUM_0 = 0;
30 constexpr int32_t NUM_1 = 1;
31 constexpr int32_t NUM_2 = 2;
32 constexpr int32_t NUM_3 = 3;
33 constexpr int32_t NUM_4 = 4;
34 constexpr int32_t NUM_5 = 5;
35 constexpr int32_t NUM_6 = 6;
36 constexpr int32_t NUM_7 = 7;
37 constexpr bool DEFAULT_COUNT_DOWN = false;
38 constexpr double MAX_COUNT_DOWN = 86400000.0;
39 const std::string DEFAULT_STR = "-1";
40 const char* TEXTTIMER_NODEPTR_OF_UINODE = "nodePtr_";
41 } // namespace
42 
SetFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)43 ArkUINativeModuleValue TextTimerBridge::SetFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
44 {
45     EcmaVM* vm = runtimeCallInfo->GetVM();
46     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
47     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
48     Local<JSValueRef> paramArg = runtimeCallInfo->GetCallArgRef(NUM_1);
49     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
50     Color color;
51     if (!ArkTSUtils::ParseJsColorAlpha(vm, paramArg, color)) {
52         GetArkUINodeModifiers()->getTextTimerModifier()->resetFontColor(nativeNode);
53     } else {
54         GetArkUINodeModifiers()->getTextTimerModifier()->setFontColor(nativeNode, color.GetValue());
55     }
56     return panda::JSValueRef::Undefined(vm);
57 }
58 
ResetFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)59 ArkUINativeModuleValue TextTimerBridge::ResetFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
60 {
61     EcmaVM* vm = runtimeCallInfo->GetVM();
62     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
63     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
64     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
65     GetArkUINodeModifiers()->getTextTimerModifier()->resetFontColor(nativeNode);
66     return panda::JSValueRef::Undefined(vm);
67 }
68 
SetFontSize(ArkUIRuntimeCallInfo * runtimeCallInfo)69 ArkUINativeModuleValue TextTimerBridge::SetFontSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
70 {
71     EcmaVM* vm = runtimeCallInfo->GetVM();
72     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
73     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
74     Local<JSValueRef> fontSizeArg = runtimeCallInfo->GetCallArgRef(NUM_1);
75     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
76     CalcDimension fontSize;
77     if (!ArkTSUtils::ParseJsDimensionFp(vm, fontSizeArg, fontSize) || fontSize.Value() < 0 ||
78         fontSize.Unit() == DimensionUnit::PERCENT) {
79         GetArkUINodeModifiers()->getTextTimerModifier()->resetFontSize(nativeNode);
80     } else {
81         GetArkUINodeModifiers()->getTextTimerModifier()->setFontSize(
82             nativeNode, fontSize.Value(), static_cast<int32_t>(fontSize.Unit()));
83     }
84     return panda::JSValueRef::Undefined(vm);
85 }
86 
ResetFontSize(ArkUIRuntimeCallInfo * runtimeCallInfo)87 ArkUINativeModuleValue TextTimerBridge::ResetFontSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
88 {
89     EcmaVM* vm = runtimeCallInfo->GetVM();
90     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
91     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
92     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
93     GetArkUINodeModifiers()->getTextTimerModifier()->resetFontSize(nativeNode);
94     return panda::JSValueRef::Undefined(vm);
95 }
96 
SetFontStyle(ArkUIRuntimeCallInfo * runtimeCallInfo)97 ArkUINativeModuleValue TextTimerBridge::SetFontStyle(ArkUIRuntimeCallInfo* runtimeCallInfo)
98 {
99     EcmaVM* vm = runtimeCallInfo->GetVM();
100     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
101     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
102     Local<JSValueRef> paramArg = runtimeCallInfo->GetCallArgRef(NUM_1);
103     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
104     if (paramArg->IsNumber()) {
105         uint32_t fontStyle = paramArg->Uint32Value(vm);
106         if (fontStyle < static_cast<uint32_t>(OHOS::Ace::FontStyle::NORMAL) ||
107             fontStyle > static_cast<uint32_t>(OHOS::Ace::FontStyle::ITALIC)) {
108             fontStyle = static_cast<uint32_t>(OHOS::Ace::FontStyle::NORMAL);
109         }
110         GetArkUINodeModifiers()->getTextTimerModifier()->setFontStyle(nativeNode, fontStyle);
111     } else {
112         GetArkUINodeModifiers()->getTextTimerModifier()->resetFontStyle(nativeNode);
113     }
114     return panda::JSValueRef::Undefined(vm);
115 }
116 
ResetFontStyle(ArkUIRuntimeCallInfo * runtimeCallInfo)117 ArkUINativeModuleValue TextTimerBridge::ResetFontStyle(ArkUIRuntimeCallInfo* runtimeCallInfo)
118 {
119     EcmaVM* vm = runtimeCallInfo->GetVM();
120     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
121     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
122     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
123     GetArkUINodeModifiers()->getTextTimerModifier()->resetFontStyle(nativeNode);
124     return panda::JSValueRef::Undefined(vm);
125 }
126 
SetFontWeight(ArkUIRuntimeCallInfo * runtimeCallInfo)127 ArkUINativeModuleValue TextTimerBridge::SetFontWeight(ArkUIRuntimeCallInfo* runtimeCallInfo)
128 {
129     EcmaVM* vm = runtimeCallInfo->GetVM();
130     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
131     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
132     Local<JSValueRef> fontWeightArg = runtimeCallInfo->GetCallArgRef(NUM_1);
133     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
134     std::string fontWeight;
135     if (!fontWeightArg->IsNull()) {
136         if (fontWeightArg->IsNumber()) {
137             fontWeight = std::to_string(fontWeightArg->Int32Value(vm));
138         } else if (fontWeightArg->IsString(vm)) {
139             fontWeight = fontWeightArg->ToString(vm)->ToString(vm);
140         }
141     }
142     GetArkUINodeModifiers()->getTextTimerModifier()->setFontWeight(nativeNode, fontWeight.c_str());
143     return panda::JSValueRef::Undefined(vm);
144 }
145 
ResetFontWeight(ArkUIRuntimeCallInfo * runtimeCallInfo)146 ArkUINativeModuleValue TextTimerBridge::ResetFontWeight(ArkUIRuntimeCallInfo* runtimeCallInfo)
147 {
148     EcmaVM* vm = runtimeCallInfo->GetVM();
149     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
150     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
151     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
152     GetArkUINodeModifiers()->getTextTimerModifier()->resetFontWeight(nativeNode);
153     return panda::JSValueRef::Undefined(vm);
154 }
155 
SetFontFamily(ArkUIRuntimeCallInfo * runtimeCallInfo)156 ArkUINativeModuleValue TextTimerBridge::SetFontFamily(ArkUIRuntimeCallInfo* runtimeCallInfo)
157 {
158     EcmaVM* vm = runtimeCallInfo->GetVM();
159     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
160     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
161     Local<JSValueRef> fontFamilyArg = runtimeCallInfo->GetCallArgRef(NUM_1);
162     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
163 
164     std::string fontFamilyStr;
165     if (!ArkTSUtils::ParseJsFontFamiliesToString(vm, fontFamilyArg, fontFamilyStr)) {
166         GetArkUINodeModifiers()->getTextTimerModifier()->resetFontFamily(nativeNode);
167         return panda::JSValueRef::Undefined(vm);
168     }
169     GetArkUINodeModifiers()->getTextTimerModifier()->setFontFamily(nativeNode, fontFamilyStr.c_str());
170     return panda::JSValueRef::Undefined(vm);
171 }
172 
ResetFontFamily(ArkUIRuntimeCallInfo * runtimeCallInfo)173 ArkUINativeModuleValue TextTimerBridge::ResetFontFamily(ArkUIRuntimeCallInfo* runtimeCallInfo)
174 {
175     EcmaVM* vm = runtimeCallInfo->GetVM();
176     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
177     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
178     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
179 
180     GetArkUINodeModifiers()->getTextTimerModifier()->resetFontFamily(nativeNode);
181     return panda::JSValueRef::Undefined(vm);
182 }
183 
SetFormat(ArkUIRuntimeCallInfo * runtimeCallInfo)184 ArkUINativeModuleValue TextTimerBridge::SetFormat(ArkUIRuntimeCallInfo* runtimeCallInfo)
185 {
186     EcmaVM* vm = runtimeCallInfo->GetVM();
187     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
188     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
189     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
190     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
191     if (!secondArg->IsString(vm)) {
192         GetArkUINodeModifiers()->getTextTimerModifier()->resetFormat(nativeNode);
193     }
194     std::string format = secondArg->ToString(vm)->ToString(vm);
195     GetArkUINodeModifiers()->getTextTimerModifier()->setFormat(nativeNode, format.c_str());
196     return panda::JSValueRef::Undefined(vm);
197 }
198 
ResetFormat(ArkUIRuntimeCallInfo * runtimeCallInfo)199 ArkUINativeModuleValue TextTimerBridge::ResetFormat(ArkUIRuntimeCallInfo* runtimeCallInfo)
200 {
201     EcmaVM* vm = runtimeCallInfo->GetVM();
202     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
203     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
204     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
205     GetArkUINodeModifiers()->getTextTimerModifier()->resetFormat(nativeNode);
206     return panda::JSValueRef::Undefined(vm);
207 }
208 
SetTextShadow(ArkUIRuntimeCallInfo * runtimeCallInfo)209 ArkUINativeModuleValue TextTimerBridge::SetTextShadow(ArkUIRuntimeCallInfo* runtimeCallInfo)
210 {
211     EcmaVM* vm = runtimeCallInfo->GetVM();
212     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
213     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
214     Local<JSValueRef> lengthArg = runtimeCallInfo->GetCallArgRef(NUM_7);
215     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
216     if (!lengthArg->IsNumber() || lengthArg->Uint32Value(vm) == 0) {
217         return panda::JSValueRef::Undefined(vm);
218     }
219     uint32_t length = lengthArg->Uint32Value(vm);
220     auto radiusArray = std::make_unique<double[]>(length);
221     auto typeArray = std::make_unique<uint32_t[]>(length);
222     auto colorArray = std::make_unique<uint32_t[]>(length);
223     auto offsetXArray = std::make_unique<double[]>(length);
224     auto offsetYArray = std::make_unique<double[]>(length);
225     auto fillArray = std::make_unique<uint32_t[]>(length);
226     bool radiusParseResult = ArkTSUtils::ParseArray<double>(
227         vm, runtimeCallInfo->GetCallArgRef(NUM_1), radiusArray.get(), length, ArkTSUtils::parseShadowRadius);
228     bool typeParseResult = ArkTSUtils::ParseArray<uint32_t>(
229         vm, runtimeCallInfo->GetCallArgRef(NUM_2), typeArray.get(), length, ArkTSUtils::parseShadowType);
230     bool colorParseResult = ArkTSUtils::ParseArray<uint32_t>(
231         vm, runtimeCallInfo->GetCallArgRef(NUM_3), colorArray.get(), length, ArkTSUtils::parseShadowColor);
232     bool offsetXParseResult = ArkTSUtils::ParseArray<double>(
233         vm, runtimeCallInfo->GetCallArgRef(NUM_4), offsetXArray.get(), length, ArkTSUtils::parseShadowOffset);
234     bool offsetYParseResult = ArkTSUtils::ParseArray<double>(
235         vm, runtimeCallInfo->GetCallArgRef(NUM_5), offsetYArray.get(), length, ArkTSUtils::parseShadowOffset);
236     bool fillParseResult = ArkTSUtils::ParseArray<uint32_t>(
237         vm, runtimeCallInfo->GetCallArgRef(NUM_6), fillArray.get(), length, ArkTSUtils::parseShadowFill);
238     if (!radiusParseResult || !colorParseResult || !offsetXParseResult ||
239         !offsetYParseResult || !fillParseResult || !typeParseResult) {
240         return panda::JSValueRef::Undefined(vm);
241     }
242     auto textShadowArray = std::make_unique<ArkUITextShadowStruct[]>(length);
243     CHECK_NULL_RETURN(textShadowArray.get(), panda::JSValueRef::Undefined(vm));
244     for (uint32_t i = 0; i < length; i++) {
245         textShadowArray[i].radius = radiusArray[i];
246         textShadowArray[i].type = typeArray[i];
247         textShadowArray[i].color = colorArray[i];
248         textShadowArray[i].offsetX = offsetXArray[i];
249         textShadowArray[i].offsetY = offsetYArray[i];
250         textShadowArray[i].fill = fillArray[i];
251     }
252     GetArkUINodeModifiers()->getTextTimerModifier()->setTextShadow(nativeNode, textShadowArray.get(), length);
253     return panda::JSValueRef::Undefined(vm);
254 }
255 
ResetTextShadow(ArkUIRuntimeCallInfo * runtimeCallInfo)256 ArkUINativeModuleValue TextTimerBridge::ResetTextShadow(ArkUIRuntimeCallInfo* runtimeCallInfo)
257 {
258     EcmaVM* vm = runtimeCallInfo->GetVM();
259     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
260     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
261     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
262     GetArkUINodeModifiers()->getTextTimerModifier()->resetTextShadow(nativeNode);
263     return panda::JSValueRef::Undefined(vm);
264 }
265 
SetContentModifierBuilder(ArkUIRuntimeCallInfo * runtimeCallInfo)266 ArkUINativeModuleValue TextTimerBridge::SetContentModifierBuilder(ArkUIRuntimeCallInfo* runtimeCallInfo)
267 {
268     EcmaVM* vm = runtimeCallInfo->GetVM();
269     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
270     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
271     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
272     auto* frameNode = reinterpret_cast<FrameNode*>(firstArg->ToNativePointer(vm)->Value());
273     if (!secondArg->IsObject(vm)) {
274         TextTimerModelNG::SetBuilderFunc(frameNode, nullptr);
275         return panda::JSValueRef::Undefined(vm);
276     }
277     panda::CopyableGlobal<panda::ObjectRef> obj(vm, secondArg);
278     TextTimerModelNG::SetBuilderFunc(frameNode,
279         [vm, frameNode, obj = std::move(obj), containerId = Container::CurrentId()](
280             TextTimerConfiguration config) -> RefPtr<FrameNode> {
281             ContainerScope scope(containerId);
282             auto context = ArkTSUtils::GetContext(vm);
283             CHECK_EQUAL_RETURN(context->IsUndefined(), true, nullptr);
284             const char* keysOfTextTimer[] = { "count", "isCountDown", "started", "enabled", "elapsedTime"};
285             Local<JSValueRef> valuesOfTextTimer[] = {
286                 panda::NumberRef::New(vm, config.count_),
287                 panda::BooleanRef::New(vm, config.isCountDown_),
288                 panda::BooleanRef::New(vm, config.started_),
289                 panda::BooleanRef::New(vm, config.enabled_),
290                 panda::NumberRef::New(vm, static_cast<int64_t>(config.elapsedTime_))};
291             auto textTimer = panda::ObjectRef::NewWithNamedProperties(vm,
292                 ArraySize(keysOfTextTimer), keysOfTextTimer, valuesOfTextTimer);
293             textTimer->SetNativePointerFieldCount(vm, 1);
294             textTimer->SetNativePointerField(vm, 0, static_cast<void*>(frameNode));
295             panda::Local<panda::JSValueRef> params[2] = { context, textTimer };
296             LocalScope pandaScope(vm);
297             panda::TryCatch trycatch(vm);
298             auto jsObject = obj.ToLocal();
299             auto makeFunc = jsObject->Get(vm, panda::StringRef::NewFromUtf8(vm, "makeContentModifierNode"));
300             CHECK_EQUAL_RETURN(makeFunc->IsFunction(vm), false, nullptr);
301             panda::Local<panda::FunctionRef> func = makeFunc;
302             auto result = func->Call(vm, jsObject, params, 2);
303             JSNApi::ExecutePendingJob(vm);
304             CHECK_EQUAL_RETURN(result.IsEmpty() || trycatch.HasCaught() || !result->IsObject(vm), true, nullptr);
305             auto resultObj = result->ToObject(vm);
306             panda::Local<panda::JSValueRef> nodeptr =
307                 resultObj->Get(vm, panda::StringRef::NewFromUtf8(vm, TEXTTIMER_NODEPTR_OF_UINODE));
308             CHECK_EQUAL_RETURN(nodeptr.IsEmpty() || nodeptr->IsUndefined() || nodeptr->IsNull(), true, nullptr);
309             auto* frameNode = reinterpret_cast<FrameNode*>(nodeptr->ToNativePointer(vm)->Value());
310             CHECK_NULL_RETURN(frameNode, nullptr);
311             return AceType::Claim(frameNode);
312         });
313     return panda::JSValueRef::Undefined(vm);
314 }
315 
SetTextTimerOptions(ArkUIRuntimeCallInfo * runtimeCallInfo)316 ArkUINativeModuleValue TextTimerBridge::SetTextTimerOptions(ArkUIRuntimeCallInfo* runtimeCallInfo)
317 {
318     EcmaVM* vm = runtimeCallInfo->GetVM();
319     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
320     Local<JSValueRef> nodeVal = runtimeCallInfo->GetCallArgRef(NUM_0);
321     Local<JSValueRef> isCountDownVal = runtimeCallInfo->GetCallArgRef(NUM_1);
322     Local<JSValueRef> countVal = runtimeCallInfo->GetCallArgRef(NUM_2);
323     Local<JSValueRef> controllerVal = runtimeCallInfo->GetCallArgRef(NUM_3);
324     auto nativeNode = nodePtr(nodeVal->ToNativePointer(vm)->Value());
325     bool isCountDown = DEFAULT_COUNT_DOWN;
326     double count = TIME_DEFAULT_COUNT;
327     if (isCountDownVal->IsBoolean()) {
328         isCountDown = isCountDownVal->BooleaValue(vm);
329         if (isCountDown && countVal->IsNumber()) {
330             auto tempCount = countVal->ToNumber(vm)->Value();
331             if (tempCount > 0 && tempCount < MAX_COUNT_DOWN) {
332                 count = tempCount;
333             }
334         }
335     }
336     GetArkUINodeModifiers()->getTextTimerModifier()->setTextTimerOptions(nativeNode, isCountDown, count);
337     auto* frameNode = reinterpret_cast<FrameNode*>(nativeNode);
338     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
339     if (controllerVal->IsObject(vm)) {
340         auto* jsController = Framework::JSRef<Framework::JSObject>(Framework::JSObject(controllerVal->ToObject(vm)))
341                                  ->Unwrap<Framework::JSTextTimerController>();
342         if (jsController) {
343             auto pointer = TextTimerModelNG::GetJSTextTimerController(frameNode);
344             auto preController = static_cast<Framework::JSTextTimerController*>(Referenced::RawPtr(pointer));
345             if (preController) {
346                 preController->SetController(nullptr);
347             }
348             TextTimerModelNG::SetJSTextTimerController(
349                 frameNode, Referenced::Claim(static_cast<Referenced*>(jsController)));
350             auto controller = TextTimerModelNG::InitTextController(frameNode);
351             jsController->SetInstanceId(Container::CurrentId());
352             jsController->SetController(controller);
353         }
354     } else {
355         auto pointer = TextTimerModelNG::GetJSTextTimerController(frameNode);
356         auto preController = static_cast<Framework::JSTextTimerController*>(Referenced::RawPtr(pointer));
357         if (preController) {
358             preController->SetController(nullptr);
359         }
360         TextTimerModelNG::SetJSTextTimerController(frameNode, nullptr);
361     }
362 
363     return panda::JSValueRef::Undefined(vm);
364 }
365 } // namespace OHOS::Ace::NG
366