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_radio_bridge.h"
16 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
17 #include "core/components/checkable/checkable_theme.h"
18 #include "core/components_ng/base/frame_node.h"
19 #include "core/components_ng/pattern/radio/radio_model_ng.h"
20
21 namespace OHOS::Ace::NG {
22 constexpr int NUM_0 = 0;
23 constexpr int NUM_1 = 1;
24 constexpr int NUM_2 = 2;
25 constexpr int NUM_3 = 3;
26 const char* RADIO_BUILDER_NODEPTR_OF_UINODE = "nodePtr_";
JsRadioChangeCallback(panda::JsiRuntimeCallInfo * runtimeCallInfo)27 panda::Local<panda::JSValueRef> JsRadioChangeCallback(panda::JsiRuntimeCallInfo* runtimeCallInfo)
28 {
29 auto vm = runtimeCallInfo->GetVM();
30 int32_t argc = static_cast<int32_t>(runtimeCallInfo->GetArgsNumber());
31 if (argc != NUM_1) {
32 return panda::JSValueRef::Undefined(vm);
33 }
34 auto firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
35 if (!firstArg->IsBoolean()) {
36 return panda::JSValueRef::Undefined(vm);
37 }
38 bool value = firstArg->ToBoolean(vm)->Value();
39 auto ref = runtimeCallInfo->GetThisRef();
40 auto obj = ref->ToObject(vm);
41 if (obj->GetNativePointerFieldCount(vm) < NUM_1) {
42 return panda::JSValueRef::Undefined(vm);
43 }
44 auto frameNode = static_cast<FrameNode*>(obj->GetNativePointerField(vm, 0));
45 CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
46 RadioModelNG::SetChangeValue(frameNode, value);
47 return panda::JSValueRef::Undefined(vm);
48 }
49
SetRadioChecked(ArkUIRuntimeCallInfo * runtimeCallInfo)50 ArkUINativeModuleValue RadioBridge::SetRadioChecked(ArkUIRuntimeCallInfo* runtimeCallInfo)
51 {
52 EcmaVM* vm = runtimeCallInfo->GetVM();
53 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
54 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
55 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
56 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
57 bool isCheck = secondArg->ToBoolean(vm)->Value();
58 GetArkUINodeModifiers()->getRadioModifier()->setRadioChecked(nativeNode, isCheck);
59 return panda::JSValueRef::Undefined(vm);
60 }
61
ResetRadioChecked(ArkUIRuntimeCallInfo * runtimeCallInfo)62 ArkUINativeModuleValue RadioBridge::ResetRadioChecked(ArkUIRuntimeCallInfo* runtimeCallInfo)
63 {
64 EcmaVM* vm = runtimeCallInfo->GetVM();
65 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
66 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
67 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
68 GetArkUINodeModifiers()->getRadioModifier()->resetRadioChecked(nativeNode);
69 return panda::JSValueRef::Undefined(vm);
70 }
71
SetRadioStyle(ArkUIRuntimeCallInfo * runtimeCallInfo)72 ArkUINativeModuleValue RadioBridge::SetRadioStyle(ArkUIRuntimeCallInfo* runtimeCallInfo)
73 {
74 EcmaVM* vm = runtimeCallInfo->GetVM();
75 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
76 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
77 Local<JSValueRef> checkedBackgroundColor = runtimeCallInfo->GetCallArgRef(NUM_1);
78 Local<JSValueRef> uncheckedBorderColor = runtimeCallInfo->GetCallArgRef(NUM_2);
79 Local<JSValueRef> indicatorColor = runtimeCallInfo->GetCallArgRef(NUM_3);
80 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
81
82 auto pipeline = PipelineBase::GetCurrentContext();
83 CHECK_NULL_RETURN(pipeline, panda::NativePointerRef::New(vm, nullptr));
84 auto radioTheme = pipeline->GetTheme<RadioTheme>();
85 CHECK_NULL_RETURN(radioTheme, panda::NativePointerRef::New(vm, nullptr));
86
87 Color checkedBackgroundColorVal;
88 if (checkedBackgroundColor->IsNull() || checkedBackgroundColor->IsUndefined() ||
89 !ArkTSUtils::ParseJsColorAlpha(vm, checkedBackgroundColor, checkedBackgroundColorVal)) {
90 checkedBackgroundColorVal = radioTheme->GetActiveColor();
91 }
92 Color uncheckedBorderColorVal;
93 if (uncheckedBorderColor->IsNull() || uncheckedBorderColor->IsUndefined() ||
94 !ArkTSUtils::ParseJsColorAlpha(vm, uncheckedBorderColor, uncheckedBorderColorVal)) {
95 uncheckedBorderColorVal = radioTheme->GetInactiveColor();
96 }
97 Color indicatorColorVal;
98 if (indicatorColor->IsNull() || indicatorColor->IsUndefined() ||
99 !ArkTSUtils::ParseJsColorAlpha(vm, indicatorColor, indicatorColorVal)) {
100 indicatorColorVal = radioTheme->GetPointColor();
101 }
102
103 GetArkUINodeModifiers()->getRadioModifier()->setRadioStyle(nativeNode,
104 checkedBackgroundColorVal.GetValue(), uncheckedBorderColorVal.GetValue(), indicatorColorVal.GetValue());
105 return panda::JSValueRef::Undefined(vm);
106 }
107
ResetRadioStyle(ArkUIRuntimeCallInfo * runtimeCallInfo)108 ArkUINativeModuleValue RadioBridge::ResetRadioStyle(ArkUIRuntimeCallInfo* runtimeCallInfo)
109 {
110 EcmaVM* vm = runtimeCallInfo->GetVM();
111 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
112 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
113 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
114 GetArkUINodeModifiers()->getRadioModifier()->resetRadioStyle(nativeNode);
115 return panda::JSValueRef::Undefined(vm);
116 }
117
SetRadioWidth(ArkUIRuntimeCallInfo * runtimeCallInfo)118 ArkUINativeModuleValue RadioBridge::SetRadioWidth(ArkUIRuntimeCallInfo* runtimeCallInfo)
119 {
120 EcmaVM* vm = runtimeCallInfo->GetVM();
121 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
122 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
123 Local<JSValueRef> widthArg = runtimeCallInfo->GetCallArgRef(1);
124 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
125 CalcDimension width;
126 if (!ArkTSUtils::ParseJsDimensionVpNG(vm, widthArg, width)) {
127 GetArkUINodeModifiers()->getRadioModifier()->resetRadioWidth(nativeNode);
128 return panda::JSValueRef::Undefined(vm);
129 }
130 if (LessNotEqual(width.Value(), 0.0)) {
131 width.SetValue(0.0);
132 }
133 std::string widthCalc = width.CalcValue();
134 GetArkUINodeModifiers()->getRadioModifier()->setRadioWidth(
135 nativeNode, width.Value(), static_cast<int32_t>(width.Unit()), widthCalc.c_str());
136 return panda::JSValueRef::Undefined(vm);
137 }
138
ResetRadioWidth(ArkUIRuntimeCallInfo * runtimeCallInfo)139 ArkUINativeModuleValue RadioBridge::ResetRadioWidth(ArkUIRuntimeCallInfo* runtimeCallInfo)
140 {
141 EcmaVM* vm = runtimeCallInfo->GetVM();
142 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
143 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0); //0 is node arguments
144 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
145 GetArkUINodeModifiers()->getRadioModifier()->resetRadioWidth(nativeNode);
146 return panda::JSValueRef::Undefined(vm);
147 }
148
SetRadioHeight(ArkUIRuntimeCallInfo * runtimeCallInfo)149 ArkUINativeModuleValue RadioBridge::SetRadioHeight(ArkUIRuntimeCallInfo* runtimeCallInfo)
150 {
151 EcmaVM* vm = runtimeCallInfo->GetVM();
152 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
153 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
154 Local<JSValueRef> heightArg = runtimeCallInfo->GetCallArgRef(1);
155 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
156 CalcDimension height;
157 if (!ArkTSUtils::ParseJsDimensionVpNG(vm, heightArg, height)) {
158 GetArkUINodeModifiers()->getRadioModifier()->resetRadioHeight(nativeNode);
159 return panda::JSValueRef::Undefined(vm);
160 }
161 if (LessNotEqual(height.Value(), 0.0)) {
162 height.SetValue(0.0);
163 }
164 std::string heightCalc = height.CalcValue();
165 GetArkUINodeModifiers()->getRadioModifier()->setRadioHeight(
166 nativeNode, height.Value(), static_cast<int32_t>(height.Unit()), heightCalc.c_str());
167 return panda::JSValueRef::Undefined(vm);
168 }
169
ResetRadioHeight(ArkUIRuntimeCallInfo * runtimeCallInfo)170 ArkUINativeModuleValue RadioBridge::ResetRadioHeight(ArkUIRuntimeCallInfo* runtimeCallInfo)
171 {
172 EcmaVM* vm = runtimeCallInfo->GetVM();
173 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
174 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0); //0 is node arguments
175 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
176 GetArkUINodeModifiers()->getRadioModifier()->resetRadioHeight(nativeNode);
177 return panda::JSValueRef::Undefined(vm);
178 }
179
SetRadioSize(ArkUIRuntimeCallInfo * runtimeCallInfo)180 ArkUINativeModuleValue RadioBridge::SetRadioSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
181 {
182 EcmaVM* vm = runtimeCallInfo->GetVM();
183 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
184 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0); //0 is node arguments
185 Local<JSValueRef> widthArg = runtimeCallInfo->GetCallArgRef(1); //1 is width value
186 Local<JSValueRef> heightArg = runtimeCallInfo->GetCallArgRef(2); //2 is height value
187 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
188
189 CalcDimension width;
190 CalcDimension height;
191 if (!ArkTSUtils::ParseJsDimensionVpNG(vm, widthArg, width)) {
192 GetArkUINodeModifiers()->getRadioModifier()->resetRadioWidth(nativeNode);
193 } else {
194 std::string widthCalc = width.CalcValue();
195 if (LessNotEqual(width.Value(), 0.0)) {
196 width.SetValue(0.0);
197 }
198 GetArkUINodeModifiers()->getRadioModifier()->setRadioWidth(
199 nativeNode, width.Value(), static_cast<int>(width.Unit()), widthCalc.c_str());
200 }
201 if (!ArkTSUtils::ParseJsDimensionVpNG(vm, heightArg, height)) {
202 GetArkUINodeModifiers()->getRadioModifier()->resetRadioHeight(nativeNode);
203 } else {
204 std::string heightCalc = height.CalcValue();
205 if (LessNotEqual(height.Value(), 0.0)) {
206 height.SetValue(0.0);
207 }
208 GetArkUINodeModifiers()->getRadioModifier()->setRadioHeight(
209 nativeNode, height.Value(), static_cast<int>(height.Unit()), heightCalc.c_str());
210 }
211 return panda::JSValueRef::Undefined(vm);
212 }
213
ResetRadioSize(ArkUIRuntimeCallInfo * runtimeCallInfo)214 ArkUINativeModuleValue RadioBridge::ResetRadioSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
215 {
216 EcmaVM* vm = runtimeCallInfo->GetVM();
217 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
218 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0); //0 is node arguments
219 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
220 GetArkUINodeModifiers()->getRadioModifier()->resetRadioSize(nativeNode);
221 return panda::JSValueRef::Undefined(vm);
222 }
223
SetRadioHoverEffect(ArkUIRuntimeCallInfo * runtimeCallInfo)224 ArkUINativeModuleValue RadioBridge::SetRadioHoverEffect(ArkUIRuntimeCallInfo* runtimeCallInfo)
225 {
226 EcmaVM* vm = runtimeCallInfo->GetVM();
227 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
228 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0); //0 is node arguments
229 Local<JSValueRef> valueArg = runtimeCallInfo->GetCallArgRef(1); //1 is Jsvalue
230 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
231
232 if (valueArg->IsUndefined() || !valueArg->IsNumber()) {
233 GetArkUINodeModifiers()->getRadioModifier()->resetRadioHoverEffect(nativeNode);
234 return panda::JSValueRef::Undefined(vm);
235 }
236 int32_t intValue = valueArg->Int32Value(vm);
237 GetArkUINodeModifiers()->getRadioModifier()->setRadioHoverEffect(nativeNode, intValue);
238 return panda::JSValueRef::Undefined(vm);
239 }
240
ResetRadioHoverEffect(ArkUIRuntimeCallInfo * runtimeCallInfo)241 ArkUINativeModuleValue RadioBridge::ResetRadioHoverEffect(ArkUIRuntimeCallInfo* runtimeCallInfo)
242 {
243 EcmaVM* vm = runtimeCallInfo->GetVM();
244 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
245 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0); //0 is node arguments
246 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
247 GetArkUINodeModifiers()->getRadioModifier()->resetRadioHoverEffect(nativeNode);
248 return panda::JSValueRef::Undefined(vm);
249 }
250
SetRadioPadding(ArkUIRuntimeCallInfo * runtimeCallInfo)251 ArkUINativeModuleValue RadioBridge::SetRadioPadding(ArkUIRuntimeCallInfo *runtimeCallInfo)
252 {
253 EcmaVM *vm = runtimeCallInfo->GetVM();
254 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
255 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0); //0 is node arguments
256 Local<JSValueRef> topArg = runtimeCallInfo->GetCallArgRef(1); //1 is top arguments
257 Local<JSValueRef> rightArg = runtimeCallInfo->GetCallArgRef(2); //2 is right arguments
258 Local<JSValueRef> bottomArg = runtimeCallInfo->GetCallArgRef(3); //3 is bottom arguments
259 Local<JSValueRef> leftArg = runtimeCallInfo->GetCallArgRef(4); //4 is left arguments
260 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
261
262 struct ArkUISizeType top = { 0.0, static_cast<int8_t>(DimensionUnit::VP) };
263 struct ArkUISizeType right = { 0.0, static_cast<int8_t>(DimensionUnit::VP) };
264 struct ArkUISizeType bottom = { 0.0, static_cast<int8_t>(DimensionUnit::VP) };
265 struct ArkUISizeType left = { 0.0, static_cast<int8_t>(DimensionUnit::VP) };
266
267 CalcDimension topDimen(0, DimensionUnit::VP);
268 CalcDimension rightDimen(0, DimensionUnit::VP);
269 CalcDimension bottomDimen(0, DimensionUnit::VP);
270 CalcDimension leftDimen(0, DimensionUnit::VP);
271 ArkTSUtils::ParsePadding(vm, topArg, topDimen, top);
272 ArkTSUtils::ParsePadding(vm, rightArg, rightDimen, right);
273 ArkTSUtils::ParsePadding(vm, bottomArg, bottomDimen, bottom);
274 ArkTSUtils::ParsePadding(vm, leftArg, leftDimen, left);
275 GetArkUINodeModifiers()->getRadioModifier()->setRadioPadding(nativeNode, &top, &right, &bottom, &left);
276
277 return panda::JSValueRef::Undefined(vm);
278 }
279
ResetRadioPadding(ArkUIRuntimeCallInfo * runtimeCallInfo)280 ArkUINativeModuleValue RadioBridge::ResetRadioPadding(ArkUIRuntimeCallInfo *runtimeCallInfo)
281 {
282 EcmaVM *vm = runtimeCallInfo->GetVM();
283 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
284 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0); //0 is node arguments
285 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
286 GetArkUINodeModifiers()->getRadioModifier()->resetRadioPadding(nativeNode);
287 return panda::JSValueRef::Undefined(vm);
288 }
289
SetRadioResponseRegion(ArkUIRuntimeCallInfo * runtimeCallInfo)290 ArkUINativeModuleValue RadioBridge::SetRadioResponseRegion(ArkUIRuntimeCallInfo* runtimeCallInfo)
291 {
292 EcmaVM* vm = runtimeCallInfo->GetVM();
293 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
294 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0); //0 is node arguments
295 Local<JSValueRef> valueArg = runtimeCallInfo->GetCallArgRef(1); //1 is JsValue
296 Local<JSValueRef> lengthArg = runtimeCallInfo->GetCallArgRef(2); //2 is length arguments
297 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
298 uint32_t length = static_cast<uint32_t>(lengthArg->Int32Value(vm));
299 ArkUI_Float32 regionArray[length];
300 int32_t regionUnits[length];
301 if (!ArkTSUtils::ParseResponseRegion(vm, valueArg, regionArray, regionUnits, length)) {
302 GetArkUINodeModifiers()->getRadioModifier()->resetRadioResponseRegion(nativeNode);
303 return panda::JSValueRef::Undefined(vm);
304 }
305 GetArkUINodeModifiers()->getRadioModifier()->setRadioResponseRegion(
306 nativeNode, regionArray, regionUnits, length);
307 return panda::JSValueRef::Undefined(vm);
308 }
309
ResetRadioResponseRegion(ArkUIRuntimeCallInfo * runtimeCallInfo)310 ArkUINativeModuleValue RadioBridge::ResetRadioResponseRegion(ArkUIRuntimeCallInfo* runtimeCallInfo)
311 {
312 EcmaVM* vm = runtimeCallInfo->GetVM();
313 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
314 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0); //0 is node arguments
315 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
316 GetArkUINodeModifiers()->getRadioModifier()->resetRadioResponseRegion(nativeNode);
317 return panda::JSValueRef::Undefined(vm);
318 }
319
SetContentModifierBuilder(ArkUIRuntimeCallInfo * runtimeCallInfo)320 ArkUINativeModuleValue RadioBridge::SetContentModifierBuilder(ArkUIRuntimeCallInfo* runtimeCallInfo)
321 {
322 EcmaVM* vm = runtimeCallInfo->GetVM();
323 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
324 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
325 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
326 auto* frameNode = reinterpret_cast<FrameNode*>(firstArg->ToNativePointer(vm)->Value());
327 if (!secondArg->IsObject(vm)) {
328 RadioModelNG::SetBuilderFunc(frameNode, nullptr);
329 return panda::JSValueRef::Undefined(vm);
330 }
331 panda::CopyableGlobal<panda::ObjectRef> obj(vm, secondArg);
332 RadioModelNG::SetBuilderFunc(frameNode,
333 [vm, frameNode, obj = std::move(obj), containerId = Container::CurrentId()](
334 RadioConfiguration config) -> RefPtr<FrameNode> {
335 ContainerScope scope(containerId);
336 auto context = ArkTSUtils::GetContext(vm);
337 CHECK_EQUAL_RETURN(context->IsUndefined(), true, nullptr);
338 const char* keysOfRadio[] = { "value", "checked", "enabled", "triggerChange"};
339 Local<JSValueRef> valuesOfRadio[] = { panda::StringRef::NewFromUtf8(vm, config.value_.c_str()),
340 panda::BooleanRef::New(vm, config.checked_), panda::BooleanRef::New(vm, config.enabled_),
341 panda::FunctionRef::New(vm, JsRadioChangeCallback)};
342 auto radio = panda::ObjectRef::NewWithNamedProperties(vm,
343 ArraySize(keysOfRadio), keysOfRadio, valuesOfRadio);
344 radio->SetNativePointerFieldCount(vm, 1);
345 radio->SetNativePointerField(vm, 0, static_cast<void*>(frameNode));
346 panda::Local<panda::JSValueRef> params[NUM_2] = { context, radio };
347 LocalScope pandaScope(vm);
348 panda::TryCatch trycatch(vm);
349 auto jsObject = obj.ToLocal();
350 auto makeFunc = jsObject->Get(vm, panda::StringRef::NewFromUtf8(vm, "makeContentModifierNode"));
351 CHECK_EQUAL_RETURN(makeFunc->IsFunction(vm), false, nullptr);
352 panda::Local<panda::FunctionRef> func = makeFunc;
353 auto result = func->Call(vm, jsObject, params, NUM_2);
354 JSNApi::ExecutePendingJob(vm);
355 CHECK_EQUAL_RETURN(result.IsEmpty() || trycatch.HasCaught() || !result->IsObject(vm), true, nullptr);
356 auto resultObj = result->ToObject(vm);
357 panda::Local<panda::JSValueRef> nodeptr =
358 resultObj->Get(vm, panda::StringRef::NewFromUtf8(vm, RADIO_BUILDER_NODEPTR_OF_UINODE));
359 CHECK_EQUAL_RETURN(nodeptr.IsEmpty() || nodeptr->IsUndefined() || nodeptr->IsNull(), true, nullptr);
360 auto* frameNode = reinterpret_cast<FrameNode*>(nodeptr->ToNativePointer(vm)->Value());
361 CHECK_NULL_RETURN(frameNode, nullptr);
362 return AceType::Claim(frameNode);
363 });
364 return panda::JSValueRef::Undefined(vm);
365 }
366 }
367