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