• 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     RefPtr<ResourceObject> formatResObj;
88     ArkTSUtils::ParseJsString(vm, formatArg, format, formatResObj);
89     auto nodeModifiers = GetArkUINodeModifiers();
90     CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
91     if (0 == format.length() || DEFAULT_STR == format) {
92         nodeModifiers->getTextClockModifier()->resetFormat(nativeNode);
93     } else if (!StringUtils::IsAscii(format) && Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
94         nodeModifiers->getTextClockModifier()->resetFormat(nativeNode);
95     } else {
96         auto formatRawPtr = AceType::RawPtr(formatResObj);
97         nodeModifiers->getTextClockModifier()->setFormatRes(nativeNode, format.c_str(), formatRawPtr);
98     }
99     return panda::JSValueRef::Undefined(vm);
100 }
101 
ResetFormat(ArkUIRuntimeCallInfo * runtimeCallInfo)102 ArkUINativeModuleValue TextClockBridge::ResetFormat(ArkUIRuntimeCallInfo* runtimeCallInfo)
103 {
104     EcmaVM* vm = runtimeCallInfo->GetVM();
105     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
106     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
107     CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
108     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
109     auto nodeModifiers = GetArkUINodeModifiers();
110     CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
111     nodeModifiers->getTextClockModifier()->resetFormat(nativeNode);
112     return panda::JSValueRef::Undefined(vm);
113 }
114 
SetFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)115 ArkUINativeModuleValue TextClockBridge::SetFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
116 {
117     EcmaVM* vm = runtimeCallInfo->GetVM();
118     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
119     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
120     Local<JSValueRef> fontColorArg = runtimeCallInfo->GetCallArgRef(NUM_1);
121     CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
122     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
123     Color color;
124     RefPtr<ResourceObject> fontColorResObj;
125     auto nodeModifiers = GetArkUINodeModifiers();
126     CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
127     auto nodeInfo = ArkTSUtils::MakeNativeNodeInfo(nativeNode);
128     if (!ArkTSUtils::ParseJsColorAlpha(vm, fontColorArg, color, fontColorResObj, nodeInfo)) {
129         nodeModifiers->getTextClockModifier()->resetFontColor(nativeNode);
130     } else {
131         auto fontColorRawPtr = AceType::RawPtr(fontColorResObj);
132         nodeModifiers->getTextClockModifier()->setFontColorRes(nativeNode, color.GetValue(), fontColorRawPtr);
133     }
134     return panda::JSValueRef::Undefined(vm);
135 }
136 
ResetFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)137 ArkUINativeModuleValue TextClockBridge::ResetFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
138 {
139     EcmaVM* vm = runtimeCallInfo->GetVM();
140     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
141     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
142     CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
143     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
144     auto nodeModifiers = GetArkUINodeModifiers();
145     CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
146     nodeModifiers->getTextClockModifier()->resetFontColor(nativeNode);
147     return panda::JSValueRef::Undefined(vm);
148 }
149 
SetFontSize(ArkUIRuntimeCallInfo * runtimeCallInfo)150 ArkUINativeModuleValue TextClockBridge::SetFontSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
151 {
152     EcmaVM* vm = runtimeCallInfo->GetVM();
153     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
154     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
155     Local<JSValueRef> fontSizeArg = runtimeCallInfo->GetCallArgRef(NUM_1);
156     CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
157     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
158     CalcDimension fontSize;
159     RefPtr<ResourceObject> fontSizeResObj;
160     auto nodeModifiers = GetArkUINodeModifiers();
161     CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
162     if (!ArkTSUtils::ParseJsDimensionNG(vm, fontSizeArg, fontSize, DimensionUnit::FP, fontSizeResObj, false) ||
163         fontSize.Value() < 0 || fontSize.Unit() == DimensionUnit::PERCENT) {
164         nodeModifiers->getTextClockModifier()->resetFontSize(nativeNode);
165     } else {
166         auto fontSizeRawPtr = AceType::RawPtr(fontSizeResObj);
167         nodeModifiers->getTextClockModifier()->setFontSizeRes(
168             nativeNode, fontSize.Value(), static_cast<int>(fontSize.Unit()), fontSizeRawPtr);
169     }
170     return panda::JSValueRef::Undefined(vm);
171 }
172 
ResetFontSize(ArkUIRuntimeCallInfo * runtimeCallInfo)173 ArkUINativeModuleValue TextClockBridge::ResetFontSize(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     CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
179     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
180     auto nodeModifiers = GetArkUINodeModifiers();
181     CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
182     nodeModifiers->getTextClockModifier()->resetFontSize(nativeNode);
183     return panda::JSValueRef::Undefined(vm);
184 }
185 
SetFontStyle(ArkUIRuntimeCallInfo * runtimeCallInfo)186 ArkUINativeModuleValue TextClockBridge::SetFontStyle(ArkUIRuntimeCallInfo* runtimeCallInfo)
187 {
188     EcmaVM* vm = runtimeCallInfo->GetVM();
189     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
190     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
191     Local<JSValueRef> fontStyleArg = runtimeCallInfo->GetCallArgRef(NUM_1);
192     CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
193     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
194     auto nodeModifiers = GetArkUINodeModifiers();
195     CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
196     if (fontStyleArg->IsNumber()) {
197         uint32_t fontStyle = fontStyleArg->Uint32Value(vm);
198         if (fontStyle < static_cast<uint32_t>(OHOS::Ace::FontStyle::NORMAL) ||
199             fontStyle > static_cast<uint32_t>(OHOS::Ace::FontStyle::ITALIC)) {
200             fontStyle = static_cast<uint32_t>(OHOS::Ace::FontStyle::NORMAL);
201         }
202         nodeModifiers->getTextClockModifier()->setFontStyle(nativeNode, fontStyle);
203     } else {
204         nodeModifiers->getTextClockModifier()->resetFontStyle(nativeNode);
205     }
206     return panda::JSValueRef::Undefined(vm);
207 }
208 
ResetFontStyle(ArkUIRuntimeCallInfo * runtimeCallInfo)209 ArkUINativeModuleValue TextClockBridge::ResetFontStyle(ArkUIRuntimeCallInfo* runtimeCallInfo)
210 {
211     EcmaVM* vm = runtimeCallInfo->GetVM();
212     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
213     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
214     CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
215     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
216     auto nodeModifiers = GetArkUINodeModifiers();
217     CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
218     nodeModifiers->getTextClockModifier()->resetFontStyle(nativeNode);
219     return panda::JSValueRef::Undefined(vm);
220 }
221 
SetFontWeight(ArkUIRuntimeCallInfo * runtimeCallInfo)222 ArkUINativeModuleValue TextClockBridge::SetFontWeight(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> fontWeightArg = runtimeCallInfo->GetCallArgRef(NUM_1);
228     CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
229     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
230     std::string fontWeight;
231     RefPtr<ResourceObject> fontWeightResObj;
232     if (!fontWeightArg->IsNull()) {
233         if (fontWeightArg->IsNumber()) {
234             fontWeight = std::to_string(fontWeightArg->Int32Value(vm));
235         } else {
236             ArkTSUtils::ParseJsString(vm, fontWeightArg, fontWeight, fontWeightResObj);
237         }
238     }
239     auto nodeModifiers = GetArkUINodeModifiers();
240     CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
241     auto fontWeightRawPtr = AceType::RawPtr(fontWeightResObj);
242     nodeModifiers->getTextClockModifier()->setFontWeightRes(nativeNode, fontWeight.c_str(), fontWeightRawPtr);
243     return panda::JSValueRef::Undefined(vm);
244 }
245 
ResetFontWeight(ArkUIRuntimeCallInfo * runtimeCallInfo)246 ArkUINativeModuleValue TextClockBridge::ResetFontWeight(ArkUIRuntimeCallInfo* runtimeCallInfo)
247 {
248     EcmaVM* vm = runtimeCallInfo->GetVM();
249     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
250     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
251     CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
252     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
253     auto nodeModifiers = GetArkUINodeModifiers();
254     CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
255     nodeModifiers->getTextClockModifier()->resetFontWeight(nativeNode);
256     return panda::JSValueRef::Undefined(vm);
257 }
258 
SetFontFamily(ArkUIRuntimeCallInfo * runtimeCallInfo)259 ArkUINativeModuleValue TextClockBridge::SetFontFamily(ArkUIRuntimeCallInfo* runtimeCallInfo)
260 {
261     EcmaVM* vm = runtimeCallInfo->GetVM();
262     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
263     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
264     Local<JSValueRef> fontFamilyArg = runtimeCallInfo->GetCallArgRef(NUM_1);
265     CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
266     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
267 
268     std::string fontFamilyStr;
269     RefPtr<ResourceObject> fontFamilyResObj;
270     auto nodeModifiers = GetArkUINodeModifiers();
271     CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
272     if (!ArkTSUtils::ParseJsFontFamiliesToString(vm, fontFamilyArg, fontFamilyStr, fontFamilyResObj)) {
273         nodeModifiers->getTextClockModifier()->resetFontFamily(nativeNode);
274         return panda::JSValueRef::Undefined(vm);
275     }
276     auto fontFamilyRawPtr = AceType::RawPtr(fontFamilyResObj);
277     nodeModifiers->getTextClockModifier()->setFontFamilyRes(nativeNode, fontFamilyStr.c_str(), fontFamilyRawPtr);
278     return panda::JSValueRef::Undefined(vm);
279 }
280 
ResetFontFamily(ArkUIRuntimeCallInfo * runtimeCallInfo)281 ArkUINativeModuleValue TextClockBridge::ResetFontFamily(ArkUIRuntimeCallInfo* runtimeCallInfo)
282 {
283     EcmaVM* vm = runtimeCallInfo->GetVM();
284     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
285     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
286     CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
287     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
288 
289     auto nodeModifiers = GetArkUINodeModifiers();
290     CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
291     nodeModifiers->getTextClockModifier()->resetFontFamily(nativeNode);
292     return panda::JSValueRef::Undefined(vm);
293 }
294 
SetFontFeature(ArkUIRuntimeCallInfo * runtimeCallInfo)295 ArkUINativeModuleValue TextClockBridge::SetFontFeature(ArkUIRuntimeCallInfo* runtimeCallInfo)
296 {
297     EcmaVM* vm = runtimeCallInfo->GetVM();
298     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
299     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
300     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
301     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
302     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
303     auto nodeModifiers = GetArkUINodeModifiers();
304     CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
305     if (secondArg->IsString(vm)) {
306         auto value = secondArg->ToString(vm)->ToString(vm);
307         nodeModifiers->getTextClockModifier()->setFontFeature(nativeNode, value.c_str());
308     } else {
309         nodeModifiers->getTextClockModifier()->resetFontFeature(nativeNode);
310     }
311     return panda::JSValueRef::Undefined(vm);
312 }
313 
ResetFontFeature(ArkUIRuntimeCallInfo * runtimeCallInfo)314 ArkUINativeModuleValue TextClockBridge::ResetFontFeature(ArkUIRuntimeCallInfo* runtimeCallInfo)
315 {
316     EcmaVM* vm = runtimeCallInfo->GetVM();
317     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
318     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
319     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
320     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
321     auto nodeModifiers = GetArkUINodeModifiers();
322     CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
323     nodeModifiers->getTextClockModifier()->resetFontFeature(nativeNode);
324     return panda::JSValueRef::Undefined(vm);
325 }
326 
SetTextShadow(ArkUIRuntimeCallInfo * runtimeCallInfo)327 ArkUINativeModuleValue TextClockBridge::SetTextShadow(ArkUIRuntimeCallInfo* runtimeCallInfo)
328 {
329     EcmaVM* vm = runtimeCallInfo->GetVM();
330     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
331     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
332     Local<JSValueRef> lengthArg = runtimeCallInfo->GetCallArgRef(NUM_7);
333     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
334     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
335     if (!lengthArg->IsNumber() || lengthArg->Uint32Value(vm) == 0) {
336         return panda::JSValueRef::Undefined(vm);
337     }
338     uint32_t length = lengthArg->Uint32Value(vm);
339     auto radiusArray = std::make_unique<double[]>(length);
340     auto typeArray = std::make_unique<uint32_t[]>(length);
341     auto colorArray = std::make_unique<uint32_t[]>(length);
342     auto offsetXArray = std::make_unique<double[]>(length);
343     auto offsetYArray = std::make_unique<double[]>(length);
344     auto fillArray = std::make_unique<uint32_t[]>(length);
345     std::vector<RefPtr<ResourceObject>> radiusResObjArray;
346     std::vector<RefPtr<ResourceObject>> colorResObjArray;
347     std::vector<RefPtr<ResourceObject>> offsetXResObjArray;
348     std::vector<RefPtr<ResourceObject>> offsetYResObjArray;
349     bool radiusParseResult = ArkTSUtils::ParseArrayWithResObj<double>(vm, runtimeCallInfo->GetCallArgRef(NUM_1),
350         radiusArray.get(), length, ArkTSUtils::parseShadowRadiusWithResObj, radiusResObjArray);
351     bool typeParseResult = ArkTSUtils::ParseArray<uint32_t>(
352         vm, runtimeCallInfo->GetCallArgRef(NUM_2), typeArray.get(), length, ArkTSUtils::parseShadowType);
353     bool colorParseResult = ArkTSUtils::ParseArrayWithResObj<uint32_t>(vm, runtimeCallInfo->GetCallArgRef(NUM_3),
354         colorArray.get(), length, ArkTSUtils::parseShadowColorWithResObj, colorResObjArray);
355     bool offsetXParseResult = ArkTSUtils::ParseArrayWithResObj<double>(vm, runtimeCallInfo->GetCallArgRef(NUM_4),
356         offsetXArray.get(), length, ArkTSUtils::parseShadowOffsetWithResObj, offsetXResObjArray);
357     bool offsetYParseResult = ArkTSUtils::ParseArrayWithResObj<double>(vm, runtimeCallInfo->GetCallArgRef(NUM_5),
358         offsetYArray.get(), length, ArkTSUtils::parseShadowOffsetWithResObj, offsetYResObjArray);
359     bool fillParseResult = ArkTSUtils::ParseArray<uint32_t>(
360         vm, runtimeCallInfo->GetCallArgRef(NUM_6), fillArray.get(), length, ArkTSUtils::parseShadowFill);
361     if (!radiusParseResult || !colorParseResult || !offsetXParseResult ||
362         !offsetYParseResult || !fillParseResult || !typeParseResult) {
363         return panda::JSValueRef::Undefined(vm);
364     }
365     auto textShadowArray = std::make_unique<ArkUITextShadowStruct[]>(length);
366     auto textShadowResArray = std::make_unique<ArkUITextShadowResStruct[]>(length);
367     CHECK_NULL_RETURN(textShadowArray && textShadowResArray, panda::JSValueRef::Undefined(vm));
368     for (uint32_t i = 0; i < length; i++) {
369         textShadowArray[i] = { radiusArray[i], typeArray[i], colorArray[i], offsetXArray[i], offsetYArray[i],
370             fillArray[i] };
371         textShadowResArray[i] = { AceType::RawPtr(radiusResObjArray[i]), AceType::RawPtr(colorResObjArray[i]),
372             AceType::RawPtr(offsetXResObjArray[i]), AceType::RawPtr(offsetYResObjArray[i]) };
373     }
374     GetArkUINodeModifiers()->getTextClockModifier()->setTextShadowRes(
375         nativeNode, textShadowArray.get(), textShadowResArray.get(), length);
376     return panda::JSValueRef::Undefined(vm);
377 }
378 
ResetTextShadow(ArkUIRuntimeCallInfo * runtimeCallInfo)379 ArkUINativeModuleValue TextClockBridge::ResetTextShadow(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     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
385     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
386     auto nodeModifiers = GetArkUINodeModifiers();
387     CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
388     nodeModifiers->getTextClockModifier()->resetTextShadow(nativeNode);
389     return panda::JSValueRef::Undefined(vm);
390 }
391 
SetContentModifierBuilder(ArkUIRuntimeCallInfo * runtimeCallInfo)392 ArkUINativeModuleValue TextClockBridge::SetContentModifierBuilder(ArkUIRuntimeCallInfo* runtimeCallInfo)
393 {
394     EcmaVM* vm = runtimeCallInfo->GetVM();
395     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
396     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
397     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
398     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
399     void* nativeNode = firstArg->ToNativePointer(vm)->Value();
400     auto* frameNode = reinterpret_cast<FrameNode*>(nativeNode);
401     if (!secondArg->IsObject(vm)) {
402         TextClockModelNG::SetBuilderFunc(frameNode, nullptr);
403         return panda::JSValueRef::Undefined(vm);
404     }
405     panda::CopyableGlobal<panda::ObjectRef> obj(vm, secondArg);
406     TextClockModelNG::SetBuilderFunc(frameNode,
407         [vm, frameNode, obj = std::move(obj), containerId = Container::CurrentId()](
408             TextClockConfiguration config) -> RefPtr<FrameNode> {
409             ContainerScope scope(containerId);
410             auto context = ArkTSUtils::GetContext(vm);
411             CHECK_EQUAL_RETURN(context->IsUndefined(), true, nullptr);
412             const char* keysOfTextClock[] = { "timeZoneOffset", "started", "enabled", "timeValue" };
413             Local<JSValueRef> valuesOfTextClock[] = { panda::NumberRef::New(vm, config.timeZoneOffset_),
414                 panda::BooleanRef::New(vm, config.started_), panda::BooleanRef::New(vm, config.enabled_),
415                 panda::NumberRef::New(vm, config.timeValue_) };
416             auto textClock = panda::ObjectRef::NewWithNamedProperties(
417                 vm, ArraySize(keysOfTextClock), keysOfTextClock, valuesOfTextClock);
418             obj->SetNativePointerFieldCount(vm, 1);
419             obj->SetNativePointerField(vm, 0, static_cast<void*>(frameNode));
420             panda::Local<panda::JSValueRef> params[NUM_2] = { context, textClock };
421             LocalScope pandaScope(vm);
422             panda::TryCatch trycatch(vm);
423             auto jsObject = obj.ToLocal();
424             auto makeFunc = jsObject->Get(vm, panda::StringRef::NewFromUtf8(vm, "makeContentModifierNode"));
425             CHECK_EQUAL_RETURN(makeFunc->IsFunction(vm), false, nullptr);
426             panda::Local<panda::FunctionRef> func = makeFunc;
427             auto result = func->Call(vm, jsObject, params, NUM_2);
428             JSNApi::ExecutePendingJob(vm);
429             CHECK_EQUAL_RETURN(result.IsEmpty() || trycatch.HasCaught() || !result->IsObject(vm), true, nullptr);
430             auto resultObj = result->ToObject(vm);
431             panda::Local<panda::JSValueRef> nodeptr =
432                 resultObj->Get(vm, panda::StringRef::NewFromUtf8(vm, TEXTCLOCK_NODEPTR_OF_UINODE));
433             CHECK_EQUAL_RETURN(nodeptr.IsEmpty() || nodeptr->IsUndefined() || nodeptr->IsNull(), true, nullptr);
434             auto* frameNode = reinterpret_cast<FrameNode*>(nodeptr->ToNativePointer(vm)->Value());
435             CHECK_NULL_RETURN(frameNode, nullptr);
436             return AceType::Claim(frameNode);
437         });
438     return panda::JSValueRef::Undefined(vm);
439 }
SetDateTimeOptions(ArkUIRuntimeCallInfo * runtimeCallInfo)440 ArkUINativeModuleValue TextClockBridge::SetDateTimeOptions(ArkUIRuntimeCallInfo* runtimeCallInfo)
441 {
442     EcmaVM* vm = runtimeCallInfo->GetVM();
443     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
444     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
445     Local<JSValueRef> hourArg = runtimeCallInfo->GetCallArgRef(NUM_1);
446     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
447     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
448     ZeroPrefixType hourType = ZeroPrefixType::AUTO;
449     std::string hour = TEXTCLOCK_DATE_TIME_OPTIONS_HOUR;
450     if (hourArg->IsString(vm)) {
451         std::string hour = hourArg->ToString(vm)->ToString(vm);
452         if (hour == TEXTCLOCK_DATE_TIME_OPTIONS_TWO_DIGIT_VAL) {
453             hourType = ZeroPrefixType::SHOW;
454         } else if (hour == TEXTCLOCK_DATE_TIME_OPTIONS_NUMERIC_VAL) {
455             hourType = ZeroPrefixType::HIDE;
456         }
457     }
458     auto nodeModifiers = GetArkUINodeModifiers();
459     CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
460     nodeModifiers->getTextClockModifier()->setDateTimeOptions(
461         nativeNode, static_cast<ArkUI_Int32>(hourType));
462     return panda::JSValueRef::Undefined(vm);
463 }
464 
ResetDateTimeOptions(ArkUIRuntimeCallInfo * runtimeCallInfo)465 ArkUINativeModuleValue TextClockBridge::ResetDateTimeOptions(ArkUIRuntimeCallInfo* runtimeCallInfo)
466 {
467     EcmaVM* vm = runtimeCallInfo->GetVM();
468     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
469     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
470     CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
471     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
472     auto nodeModifiers = GetArkUINodeModifiers();
473     CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
474     nodeModifiers->getTextClockModifier()->resetDateTimeOptions(nativeNode);
475     return panda::JSValueRef::Undefined(vm);
476 }
477 
SetTextClockTimeZoneOffset(ArkUIRuntimeCallInfo * runtimeCallInfo)478 ArkUINativeModuleValue TextClockBridge::SetTextClockTimeZoneOffset(ArkUIRuntimeCallInfo* runtimeCallInfo)
479 {
480     EcmaVM* vm = runtimeCallInfo->GetVM();
481     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
482     Local<JSValueRef> nodeVal = runtimeCallInfo->GetCallArgRef(NUM_0);
483     Local<JSValueRef> hourWestVal = runtimeCallInfo->GetCallArgRef(NUM_1);
484     CHECK_NULL_RETURN(nodeVal->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
485     auto nativeNode = nodePtr(nodeVal->ToNativePointer(vm)->Value());
486     float hourWest = NAN;
487     if (hourWestVal->IsNumber() && HoursWestIsValid(hourWestVal->Int32Value(vm))) {
488         hourWest = GetHoursWest(hourWestVal->ToNumber(vm)->Value());
489     }
490     auto nodeModifiers = GetArkUINodeModifiers();
491     CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
492     nodeModifiers->getTextClockModifier()->setTextClockTimeZoneOffset(nativeNode, hourWest);
493     return panda::JSValueRef::Undefined(vm);
494 }
495 
SetTextClockController(ArkUIRuntimeCallInfo * runtimeCallInfo)496 ArkUINativeModuleValue TextClockBridge::SetTextClockController(ArkUIRuntimeCallInfo* runtimeCallInfo)
497 {
498     EcmaVM* vm = runtimeCallInfo->GetVM();
499     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
500     Local<JSValueRef> nodeVal = runtimeCallInfo->GetCallArgRef(NUM_0);
501     Local<JSValueRef> controllerVal = runtimeCallInfo->GetCallArgRef(NUM_1);
502     CHECK_NULL_RETURN(nodeVal->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
503     auto nativeNode = nodePtr(nodeVal->ToNativePointer(vm)->Value());
504 
505     auto* frameNode = reinterpret_cast<FrameNode*>(nativeNode);
506     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
507     auto controller = TextClockModelNG::InitTextController(frameNode);
508     if (!controllerVal->IsUndefined() && !controllerVal->IsNull() && controllerVal->IsObject(vm)) {
509         auto* jsController = Framework::JSRef<Framework::JSObject>(Framework::JSObject(controllerVal->ToObject(vm)))
510                                  ->Unwrap<Framework::JSTextClockController>();
511         if (jsController) {
512             jsController->SetInstanceId(Container::CurrentId());
513             if (controller) {
514                 RemoveJSController(frameNode, controller, jsController);
515                 jsController->AddController(controller);
516             }
517         }
518     } else if (controller) {
519         auto pointer = TextClockModelNG::GetJSTextClockController(frameNode);
520         auto preController = static_cast<Framework::JSTextClockController*>(Referenced::RawPtr(pointer));
521         if (preController) {
522             preController->removeController(controller);
523         }
524         TextClockModelNG::SetJSTextClockController(frameNode, nullptr);
525     }
526     return panda::JSValueRef::Undefined(vm);
527 }
528 
SetTextClockOnDateChange(ArkUIRuntimeCallInfo * runtimeCallInfo)529 ArkUINativeModuleValue TextClockBridge::SetTextClockOnDateChange(ArkUIRuntimeCallInfo* runtimeCallInfo)
530 {
531     EcmaVM* vm = runtimeCallInfo->GetVM();
532     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
533     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
534     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
535     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
536 
537     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
538         GetArkUINodeModifiers()->getTextClockModifier()->resetTextClockOnDateChange(nativeNode);
539         return panda::JSValueRef::Undefined(vm);
540     }
541     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
542     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
543     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
544     std::function<void(const std::string&)> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)](
545                                                            const std::string& value) {
546         panda::LocalScope pandaScope(vm);
547         panda::TryCatch trycatch(vm);
548         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
549 
550         panda::Local<panda::JSValueRef> params[1] = { panda::StringRef::NewFromUtf8(vm, value.c_str()) };
551         func->Call(vm, func.ToLocal(), params, 1);
552     };
553     GetArkUINodeModifiers()->getTextClockModifier()->setTextClockOnDateChange(
554         nativeNode, reinterpret_cast<void*>(&callback));
555     return panda::JSValueRef::Undefined(vm);
556 }
557 
ResetTextClockOnDateChange(ArkUIRuntimeCallInfo * runtimeCallInfo)558 ArkUINativeModuleValue TextClockBridge::ResetTextClockOnDateChange(ArkUIRuntimeCallInfo* runtimeCallInfo)
559 {
560     EcmaVM* vm = runtimeCallInfo->GetVM();
561     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
562     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
563     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
564     GetArkUINodeModifiers()->getTextClockModifier()->resetTextClockOnDateChange(nativeNode);
565     return panda::JSValueRef::Undefined(vm);
566 }
567 } // namespace OHOS::Ace::NG
568