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_clock_bridge.h"
16 
17 #include "base/utils/string_utils.h"
18 #include "base/utils/utils.h"
19 #include "bridge/declarative_frontend/ark_theme/theme_apply/js_text_clock_theme.h"
20 #include "core/components_ng/base/frame_node.h"
21 #include "core/components_ng/pattern/text_clock/text_clock_model_ng.h"
22 #include "frameworks/base/geometry/calc_dimension.h"
23 #include "frameworks/base/geometry/dimension.h"
24 #include "frameworks/bridge/declarative_frontend/engine/jsi/jsi_value_conversions.h"
25 #include "frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
26 #include "frameworks/bridge/declarative_frontend/jsview/js_text_clock.h"
27 
28 namespace OHOS::Ace::NG {
29 namespace {
30 constexpr int32_t NUM_0 = 0;
31 constexpr int32_t NUM_1 = 1;
32 constexpr int32_t NUM_2 = 2;
33 constexpr int32_t NUM_3 = 3;
34 constexpr int32_t NUM_4 = 4;
35 constexpr int32_t NUM_5 = 5;
36 constexpr int32_t NUM_6 = 6;
37 constexpr int32_t NUM_7 = 7;
38 constexpr int32_t HOURS_WEST_LOWER_LIMIT = -14;
39 constexpr int32_t HOURS_WEST_UPPER_LIMIT = 12;
40 constexpr float HOURS_WEST[] = { 9.5f, 3.5f, -3.5f, -4.5f, -5.5f, -5.75f, -6.5f, -9.5f, -10.5f, -12.75f };
41 const std::string DEFAULT_STR = "-1";
42 const char* TEXTCLOCK_NODEPTR_OF_UINODE = "nodePtr_";
43 const std::string TEXTCLOCK_DATE_TIME_OPTIONS_HOUR = "hour";
44 const std::string TEXTCLOCK_DATE_TIME_OPTIONS_TWO_DIGIT_VAL = "2-digit";
45 const std::string TEXTCLOCK_DATE_TIME_OPTIONS_NUMERIC_VAL = "numeric";
46 
HoursWestIsValid(int32_t hoursWest)47 bool HoursWestIsValid(int32_t hoursWest)
48 {
49     return !(hoursWest < HOURS_WEST_LOWER_LIMIT || hoursWest > HOURS_WEST_UPPER_LIMIT);
50 }
51 
GetHoursWest(float hoursWest)52 float GetHoursWest(float hoursWest)
53 {
54     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_ELEVEN)) {
55         for (float i : HOURS_WEST) {
56             if (NearEqual(hoursWest, i)) {
57                 return hoursWest;
58             }
59         }
60     }
61 
62     return int32_t(hoursWest);
63 }
64 
RemoveJSController(FrameNode * frameNode,const RefPtr<TextClockController> & controller,Framework::JSTextClockController * jsController)65 void RemoveJSController(
66     FrameNode* frameNode, const RefPtr<TextClockController>& controller, Framework::JSTextClockController* jsController)
67 {
68     CHECK_NULL_VOID(frameNode);
69     CHECK_NULL_VOID(controller);
70     CHECK_NULL_VOID(jsController);
71     auto pointer = TextClockModelNG::GetJSTextClockController(frameNode);
72     auto preController = static_cast<Framework::JSTextClockController*>(Referenced::RawPtr(pointer));
73     if (preController) {
74         preController->removeController(controller);
75     }
76     TextClockModelNG::SetJSTextClockController(frameNode, Referenced::Claim(static_cast<Referenced*>(jsController)));
77 }
78 } // namespace
79 
SetFormat(ArkUIRuntimeCallInfo * runtimeCallInfo)80 ArkUINativeModuleValue TextClockBridge::SetFormat(ArkUIRuntimeCallInfo* runtimeCallInfo)
81 {
82     EcmaVM* vm = runtimeCallInfo->GetVM();
83     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
84     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
85     Local<JSValueRef> formatArg = runtimeCallInfo->GetCallArgRef(NUM_1);
86     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
87     std::string format;
88     ArkTSUtils::GetStringFromJS(vm, formatArg, format);
89     if (0 == format.length() || DEFAULT_STR == format) {
90         GetArkUINodeModifiers()->getTextClockModifier()->resetFormat(nativeNode);
91     } else if (!StringUtils::IsAscii(format) && Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
92         GetArkUINodeModifiers()->getTextClockModifier()->resetFormat(nativeNode);
93     } else {
94         GetArkUINodeModifiers()->getTextClockModifier()->setFormat(nativeNode, format.c_str());
95     }
96     return panda::JSValueRef::Undefined(vm);
97 }
98 
ResetFormat(ArkUIRuntimeCallInfo * runtimeCallInfo)99 ArkUINativeModuleValue TextClockBridge::ResetFormat(ArkUIRuntimeCallInfo* runtimeCallInfo)
100 {
101     EcmaVM* vm = runtimeCallInfo->GetVM();
102     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
103     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
104     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
105     GetArkUINodeModifiers()->getTextClockModifier()->resetFormat(nativeNode);
106     return panda::JSValueRef::Undefined(vm);
107 }
108 
SetFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)109 ArkUINativeModuleValue TextClockBridge::SetFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
110 {
111     EcmaVM* vm = runtimeCallInfo->GetVM();
112     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
113     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
114     Local<JSValueRef> fontColorArg = runtimeCallInfo->GetCallArgRef(NUM_1);
115     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
116     Color color;
117     if (!ArkTSUtils::ParseJsColorAlpha(vm, fontColorArg, color)) {
118         GetArkUINodeModifiers()->getTextClockModifier()->resetFontColor(nativeNode);
119     } else {
120         GetArkUINodeModifiers()->getTextClockModifier()->setFontColor(nativeNode, color.GetValue());
121     }
122     return panda::JSValueRef::Undefined(vm);
123 }
124 
ResetFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)125 ArkUINativeModuleValue TextClockBridge::ResetFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
126 {
127     EcmaVM* vm = runtimeCallInfo->GetVM();
128     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
129     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
130     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
131     GetArkUINodeModifiers()->getTextClockModifier()->resetFontColor(nativeNode);
132     return panda::JSValueRef::Undefined(vm);
133 }
134 
SetFontSize(ArkUIRuntimeCallInfo * runtimeCallInfo)135 ArkUINativeModuleValue TextClockBridge::SetFontSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
136 {
137     EcmaVM* vm = runtimeCallInfo->GetVM();
138     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
139     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
140     Local<JSValueRef> fontSizeArg = runtimeCallInfo->GetCallArgRef(NUM_1);
141     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
142     CalcDimension fontSize;
143     if (!ArkTSUtils::ParseJsDimensionNG(vm, fontSizeArg, fontSize, DimensionUnit::FP, false)
144         || fontSize.Value() < 0 || fontSize.Unit() == DimensionUnit::PERCENT) {
145         GetArkUINodeModifiers()->getTextClockModifier()->resetFontSize(nativeNode);
146     } else {
147         GetArkUINodeModifiers()->getTextClockModifier()->setFontSize(
148             nativeNode, fontSize.Value(), static_cast<int>(fontSize.Unit()));
149     }
150     return panda::JSValueRef::Undefined(vm);
151 }
152 
ResetFontSize(ArkUIRuntimeCallInfo * runtimeCallInfo)153 ArkUINativeModuleValue TextClockBridge::ResetFontSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
154 {
155     EcmaVM* vm = runtimeCallInfo->GetVM();
156     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
157     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
158     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
159     GetArkUINodeModifiers()->getTextClockModifier()->resetFontSize(nativeNode);
160     return panda::JSValueRef::Undefined(vm);
161 }
162 
SetFontStyle(ArkUIRuntimeCallInfo * runtimeCallInfo)163 ArkUINativeModuleValue TextClockBridge::SetFontStyle(ArkUIRuntimeCallInfo* runtimeCallInfo)
164 {
165     EcmaVM* vm = runtimeCallInfo->GetVM();
166     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
167     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
168     Local<JSValueRef> fontStyleArg = runtimeCallInfo->GetCallArgRef(NUM_1);
169     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
170     if (fontStyleArg->IsNumber()) {
171         uint32_t fontStyle = fontStyleArg->Uint32Value(vm);
172         if (fontStyle < static_cast<uint32_t>(OHOS::Ace::FontStyle::NORMAL) ||
173             fontStyle > static_cast<uint32_t>(OHOS::Ace::FontStyle::ITALIC)) {
174             fontStyle = static_cast<uint32_t>(OHOS::Ace::FontStyle::NORMAL);
175         }
176         GetArkUINodeModifiers()->getTextClockModifier()->setFontStyle(nativeNode, fontStyle);
177     } else {
178         GetArkUINodeModifiers()->getTextClockModifier()->resetFontStyle(nativeNode);
179     }
180     return panda::JSValueRef::Undefined(vm);
181 }
182 
ResetFontStyle(ArkUIRuntimeCallInfo * runtimeCallInfo)183 ArkUINativeModuleValue TextClockBridge::ResetFontStyle(ArkUIRuntimeCallInfo* runtimeCallInfo)
184 {
185     EcmaVM* vm = runtimeCallInfo->GetVM();
186     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
187     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
188     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
189     GetArkUINodeModifiers()->getTextClockModifier()->resetFontStyle(nativeNode);
190     return panda::JSValueRef::Undefined(vm);
191 }
192 
SetFontWeight(ArkUIRuntimeCallInfo * runtimeCallInfo)193 ArkUINativeModuleValue TextClockBridge::SetFontWeight(ArkUIRuntimeCallInfo* runtimeCallInfo)
194 {
195     EcmaVM* vm = runtimeCallInfo->GetVM();
196     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
197     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
198     Local<JSValueRef> fontWeightArg = runtimeCallInfo->GetCallArgRef(NUM_1);
199     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
200     std::string fontWeight;
201     if (!fontWeightArg->IsNull()) {
202         if (fontWeightArg->IsNumber()) {
203             fontWeight = std::to_string(fontWeightArg->Int32Value(vm));
204         } else if (fontWeightArg->IsString(vm)) {
205             fontWeight = fontWeightArg->ToString(vm)->ToString(vm);
206         }
207     }
208     GetArkUINodeModifiers()->getTextClockModifier()->setFontWeight(nativeNode, fontWeight.c_str());
209     return panda::JSValueRef::Undefined(vm);
210 }
211 
ResetFontWeight(ArkUIRuntimeCallInfo * runtimeCallInfo)212 ArkUINativeModuleValue TextClockBridge::ResetFontWeight(ArkUIRuntimeCallInfo* runtimeCallInfo)
213 {
214     EcmaVM* vm = runtimeCallInfo->GetVM();
215     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
216     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
217     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
218     GetArkUINodeModifiers()->getTextClockModifier()->resetFontWeight(nativeNode);
219     return panda::JSValueRef::Undefined(vm);
220 }
221 
SetFontFamily(ArkUIRuntimeCallInfo * runtimeCallInfo)222 ArkUINativeModuleValue TextClockBridge::SetFontFamily(ArkUIRuntimeCallInfo* runtimeCallInfo)
223 {
224     EcmaVM* vm = runtimeCallInfo->GetVM();
225     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
226     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
227     Local<JSValueRef> fontFamilyArg = runtimeCallInfo->GetCallArgRef(NUM_1);
228     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
229 
230     std::string fontFamilyStr;
231     if (!ArkTSUtils::ParseJsFontFamiliesToString(vm, fontFamilyArg, fontFamilyStr)) {
232         GetArkUINodeModifiers()->getTextClockModifier()->resetFontFamily(nativeNode);
233         return panda::JSValueRef::Undefined(vm);
234     }
235     GetArkUINodeModifiers()->getTextClockModifier()->setFontFamily(nativeNode, fontFamilyStr.c_str());
236     return panda::JSValueRef::Undefined(vm);
237 }
238 
ResetFontFamily(ArkUIRuntimeCallInfo * runtimeCallInfo)239 ArkUINativeModuleValue TextClockBridge::ResetFontFamily(ArkUIRuntimeCallInfo* runtimeCallInfo)
240 {
241     EcmaVM* vm = runtimeCallInfo->GetVM();
242     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
243     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
244     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
245 
246     GetArkUINodeModifiers()->getTextClockModifier()->resetFontFamily(nativeNode);
247     return panda::JSValueRef::Undefined(vm);
248 }
249 
SetFontFeature(ArkUIRuntimeCallInfo * runtimeCallInfo)250 ArkUINativeModuleValue TextClockBridge::SetFontFeature(ArkUIRuntimeCallInfo* runtimeCallInfo)
251 {
252     EcmaVM* vm = runtimeCallInfo->GetVM();
253     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
254     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
255     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
256     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
257     if (secondArg->IsString(vm)) {
258         auto value = secondArg->ToString(vm)->ToString(vm);
259         GetArkUINodeModifiers()->getTextClockModifier()->setFontFeature(nativeNode, value.c_str());
260     } else {
261         GetArkUINodeModifiers()->getTextClockModifier()->resetFontFeature(nativeNode);
262     }
263     return panda::JSValueRef::Undefined(vm);
264 }
265 
ResetFontFeature(ArkUIRuntimeCallInfo * runtimeCallInfo)266 ArkUINativeModuleValue TextClockBridge::ResetFontFeature(ArkUIRuntimeCallInfo* runtimeCallInfo)
267 {
268     EcmaVM* vm = runtimeCallInfo->GetVM();
269     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
270     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
271     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
272     GetArkUINodeModifiers()->getTextClockModifier()->resetFontFeature(nativeNode);
273     return panda::JSValueRef::Undefined(vm);
274 }
275 
SetTextShadow(ArkUIRuntimeCallInfo * runtimeCallInfo)276 ArkUINativeModuleValue TextClockBridge::SetTextShadow(ArkUIRuntimeCallInfo* runtimeCallInfo)
277 {
278     EcmaVM* vm = runtimeCallInfo->GetVM();
279     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
280     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
281     Local<JSValueRef> lengthArg = runtimeCallInfo->GetCallArgRef(NUM_7);
282     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
283     if (!lengthArg->IsNumber() || lengthArg->Uint32Value(vm) == 0) {
284         return panda::JSValueRef::Undefined(vm);
285     }
286     uint32_t length = lengthArg->Uint32Value(vm);
287     auto radiusArray = std::make_unique<double[]>(length);
288     auto typeArray = std::make_unique<uint32_t[]>(length);
289     auto colorArray = std::make_unique<uint32_t[]>(length);
290     auto offsetXArray = std::make_unique<double[]>(length);
291     auto offsetYArray = std::make_unique<double[]>(length);
292     auto fillArray = std::make_unique<uint32_t[]>(length);
293     bool radiusParseResult = ArkTSUtils::ParseArray<double>(
294         vm, runtimeCallInfo->GetCallArgRef(NUM_1), radiusArray.get(), length, ArkTSUtils::parseShadowRadius);
295     bool typeParseResult = ArkTSUtils::ParseArray<uint32_t>(
296         vm, runtimeCallInfo->GetCallArgRef(NUM_2), typeArray.get(), length, ArkTSUtils::parseShadowType);
297     bool colorParseResult = ArkTSUtils::ParseArray<uint32_t>(
298         vm, runtimeCallInfo->GetCallArgRef(NUM_3), colorArray.get(), length, ArkTSUtils::parseShadowColor);
299     bool offsetXParseResult = ArkTSUtils::ParseArray<double>(
300         vm, runtimeCallInfo->GetCallArgRef(NUM_4), offsetXArray.get(), length, ArkTSUtils::parseShadowOffset);
301     bool offsetYParseResult = ArkTSUtils::ParseArray<double>(
302         vm, runtimeCallInfo->GetCallArgRef(NUM_5), offsetYArray.get(), length, ArkTSUtils::parseShadowOffset);
303     bool fillParseResult = ArkTSUtils::ParseArray<uint32_t>(
304         vm, runtimeCallInfo->GetCallArgRef(NUM_6), fillArray.get(), length, ArkTSUtils::parseShadowFill);
305     if (!radiusParseResult || !colorParseResult || !offsetXParseResult ||
306         !offsetYParseResult || !fillParseResult || !typeParseResult) {
307         return panda::JSValueRef::Undefined(vm);
308     }
309     auto textShadowArray = std::make_unique<ArkUITextShadowStruct[]>(length);
310     CHECK_NULL_RETURN(textShadowArray.get(), panda::JSValueRef::Undefined(vm));
311     for (uint32_t i = 0; i < length; i++) {
312         textShadowArray[i].radius = radiusArray[i];
313         textShadowArray[i].type = typeArray[i];
314         textShadowArray[i].color = colorArray[i];
315         textShadowArray[i].offsetX = offsetXArray[i];
316         textShadowArray[i].offsetY = offsetYArray[i];
317         textShadowArray[i].fill = fillArray[i];
318     }
319     GetArkUINodeModifiers()->getTextClockModifier()->setTextShadow(nativeNode, textShadowArray.get(), length);
320     return panda::JSValueRef::Undefined(vm);
321 }
322 
ResetTextShadow(ArkUIRuntimeCallInfo * runtimeCallInfo)323 ArkUINativeModuleValue TextClockBridge::ResetTextShadow(ArkUIRuntimeCallInfo* runtimeCallInfo)
324 {
325     EcmaVM* vm = runtimeCallInfo->GetVM();
326     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
327     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
328     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
329     GetArkUINodeModifiers()->getTextClockModifier()->resetTextShadow(nativeNode);
330     return panda::JSValueRef::Undefined(vm);
331 }
332 
SetContentModifierBuilder(ArkUIRuntimeCallInfo * runtimeCallInfo)333 ArkUINativeModuleValue TextClockBridge::SetContentModifierBuilder(ArkUIRuntimeCallInfo* runtimeCallInfo)
334 {
335     EcmaVM* vm = runtimeCallInfo->GetVM();
336     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
337     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
338     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
339     void* nativeNode = firstArg->ToNativePointer(vm)->Value();
340     auto* frameNode = reinterpret_cast<FrameNode*>(nativeNode);
341     if (!secondArg->IsObject(vm)) {
342         TextClockModelNG::SetBuilderFunc(frameNode, nullptr);
343         return panda::JSValueRef::Undefined(vm);
344     }
345     panda::CopyableGlobal<panda::ObjectRef> obj(vm, secondArg);
346     TextClockModelNG::SetBuilderFunc(frameNode,
347         [vm, frameNode, obj = std::move(obj), containerId = Container::CurrentId()](
348             TextClockConfiguration config) -> RefPtr<FrameNode> {
349             ContainerScope scope(containerId);
350             auto context = ArkTSUtils::GetContext(vm);
351             CHECK_EQUAL_RETURN(context->IsUndefined(), true, nullptr);
352             const char* keysOfTextClock[] = { "timeZoneOffset", "started", "enabled", "timeValue" };
353             Local<JSValueRef> valuesOfTextClock[] = { panda::NumberRef::New(vm, config.timeZoneOffset_),
354                 panda::BooleanRef::New(vm, config.started_), panda::BooleanRef::New(vm, config.enabled_),
355                 panda::NumberRef::New(vm, config.timeValue_) };
356             auto textClock = panda::ObjectRef::NewWithNamedProperties(
357                 vm, ArraySize(keysOfTextClock), keysOfTextClock, valuesOfTextClock);
358             obj->SetNativePointerFieldCount(vm, 1);
359             obj->SetNativePointerField(vm, 0, static_cast<void*>(frameNode));
360             panda::Local<panda::JSValueRef> params[NUM_2] = { context, textClock };
361             LocalScope pandaScope(vm);
362             panda::TryCatch trycatch(vm);
363             auto jsObject = obj.ToLocal();
364             auto makeFunc = jsObject->Get(vm, panda::StringRef::NewFromUtf8(vm, "makeContentModifierNode"));
365             CHECK_EQUAL_RETURN(makeFunc->IsFunction(vm), false, nullptr);
366             panda::Local<panda::FunctionRef> func = makeFunc;
367             auto result = func->Call(vm, jsObject, params, NUM_2);
368             JSNApi::ExecutePendingJob(vm);
369             CHECK_EQUAL_RETURN(result.IsEmpty() || trycatch.HasCaught() || !result->IsObject(vm), true, nullptr);
370             auto resultObj = result->ToObject(vm);
371             panda::Local<panda::JSValueRef> nodeptr =
372                 resultObj->Get(vm, panda::StringRef::NewFromUtf8(vm, TEXTCLOCK_NODEPTR_OF_UINODE));
373             CHECK_EQUAL_RETURN(nodeptr.IsEmpty() || nodeptr->IsUndefined() || nodeptr->IsNull(), true, nullptr);
374             auto* frameNode = reinterpret_cast<FrameNode*>(nodeptr->ToNativePointer(vm)->Value());
375             CHECK_NULL_RETURN(frameNode, nullptr);
376             return AceType::Claim(frameNode);
377         });
378     return panda::JSValueRef::Undefined(vm);
379 }
SetDateTimeOptions(ArkUIRuntimeCallInfo * runtimeCallInfo)380 ArkUINativeModuleValue TextClockBridge::SetDateTimeOptions(ArkUIRuntimeCallInfo* runtimeCallInfo)
381 {
382     EcmaVM* vm = runtimeCallInfo->GetVM();
383     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
384     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
385     Local<JSValueRef> hourArg = runtimeCallInfo->GetCallArgRef(NUM_1);
386     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
387     ZeroPrefixType hourType = ZeroPrefixType::AUTO;
388     std::string hour = TEXTCLOCK_DATE_TIME_OPTIONS_HOUR;
389     if (hourArg->IsString(vm)) {
390         std::string hour = hourArg->ToString(vm)->ToString(vm);
391         if (hour == TEXTCLOCK_DATE_TIME_OPTIONS_TWO_DIGIT_VAL) {
392             hourType = ZeroPrefixType::SHOW;
393         } else if (hour == TEXTCLOCK_DATE_TIME_OPTIONS_NUMERIC_VAL) {
394             hourType = ZeroPrefixType::HIDE;
395         }
396     }
397     GetArkUINodeModifiers()->getTextClockModifier()->setDateTimeOptions(
398         nativeNode, static_cast<ArkUI_Int32>(hourType));
399     return panda::JSValueRef::Undefined(vm);
400 }
401 
ResetDateTimeOptions(ArkUIRuntimeCallInfo * runtimeCallInfo)402 ArkUINativeModuleValue TextClockBridge::ResetDateTimeOptions(ArkUIRuntimeCallInfo* runtimeCallInfo)
403 {
404     EcmaVM* vm = runtimeCallInfo->GetVM();
405     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
406     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
407     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
408     GetArkUINodeModifiers()->getTextClockModifier()->resetDateTimeOptions(nativeNode);
409     return panda::JSValueRef::Undefined(vm);
410 }
411 
SetTextClockTimeZoneOffset(ArkUIRuntimeCallInfo * runtimeCallInfo)412 ArkUINativeModuleValue TextClockBridge::SetTextClockTimeZoneOffset(ArkUIRuntimeCallInfo* runtimeCallInfo)
413 {
414     EcmaVM* vm = runtimeCallInfo->GetVM();
415     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
416     Local<JSValueRef> nodeVal = runtimeCallInfo->GetCallArgRef(NUM_0);
417     Local<JSValueRef> hourWestVal = runtimeCallInfo->GetCallArgRef(NUM_1);
418     auto nativeNode = nodePtr(nodeVal->ToNativePointer(vm)->Value());
419     auto themeColors = Framework::JSThemeUtils::GetThemeColors();
420     float hourWest = NAN;
421     if (hourWestVal->IsNumber() && HoursWestIsValid(hourWestVal->Int32Value(vm))) {
422         hourWest = GetHoursWest(hourWestVal->ToNumber(vm)->Value());
423     }
424     if (themeColors.has_value()) {
425         GetArkUINodeModifiers()->getTextClockModifier()->setFontColor(
426             nativeNode, themeColors->FontSecondary().GetValue());
427     }
428     GetArkUINodeModifiers()->getTextClockModifier()->setTextClockTimeZoneOffset(nativeNode, hourWest);
429     return panda::JSValueRef::Undefined(vm);
430 }
431 
SetTextClockController(ArkUIRuntimeCallInfo * runtimeCallInfo)432 ArkUINativeModuleValue TextClockBridge::SetTextClockController(ArkUIRuntimeCallInfo* runtimeCallInfo)
433 {
434     EcmaVM* vm = runtimeCallInfo->GetVM();
435     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
436     Local<JSValueRef> nodeVal = runtimeCallInfo->GetCallArgRef(NUM_0);
437     Local<JSValueRef> controllerVal = runtimeCallInfo->GetCallArgRef(NUM_1);
438     auto nativeNode = nodePtr(nodeVal->ToNativePointer(vm)->Value());
439     auto themeColors = Framework::JSThemeUtils::GetThemeColors();
440     if (themeColors.has_value()) {
441         GetArkUINodeModifiers()->getTextClockModifier()->setFontColor(
442             nativeNode, themeColors->FontSecondary().GetValue());
443     }
444 
445     auto* frameNode = reinterpret_cast<FrameNode*>(nativeNode);
446     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
447     auto controller = TextClockModelNG::InitTextController(frameNode);
448     if (!controllerVal->IsUndefined() && !controllerVal->IsNull() && controllerVal->IsObject(vm)) {
449         auto* jsController = Framework::JSRef<Framework::JSObject>(Framework::JSObject(controllerVal->ToObject(vm)))
450                                  ->Unwrap<Framework::JSTextClockController>();
451         if (jsController) {
452             jsController->SetInstanceId(Container::CurrentId());
453             if (controller) {
454                 RemoveJSController(frameNode, controller, jsController);
455                 jsController->AddController(controller);
456             }
457         }
458     } else if (controller) {
459         auto pointer = TextClockModelNG::GetJSTextClockController(frameNode);
460         auto preController = static_cast<Framework::JSTextClockController*>(Referenced::RawPtr(pointer));
461         if (preController) {
462             preController->removeController(controller);
463         }
464         TextClockModelNG::SetJSTextClockController(frameNode, nullptr);
465     }
466     return panda::JSValueRef::Undefined(vm);
467 }
468 } // namespace OHOS::Ace::NG
469