• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_frame_node_bridge.h"
17 
18 #include "jsnapi_expo.h"
19 
20 #include "base/log/log_wrapper.h"
21 #include "base/memory/ace_type.h"
22 #include "base/memory/referenced.h"
23 #include "base/utils/utils.h"
24 #include "bridge/declarative_frontend/engine/jsi/jsi_types.h"
25 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_api_bridge.h"
26 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_render_node_bridge.h"
27 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_toggle_bridge.h"
28 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_utils_bridge.h"
29 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_xcomponent_bridge.h"
30 #include "bridge/declarative_frontend/jsview/js_view_context.h"
31 #include "core/components_ng/base/view_abstract.h"
32 #include "core/components_ng/base/view_stack_processor.h"
33 #include "core/components_ng/pattern/custom_frame_node/custom_frame_node.h"
34 #include "core/components_ng/pattern/custom_frame_node/custom_frame_node_pattern.h"
35 #include "core/components_ng/pattern/toggle/toggle_model_ng.h"
36 #include "core/components_ng/pattern/xcomponent/xcomponent_model_ng.h"
37 #include "core/components_ng/syntax/node_content.h"
38 #include "core/interfaces/arkoala/arkoala_api.h"
39 #include "core/interfaces/native/node/extension_custom_node.h"
40 #include "frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
41 
42 namespace OHOS::Ace::NG {
43 namespace {
44 
45 constexpr double VISIBLE_RATIO_MIN = 0.0;
46 constexpr double VISIBLE_RATIO_MAX = 1.0;
47 constexpr int32_t INDEX_OF_INTERVAL = 4;
48 constexpr int32_t INDEX_OF_OPTION_OF_VISIBLE = 3;
49 constexpr int DEFAULT_EXPECTED_UPDATE_INTERVAL = 1000;
50 constexpr int32_t SIZE_OF_ARRAY = 2;
51 
ParseFloatArray(const EcmaVM * vm,const panda::Local<panda::ArrayRef> & array,std::vector<float> & outArray)52 bool ParseFloatArray(const EcmaVM* vm, const panda::Local<panda::ArrayRef>& array, std::vector<float>& outArray)
53 {
54     uint32_t length = array->Length(vm);
55     for (uint32_t i = 0; i < length; ++i) {
56         auto jsValue = panda::ArrayRef::GetValueAt(vm, array, i);
57         bool isNumber = false;
58         double value = jsValue->GetValueDouble(isNumber);
59         if (!isNumber) {
60             return false;
61         }
62         outArray.emplace_back(value);
63     }
64     return true;
65 }
66 
CheckAnimationPropertyLength(AnimationPropertyType type,size_t size,bool allowEmpty)67 bool CheckAnimationPropertyLength(AnimationPropertyType type, size_t size, bool allowEmpty)
68 {
69     if (allowEmpty && size == 0) {
70         return true;
71     }
72     const static std::unordered_map<AnimationPropertyType, std::pair<size_t, const char*>> requiredLength = {
73         { AnimationPropertyType::ROTATION, { ROTATION_PARAM_SIZE, "rotation" } },
74         { AnimationPropertyType::TRANSLATION, { TRANSLATION_PARAM_SIZE, "translation" } },
75         { AnimationPropertyType::SCALE, { SCALE_PARAM_SIZE, "scale" } },
76         { AnimationPropertyType::OPACITY, { OPACITY_PARAM_SIZE, "opacity" } },
77     };
78     auto iter = requiredLength.find(type);
79     if (iter == requiredLength.end()) {
80         return false;
81     }
82     if (iter->second.first == size) {
83         return true;
84     }
85     TAG_LOGW(AceLogTag::ACE_ANIMATION,
86         "animationProperty of %{public}s needs %{public}zu params while input size is %{public}zu", iter->second.second,
87         iter->second.first, size);
88     return false;
89 }
90 
AdjustPropertyValue(AnimationPropertyType type,std::vector<float> & startValue,std::vector<float> & endValue)91 void AdjustPropertyValue(AnimationPropertyType type, std::vector<float>& startValue, std::vector<float>& endValue)
92 {
93     if (type == AnimationPropertyType::OPACITY) {
94         for (auto& opacityItem : startValue) {
95             opacityItem = std::clamp(opacityItem, 0.0f, 1.0f);
96         }
97         for (auto& opacityItem : endValue) {
98             opacityItem = std::clamp(opacityItem, 0.0f, 1.0f);
99         }
100     }
101 }
102 
ParseFinishCallback(const panda::Local<panda::ObjectRef> & obj,FrameNode * frameNode,const EcmaVM * vm,std::optional<int32_t> & finishCount)103 std::function<void()> ParseFinishCallback(const panda::Local<panda::ObjectRef>& obj, FrameNode* frameNode,
104     const EcmaVM* vm, std::optional<int32_t>& finishCount)
105 {
106     panda::Local<panda::JSValueRef> onFinishValue = obj->Get(vm, "onFinish");
107     if (onFinishValue->IsFunction(vm)) {
108         panda::Local<panda::FunctionRef> onFinish = onFinishValue->ToObject(vm);
109         finishCount = GetAnimationFinishCount();
110         return [func = panda::CopyableGlobal(vm, onFinish), id = Container::CurrentIdSafely(),
111                    node = AceType::WeakClaim(frameNode), count = finishCount.value(), vm]() mutable {
112             if (func.IsEmpty()) {
113                 return;
114             }
115             ContainerScope scope(id);
116             ACE_SCOPED_TRACE("frameNode onFinish[cnt:%d]", count);
117             auto pipelineContext = PipelineContext::GetCurrentContextSafely();
118             CHECK_NULL_VOID(pipelineContext);
119             pipelineContext->UpdateCurrentActiveNode(node);
120             panda::LocalScope pandaScope(vm);
121             TAG_LOGI(AceLogTag::ACE_ANIMATION, "FrameNode animation finish, cnt:%{public}d", count);
122             func->Call(vm, func.ToLocal(), nullptr, 0);
123             func.Reset();
124         };
125     }
126     return nullptr;
127 }
128 
ParseAnimationProperty(const EcmaVM * vm,const panda::Local<panda::JSValueRef> & propertyArg,AnimationPropertyType & result)129 bool ParseAnimationProperty(
130     const EcmaVM* vm, const panda::Local<panda::JSValueRef>& propertyArg, AnimationPropertyType& result)
131 {
132     CHECK_NULL_RETURN(propertyArg->IsNumber(), false);
133     int32_t propertyInt = propertyArg->Int32Value(vm);
134     if (propertyInt < static_cast<int32_t>(AnimationPropertyType::ROTATION) ||
135         propertyInt > static_cast<int32_t>(AnimationPropertyType::OPACITY)) {
136         return false;
137     }
138     result = static_cast<AnimationPropertyType>(propertyInt);
139     return true;
140 }
141 
GetIsExpanded(ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUI_Int32 index)142 ArkUI_Bool GetIsExpanded(ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUI_Int32 index)
143 {
144     EcmaVM* vm = runtimeCallInfo->GetVM();
145     Local<JSValueRef> isExpandedArg = runtimeCallInfo->GetCallArgRef(index);
146     CHECK_NULL_RETURN(!isExpandedArg.IsNull(), true);
147     return isExpandedArg->IsBoolean() ? isExpandedArg->ToBoolean(vm)->Value() : true;
148 }
GetExpandMode(ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUI_Int32 index)149 ArkUI_Int32 GetExpandMode(ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUI_Int32 index)
150 {
151     EcmaVM* vm = runtimeCallInfo->GetVM();
152     Local<JSValueRef> expandModeArg = runtimeCallInfo->GetCallArgRef(index);
153     CHECK_NULL_RETURN(!expandModeArg.IsNull(), 1);
154     return expandModeArg->IsNumber() || expandModeArg->IsBoolean() ? expandModeArg->ToNumber(vm)->Value() : 1;
155 }
GetIsExcludeInner(ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUI_Int32 index)156 ArkUI_Bool GetIsExcludeInner(ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUI_Int32 index)
157 {
158     EcmaVM* vm = runtimeCallInfo->GetVM();
159     Local<JSValueRef> isExcludeInnerArg = runtimeCallInfo->GetCallArgRef(index);
160     CHECK_NULL_RETURN(!isExcludeInnerArg.IsNull(), false);
161     return isExcludeInnerArg->IsBoolean() ? isExcludeInnerArg->ToBoolean(vm)->Value() : false;
162 }
163 } // namespace
IsCustomFrameNode(FrameNode * node)164 ArkUI_Bool FrameNodeBridge::IsCustomFrameNode(FrameNode* node)
165 {
166     return node && (node->IsArkTsFrameNode() || node->GetIsRootBuilderNode());
167 }
168 
GetFrameNode(ArkUIRuntimeCallInfo * runtimeCallInfo)169 ArkUINodeHandle FrameNodeBridge::GetFrameNode(ArkUIRuntimeCallInfo* runtimeCallInfo)
170 {
171     EcmaVM* vm = runtimeCallInfo->GetVM();
172     CHECK_NULL_RETURN(vm, nullptr);
173     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
174     CHECK_NULL_RETURN(!firstArg.IsNull() && firstArg->IsNativePointer(vm), nullptr);
175     auto* nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
176     return nativeNode;
177 }
178 
GetInstanceId(ArkUIRuntimeCallInfo * runtimeCallInfo)179 int FrameNodeBridge::GetInstanceId(ArkUIRuntimeCallInfo* runtimeCallInfo)
180 {
181     EcmaVM* vm = runtimeCallInfo->GetVM();
182     CHECK_NULL_RETURN(vm, -1);
183     Local<JSValueRef> thirdArg = runtimeCallInfo->GetCallArgRef(2); // index of instanceId
184     CHECK_NULL_RETURN(!thirdArg.IsNull(), -1);
185     return thirdArg->ToNumber(vm)->Value();
186 }
187 
CreateEventTargetObject(EcmaVM * vm,const BaseEventInfo & info)188 Local<panda::ObjectRef> FrameNodeBridge::CreateEventTargetObject(EcmaVM* vm, const BaseEventInfo& info)
189 {
190     const auto& localOffset = info.GetTarget().area.GetOffset();
191     const auto& origin = info.GetTarget().origin;
192     const char* keysOfOffset[] = { "x", "y" };
193     Local<JSValueRef> valuesOfOffset[] = { panda::NumberRef::New(vm, localOffset.GetX().ConvertToVp()),
194         panda::NumberRef::New(vm, localOffset.GetY().ConvertToVp()) };
195     auto offset = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keysOfOffset), keysOfOffset, valuesOfOffset);
196 
197     const char* keysOfGlobalOffset[] = { "x", "y" };
198     Local<JSValueRef> valuesOfGlobalOffset[] = { panda::NumberRef::New(
199                                                      vm, (origin.GetX() + localOffset.GetX()).ConvertToVp()),
200         panda::NumberRef::New(vm, (origin.GetY() + localOffset.GetY()).ConvertToVp()) };
201     auto globalOffset = panda::ObjectRef::NewWithNamedProperties(
202         vm, ArraySize(keysOfGlobalOffset), keysOfGlobalOffset, valuesOfGlobalOffset);
203     const char* keysOfArea[] = { "position", "globalPosition", "width", "height" };
204     Local<JSValueRef> valuesOfArea[] = { offset, globalOffset,
205         panda::NumberRef::New(vm, info.GetTarget().area.GetWidth().ConvertToVp()),
206         panda::NumberRef::New(vm, info.GetTarget().area.GetHeight().ConvertToVp()) };
207     auto area = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keysOfArea), keysOfArea, valuesOfArea);
208     auto target = panda::ObjectRef::New(vm);
209     target->Set(vm, panda::StringRef::NewFromUtf8(vm, "area"), area);
210     if (info.GetTarget().id.empty()) {
211         target->Set(vm, panda::StringRef::NewFromUtf8(vm, "id"), panda::JSValueRef().Undefined(vm));
212     } else {
213         target->Set(vm, panda::StringRef::NewFromUtf8(vm, "id"),
214             panda::StringRef::NewFromUtf8(vm, info.GetTarget().id.c_str()));
215     }
216     return target;
217 }
218 
CreateTouchInfo(EcmaVM * vm,const TouchLocationInfo & touchInfo,TouchEventInfo & info)219 Local<panda::ObjectRef> FrameNodeBridge::CreateTouchInfo(
220     EcmaVM* vm, const TouchLocationInfo& touchInfo, TouchEventInfo& info)
221 {
222     double density = PipelineBase::GetCurrentDensity();
223     const Offset& globalOffset = touchInfo.GetGlobalLocation();
224     const Offset& localOffset = touchInfo.GetLocalLocation();
225     const Offset& screenOffset = touchInfo.GetScreenLocation();
226     const Offset& globalDisplayOffset = touchInfo.GetGlobalDisplayLocation();
227     const char* keys[] = { "type", "id", "displayX", "displayY", "windowX", "windowY", "screenX", "screenY", "x", "y",
228         "pressedTime", "pressure", "width", "height", "hand", "globalDisplayX", "globalDisplayY" };
229     Local<JSValueRef> values[] = { panda::NumberRef::New(vm, static_cast<int32_t>(touchInfo.GetTouchType())),
230         panda::NumberRef::New(vm, touchInfo.GetFingerId()), panda::NumberRef::New(vm, screenOffset.GetX() / density),
231         panda::NumberRef::New(vm, screenOffset.GetY() / density),
232         panda::NumberRef::New(vm, globalOffset.GetX() / density),
233         panda::NumberRef::New(vm, globalOffset.GetY() / density),
234         panda::NumberRef::New(vm, globalOffset.GetX() / density),
235         panda::NumberRef::New(vm, globalOffset.GetY() / density),
236         panda::NumberRef::New(vm, localOffset.GetX() / density),
237         panda::NumberRef::New(vm, localOffset.GetY() / density),
238         panda::NumberRef::New(vm, static_cast<double>(touchInfo.GetPressedTime().time_since_epoch().count())),
239         panda::NumberRef::New(vm, touchInfo.GetForce()),
240         panda::NumberRef::New(vm, touchInfo.GetWidth() / density),
241         panda::NumberRef::New(vm, touchInfo.GetHeight() / density),
242         panda::NumberRef::New(vm, touchInfo.GetOperatingHand()),
243         panda::NumberRef::New(vm, globalDisplayOffset.GetX() / density),
244         panda::NumberRef::New(vm, globalDisplayOffset.GetY() / density) };
245     auto touchInfoObj = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
246     touchInfoObj->SetNativePointerFieldCount(vm, 1);
247     touchInfoObj->SetNativePointerField(vm, 0, static_cast<void*>(&info));
248     return touchInfoObj;
249 }
250 
IsModifiable(ArkUIRuntimeCallInfo * runtimeCallInfo)251 ArkUINativeModuleValue FrameNodeBridge::IsModifiable(ArkUIRuntimeCallInfo* runtimeCallInfo)
252 {
253     EcmaVM* vm = runtimeCallInfo->GetVM();
254     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
255     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::BooleanRef::New(vm, false));
256     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
257     auto result = GetArkUINodeModifiers()->getFrameNodeModifier()->isModifiable(nativeNode);
258     return panda::BooleanRef::New(vm, result);
259 }
260 
MakeFrameNodeInfo(EcmaVM * vm,ArkUINodeHandle frameNode)261 ArkUINativeModuleValue FrameNodeBridge::MakeFrameNodeInfo(EcmaVM* vm, ArkUINodeHandle frameNode)
262 {
263     const char* keys[] = { "nodeId", "nodePtr" };
264     auto nodeId = GetArkUINodeModifiers()->getFrameNodeModifier()->getIdByNodePtr(frameNode);
265     Local<JSValueRef> values[] = { panda::NumberRef::New(vm, nodeId), panda::NativePointerRef::New(vm, frameNode) };
266     auto obj = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
267     return obj;
268 }
269 
CreateFrameNode(ArkUIRuntimeCallInfo * runtimeCallInfo)270 ArkUINativeModuleValue FrameNodeBridge::CreateFrameNode(ArkUIRuntimeCallInfo* runtimeCallInfo)
271 {
272     EcmaVM* vm = runtimeCallInfo->GetVM();
273     auto nodeId = ElementRegister::GetInstance()->MakeUniqueId();
274     auto node = NG::CustomFrameNode::GetOrCreateCustomFrameNode(nodeId);
275     node->SetExclusiveEventForChild(true);
276     node->SetIsArkTsFrameNode(true);
277     auto renderContext = node->GetRenderContext();
278     if (renderContext) {
279         renderContext->SetNeedDebugBoundary(true);
280     }
281     FrameNodeBridge::SetDrawFunc(node, runtimeCallInfo);
282     FrameNodeBridge::SetCustomFunc(node, runtimeCallInfo);
283     const char* keys[] = { "nodeId", "nativeStrongRef" };
284     Local<JSValueRef> values[] = { panda::NumberRef::New(vm, nodeId), NativeUtilsBridge::CreateStrongRef(vm, node) };
285     auto reslut = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
286     return reslut;
287 }
288 
SetCustomFunc(const RefPtr<FrameNode> & frameNode,ArkUIRuntimeCallInfo * runtimeCallInfo)289 void FrameNodeBridge::SetCustomFunc(const RefPtr<FrameNode>& frameNode, ArkUIRuntimeCallInfo* runtimeCallInfo)
290 {
291     CHECK_NULL_VOID(frameNode);
292     EcmaVM* vm = runtimeCallInfo->GetVM();
293     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
294     CHECK_NULL_VOID(firstArg->IsObject(vm));
295     auto obj = Local<panda::ObjectRef>(firstArg);
296 
297     auto customFuncExisted = false;
298     auto measureFuncName = panda::StringRef::NewFromUtf8(vm, "onMeasure");
299     auto measureFuncObj = obj->Get(vm, measureFuncName);
300     auto customNode = AceType::MakeRefPtr<ExtensionCustomNode>();
301     if (measureFuncObj->IsFunction(vm)) {
302         customFuncExisted = true;
303         customNode->SetMeasureCallback(FrameNodeBridge::GetMeasureFunc(vm, obj));
304     }
305     auto layoutFuncName = panda::StringRef::NewFromUtf8(vm, "onLayout");
306     auto layoutFuncObj = obj->Get(vm, layoutFuncName);
307     if (layoutFuncObj->IsFunction(vm)) {
308         customFuncExisted = true;
309         customNode->SetLayoutCallback(FrameNodeBridge::GetLayoutFunc(vm, obj));
310     }
311 
312     if (!customFuncExisted) {
313         return;
314     }
315 
316     frameNode->SetExtensionHandler(customNode);
317 }
318 
GetMeasureFunc(EcmaVM * vm,Local<panda::ObjectRef> obj)319 std::function<void(LayoutConstraintF& layoutConstraint)> FrameNodeBridge::GetMeasureFunc(
320     EcmaVM* vm, Local<panda::ObjectRef> obj)
321 {
322     return [vm, object = JsWeak(panda::CopyableGlobal(vm, obj))](LayoutConstraintF& layoutConstraint) {
323         panda::LocalScope pandaScope(vm);
324         panda::TryCatch trycatch(vm);
325         auto funcName = panda::StringRef::NewFromUtf8(vm, "onMeasure");
326         FrameNodeBridge::FireMeasureCallback(vm, object, layoutConstraint, funcName);
327     };
328 }
329 
GetLayoutFunc(EcmaVM * vm,Local<panda::ObjectRef> obj)330 std::function<void(OffsetF& position)> FrameNodeBridge::GetLayoutFunc(EcmaVM* vm, Local<panda::ObjectRef> obj)
331 {
332     return [vm, object = JsWeak(panda::CopyableGlobal(vm, obj))](OffsetF& position) {
333         panda::LocalScope pandaScope(vm);
334         panda::TryCatch trycatch(vm);
335         auto funcName = panda::StringRef::NewFromUtf8(vm, "onLayout");
336         FrameNodeBridge::FireLayoutCallback(vm, object, position, funcName);
337     };
338 }
339 
FireMeasureCallback(EcmaVM * vm,JsWeak<panda::CopyableGlobal<panda::ObjectRef>> object,LayoutConstraintF & layoutConstraint,Local<panda::StringRef> funcName)340 void FrameNodeBridge::FireMeasureCallback(EcmaVM* vm, JsWeak<panda::CopyableGlobal<panda::ObjectRef>> object,
341     LayoutConstraintF& layoutConstraint, Local<panda::StringRef> funcName)
342 {
343     auto obj = object.Lock();
344     CHECK_NULL_VOID(!obj.IsEmpty());
345     CHECK_NULL_VOID(obj->IsObject(vm));
346     auto funcObj = obj->Get(vm, funcName);
347     CHECK_NULL_VOID(funcObj->IsFunction(vm));
348     panda::Local<panda::FunctionRef> func = funcObj;
349     auto replaceInfinityFunc = [](float value) -> double {
350         double res = static_cast<double>(value);
351         if (GreatOrEqual(res, Infinity<double>())) {
352             return std::numeric_limits<double>::infinity();
353         }
354 
355         if (LessOrEqual(res, -Infinity<double>())) {
356             return -std::numeric_limits<double>::infinity();
357         }
358 
359         return res;
360     };
361 
362     const char* keysOfSize[] = { "height", "width" };
363     Local<JSValueRef> valuesOfMaxSize[] = { panda::NumberRef::New(
364                                                 vm, replaceInfinityFunc(layoutConstraint.maxSize.Height())),
365         panda::NumberRef::New(vm, replaceInfinityFunc(layoutConstraint.maxSize.Width())) };
366     Local<JSValueRef> valuesOfMinSize[] = { panda::NumberRef::New(
367                                                 vm, replaceInfinityFunc(layoutConstraint.minSize.Height())),
368         panda::NumberRef::New(vm, replaceInfinityFunc(layoutConstraint.minSize.Width())) };
369     Local<JSValueRef> valuesOfPercentReference[] = {
370         panda::NumberRef::New(vm, replaceInfinityFunc(layoutConstraint.percentReference.Height())),
371         panda::NumberRef::New(vm, replaceInfinityFunc(layoutConstraint.percentReference.Width()))
372     };
373     auto maxSizeObj = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keysOfSize), keysOfSize, valuesOfMaxSize);
374     auto minSizeObj = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keysOfSize), keysOfSize, valuesOfMinSize);
375     auto percentReferenceObj =
376         panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keysOfSize), keysOfSize, valuesOfPercentReference);
377 
378     Local<JSValueRef> values[] = { maxSizeObj, minSizeObj, percentReferenceObj };
379     const char* keys[] = { "maxSize", "minSize", "percentReference" };
380     auto constraintObj = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
381     panda::Local<panda::JSValueRef> params[1] = { constraintObj };
382     func->Call(vm, obj.ToLocal(), params, 1);
383 }
384 
FireLayoutCallback(EcmaVM * vm,JsWeak<panda::CopyableGlobal<panda::ObjectRef>> object,OffsetF & position,Local<panda::StringRef> funcName)385 void FrameNodeBridge::FireLayoutCallback(EcmaVM* vm, JsWeak<panda::CopyableGlobal<panda::ObjectRef>> object,
386     OffsetF& position, Local<panda::StringRef> funcName)
387 {
388     auto obj = object.Lock();
389     CHECK_NULL_VOID(!obj.IsEmpty());
390     CHECK_NULL_VOID(obj->IsObject(vm));
391     auto funcObj = obj->Get(vm, funcName);
392     CHECK_NULL_VOID(funcObj->IsFunction(vm));
393     panda::Local<panda::FunctionRef> func = funcObj;
394 
395     const char* keys[] = { "x", "y" };
396     Local<JSValueRef> valuesOfPosition[] = { panda::NumberRef::New(vm, static_cast<double>(position.GetX())),
397         panda::NumberRef::New(vm, static_cast<double>(position.GetY())) };
398 
399     auto positionObj = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, valuesOfPosition);
400     panda::Local<panda::JSValueRef> params[1] = { positionObj };
401     func->Call(vm, obj.ToLocal(), params, 1);
402 }
403 
ParseNodeType(ArkUIRuntimeCallInfo * runtimeCallInfo,EcmaVM * vm,int32_t nodeId,RefPtr<FrameNode> & node)404 static ArkUINodeType ParseNodeType(
405     ArkUIRuntimeCallInfo* runtimeCallInfo, EcmaVM* vm, int32_t nodeId, RefPtr<FrameNode>& node)
406 {
407     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(1);
408     std::string type = firstArg->IsString(vm) ? firstArg->ToString(vm)->ToString(vm) : "";
409     static const std::unordered_map<std::string, ArkUINodeType> typeMap = { { "Text", ARKUI_TEXT },
410         { "Column", ARKUI_COLUMN }, { "Row", ARKUI_ROW }, { "Stack", ARKUI_STACK }, { "Blank", ARKUI_BLANK },
411         { "Image", ARKUI_IMAGE }, { "GridRow", ARKUI_GRID_ROW }, { "GridCol", ARKUI_GRID_COL }, { "Flex", ARKUI_FLEX },
412         { "Swiper", ARKUI_SWIPER }, { "Progress", ARKUI_PROGRESS }, { "List", ARKUI_LIST },
413         { "ListItem", ARKUI_LIST_ITEM }, { "Scroll", ARKUI_SCROLL }, { "RelativeContainer", ARKUI_RELATIVE_CONTAINER },
414         { "Divider", ARKUI_DIVIDER }, { "LoadingProgress", ARKUI_LOADING_PROGRESS }, { "TextInput", ARKUI_TEXT_INPUT },
415         { "Search", ARKUI_SEARCH }, { "Button", ARKUI_BUTTON }, { "XComponent", ARKUI_XCOMPONENT },
416         { "ListItemGroup", ARKUI_LIST_ITEM_GROUP }, { "WaterFlow", ARKUI_WATER_FLOW },
417         { "FlowItem", ARKUI_FLOW_ITEM }, { "QRCode", ARKUI_QRCODE }, { "Badge", ARKUI_BADGE }, { "Grid", ARKUI_GRID },
418         { "GridItem", ARKUI_GRID_ITEM }, { "SymbolGlyph", ARKUI_SYMBOL_GLYPH}, { "TextClock", ARKUI_TEXT_CLOCK },
419         { "TextTimer", ARKUI_TEXT_TIMER }, { "Marquee", ARKUI_MARQUEE }, { "TextArea", ARKUI_TEXTAREA },
420         { "Checkbox", ARKUI_CHECKBOX }, {"CheckboxGroup", ARKUI_CHECK_BOX_GROUP }, { "Rating", ARKUI_RATING},
421         { "Radio", ARKUI_RADIO }, { "Slider", ARKUI_SLIDER }, { "Select", ARKUI_SELECT }, { "Toggle", ARKUI_TOGGLE },
422         { "EmbeddedComponent", ARKUI_EMBEDDED_COMPONENT } };
423     ArkUINodeType nodeType = ARKUI_CUSTOM;
424     auto iter = typeMap.find(type);
425     if (iter != typeMap.end()) {
426         nodeType = iter->second;
427     }
428     return nodeType;
429 }
430 
HandleNodeParams(ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUINodeType nodeType,int32_t nodeId,RefPtr<FrameNode> & node)431 static void HandleNodeParams(
432     ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUINodeType nodeType, int32_t nodeId, RefPtr<FrameNode>& node)
433 {
434     ArkUINodeHandle nodePtr = nullptr;
435     if (nodeType == ARKUI_XCOMPONENT) {
436 #ifdef XCOMPONENT_SUPPORTED
437         ArkUI_XComponent_Params params;
438         XComponentBridge::ParseParams(runtimeCallInfo, params);
439         params.nodeType = ARKUI_XCOMPONENT;
440         nodePtr = GetArkUIFullNodeAPI()->getBasicAPI()->createNodeWithParams(nodeType, nodeId, 0, params);
441         XComponentBridge::SetControllerCallback(runtimeCallInfo, reinterpret_cast<FrameNode*>(nodePtr));
442 #else
443         nodePtr = GetArkUIFullNodeAPI()->getBasicAPI()->createNode(nodeType, nodeId, 0);
444 #endif
445     } else if (nodeType == ARKUI_TOGGLE) {
446         ArkUI_Toggle_Params params;
447         params.nodeType = ARKUI_TOGGLE;
448         ToggleBridge::ParseParams(runtimeCallInfo, params);
449         nodePtr = GetArkUIFullNodeAPI()->getBasicAPI()->createNodeWithParams(nodeType, nodeId, 0, params);
450     } else {
451         nodePtr = GetArkUIFullNodeAPI()->getBasicAPI()->createNode(nodeType, nodeId, 0);
452     }
453     if (nodePtr) {
454         node = AceType::Claim(reinterpret_cast<FrameNode*>(nodePtr));
455         node->SetIsArkTsFrameNode(true);
456         auto renderContext = node->GetRenderContext();
457         if (renderContext) {
458             renderContext->SetNeedDebugBoundary(true);
459         }
460         // let 'node' take the reference, so decrease ref of C node
461         node->DecRefCount();
462     }
463 }
464 
CreateTypedFrameNode(ArkUIRuntimeCallInfo * runtimeCallInfo)465 ArkUINativeModuleValue FrameNodeBridge::CreateTypedFrameNode(ArkUIRuntimeCallInfo* runtimeCallInfo)
466 {
467     EcmaVM* vm = runtimeCallInfo->GetVM();
468     auto nodeId = ElementRegister::GetInstance()->MakeUniqueId();
469     RefPtr<FrameNode> node;
470     ArkUINodeType nodeType = ParseNodeType(runtimeCallInfo, vm, nodeId, node);
471     if (nodeType != ARKUI_CUSTOM) {
472         HandleNodeParams(runtimeCallInfo, nodeType, nodeId, node);
473     }
474 
475     const char* keys[] = { "nodeId", "nativeStrongRef" };
476     Local<JSValueRef> values[] = { panda::NumberRef::New(vm, nodeId), NativeUtilsBridge::CreateStrongRef(vm, node) };
477     auto reslut = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
478     return reslut;
479 } // namespace OHOS::Ace::NG
480 
Invalidate(ArkUIRuntimeCallInfo * runtimeCallInfo)481 ArkUINativeModuleValue FrameNodeBridge::Invalidate(ArkUIRuntimeCallInfo* runtimeCallInfo)
482 {
483     EcmaVM* vm = runtimeCallInfo->GetVM();
484     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
485     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
486     GetArkUINodeModifiers()->getFrameNodeModifier()->invalidate(nativeNode);
487     return panda::JSValueRef::Undefined(vm);
488 }
489 
ApplyAttributesFinish(ArkUIRuntimeCallInfo * runtimeCallInfo)490 ArkUINativeModuleValue FrameNodeBridge::ApplyAttributesFinish(ArkUIRuntimeCallInfo* runtimeCallInfo)
491 {
492     EcmaVM* vm = runtimeCallInfo->GetVM();
493     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
494     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
495     GetArkUINodeModifiers()->getFrameNodeModifier()->applyAttributesFinish(nativeNode);
496     return panda::JSValueRef::Undefined(vm);
497 }
498 
SetDrawFunc(const RefPtr<FrameNode> & frameNode,ArkUIRuntimeCallInfo * runtimeCallInfo)499 void FrameNodeBridge::SetDrawFunc(const RefPtr<FrameNode>& frameNode, ArkUIRuntimeCallInfo* runtimeCallInfo)
500 {
501     CHECK_NULL_VOID(frameNode);
502     EcmaVM* vm = runtimeCallInfo->GetVM();
503     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
504     CHECK_NULL_VOID(firstArg->IsObject(vm));
505     auto obj = Local<panda::ObjectRef>(firstArg);
506     auto funcName = panda::StringRef::NewFromUtf8(vm, "onDraw");
507     auto funcObj = obj->Get(vm, funcName);
508     CHECK_NULL_VOID(funcObj->IsFunction(vm));
509     auto drawCallback = [vm, object = JsWeak(panda::CopyableGlobal(vm, obj))](NG::DrawingContext& context) {
510         panda::LocalScope pandaScope(vm);
511         panda::TryCatch trycatch(vm);
512         auto funcName = panda::StringRef::NewFromUtf8(vm, "onDraw");
513         RenderNodeBridge::FireDrawCallback(vm, object, context, funcName);
514     };
515     auto pattern = frameNode->GetPattern<NG::CustomFrameNodePattern>();
516     pattern->SetDrawCallback(std::move(drawCallback));
517 }
518 
AddBuilderNode(ArkUIRuntimeCallInfo * runtimeCallInfo)519 ArkUINativeModuleValue FrameNodeBridge::AddBuilderNode(ArkUIRuntimeCallInfo* runtimeCallInfo)
520 {
521     EcmaVM* vm = runtimeCallInfo->GetVM();
522     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
523     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
524     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
525     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
526     auto childNativeNode = nodePtr(secondArg->ToNativePointer(vm)->Value());
527     GetArkUINodeModifiers()->getFrameNodeModifier()->addBuilderNode(nativeNode, childNativeNode);
528     return panda::JSValueRef::Undefined(vm);
529 }
530 
AppendChild(ArkUIRuntimeCallInfo * runtimeCallInfo)531 ArkUINativeModuleValue FrameNodeBridge::AppendChild(ArkUIRuntimeCallInfo* runtimeCallInfo)
532 {
533     EcmaVM* vm = runtimeCallInfo->GetVM();
534     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
535     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::BooleanRef::New(vm, true));
536     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
537     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
538     auto childNativeNode = nodePtr(secondArg->ToNativePointer(vm)->Value());
539     auto result = GetArkUINodeModifiers()->getFrameNodeModifier()->appendChild(nativeNode, childNativeNode);
540     return panda::BooleanRef::New(vm, result);
541 }
InsertChildAfter(ArkUIRuntimeCallInfo * runtimeCallInfo)542 ArkUINativeModuleValue FrameNodeBridge::InsertChildAfter(ArkUIRuntimeCallInfo* runtimeCallInfo)
543 {
544     EcmaVM* vm = runtimeCallInfo->GetVM();
545     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
546     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::BooleanRef::New(vm, true));
547     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
548     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
549     auto child = nodePtr(secondArg->ToNativePointer(vm)->Value());
550     Local<JSValueRef> thirdArg = runtimeCallInfo->GetCallArgRef(2); // 2 : index to get the insert node
551     if (thirdArg.IsNull()) {
552         GetArkUINodeModifiers()->getFrameNodeModifier()->insertChildAfter(nativeNode, child, nullptr);
553         return panda::JSValueRef::Undefined(vm);
554     }
555     auto sibling = nodePtr(thirdArg->ToNativePointer(vm)->Value());
556     auto result = GetArkUINodeModifiers()->getFrameNodeModifier()->insertChildAfter(nativeNode, child, sibling);
557     return panda::BooleanRef::New(vm, result);
558 }
RemoveBuilderNode(ArkUIRuntimeCallInfo * runtimeCallInfo)559 ArkUINativeModuleValue FrameNodeBridge::RemoveBuilderNode(ArkUIRuntimeCallInfo* runtimeCallInfo)
560 {
561     EcmaVM* vm = runtimeCallInfo->GetVM();
562     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
563     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
564     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
565     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
566     auto childNativeNode = nodePtr(secondArg->ToNativePointer(vm)->Value());
567     GetArkUINodeModifiers()->getFrameNodeModifier()->removeBuilderNode(nativeNode, childNativeNode);
568     return panda::JSValueRef::Undefined(vm);
569 }
RemoveChild(ArkUIRuntimeCallInfo * runtimeCallInfo)570 ArkUINativeModuleValue FrameNodeBridge::RemoveChild(ArkUIRuntimeCallInfo* runtimeCallInfo)
571 {
572     EcmaVM* vm = runtimeCallInfo->GetVM();
573     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
574     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
575     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
576     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
577     auto childNativeNode = nodePtr(secondArg->ToNativePointer(vm)->Value());
578     GetArkUINodeModifiers()->getFrameNodeModifier()->removeChild(nativeNode, childNativeNode);
579     return panda::JSValueRef::Undefined(vm);
580 }
ClearBuilderNode(ArkUIRuntimeCallInfo * runtimeCallInfo)581 ArkUINativeModuleValue FrameNodeBridge::ClearBuilderNode(ArkUIRuntimeCallInfo* runtimeCallInfo)
582 {
583     EcmaVM* vm = runtimeCallInfo->GetVM();
584     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
585     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
586     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
587     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
588     GetArkUINodeModifiers()->getFrameNodeModifier()->clearBuilderNode(nativeNode);
589     return panda::JSValueRef::Undefined(vm);
590 }
ClearChildren(ArkUIRuntimeCallInfo * runtimeCallInfo)591 ArkUINativeModuleValue FrameNodeBridge::ClearChildren(ArkUIRuntimeCallInfo* runtimeCallInfo)
592 {
593     EcmaVM* vm = runtimeCallInfo->GetVM();
594     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
595     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
596     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
597     GetArkUINodeModifiers()->getFrameNodeModifier()->clearChildren(nativeNode);
598     return panda::JSValueRef::Undefined(vm);
599 }
600 
GetChildrenCount(ArkUIRuntimeCallInfo * runtimeCallInfo)601 ArkUINativeModuleValue FrameNodeBridge::GetChildrenCount(ArkUIRuntimeCallInfo* runtimeCallInfo)
602 {
603     EcmaVM* vm = runtimeCallInfo->GetVM();
604     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
605     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::NumberRef::New(vm, 0));
606     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
607     int isExpanded = GetIsExpanded(runtimeCallInfo, 1);
608     auto number = GetArkUINodeModifiers()->getFrameNodeModifier()->getChildrenCount(nativeNode, isExpanded);
609     return panda::NumberRef::New(vm, number);
610 }
611 
GetChild(ArkUIRuntimeCallInfo * runtimeCallInfo)612 ArkUINativeModuleValue FrameNodeBridge::GetChild(ArkUIRuntimeCallInfo* runtimeCallInfo)
613 {
614     EcmaVM* vm = runtimeCallInfo->GetVM();
615     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
616     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
617     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
618     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
619     int index = secondArg->ToNumber(vm)->Value();
620     int expandMode = GetExpandMode(runtimeCallInfo, 2);
621     auto nodePtr = GetArkUINodeModifiers()->getFrameNodeModifier()->getChild(nativeNode, index, expandMode);
622     CHECK_NULL_RETURN(nodePtr, panda::JSValueRef::Undefined(vm));
623     return FrameNodeBridge::MakeFrameNodeInfo(vm, nodePtr);
624 }
625 
GetFirstChildIndexWithoutExpand(ArkUIRuntimeCallInfo * runtimeCallInfo)626 ArkUINativeModuleValue FrameNodeBridge::GetFirstChildIndexWithoutExpand(ArkUIRuntimeCallInfo* runtimeCallInfo)
627 {
628     EcmaVM* vm = runtimeCallInfo->GetVM();
629     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
630     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::NumberRef::New(vm, -1));
631     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
632     uint32_t index = -1;
633     GetArkUINodeModifiers()->getFrameNodeModifier()->getFirstChildIndexWithoutExpand(nativeNode, &index);
634     return panda::NumberRef::New(vm, index);
635 }
636 
GetLastChildIndexWithoutExpand(ArkUIRuntimeCallInfo * runtimeCallInfo)637 ArkUINativeModuleValue FrameNodeBridge::GetLastChildIndexWithoutExpand(ArkUIRuntimeCallInfo* runtimeCallInfo)
638 {
639     EcmaVM* vm = runtimeCallInfo->GetVM();
640     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
641     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::NumberRef::New(vm, -1));
642     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
643     uint32_t index = -1;
644     GetArkUINodeModifiers()->getFrameNodeModifier()->getLastChildIndexWithoutExpand(nativeNode, &index);
645     return panda::NumberRef::New(vm, index);
646 }
647 
GetFirst(ArkUIRuntimeCallInfo * runtimeCallInfo)648 ArkUINativeModuleValue FrameNodeBridge::GetFirst(ArkUIRuntimeCallInfo* runtimeCallInfo)
649 {
650     EcmaVM* vm = runtimeCallInfo->GetVM();
651     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
652     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
653     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
654     int isExpanded = GetIsExpanded(runtimeCallInfo, 1);
655     auto nodePtr = GetArkUINodeModifiers()->getFrameNodeModifier()->getFirst(nativeNode, isExpanded);
656     CHECK_NULL_RETURN(nodePtr, panda::JSValueRef::Undefined(vm));
657     return FrameNodeBridge::MakeFrameNodeInfo(vm, nodePtr);
658 }
659 
GetNextSibling(ArkUIRuntimeCallInfo * runtimeCallInfo)660 ArkUINativeModuleValue FrameNodeBridge::GetNextSibling(ArkUIRuntimeCallInfo* runtimeCallInfo)
661 {
662     EcmaVM* vm = runtimeCallInfo->GetVM();
663     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
664     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
665     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
666     int isExpanded = GetIsExpanded(runtimeCallInfo, 1);
667     auto nodePtr = GetArkUINodeModifiers()->getFrameNodeModifier()->getNextSibling(nativeNode, isExpanded);
668     CHECK_NULL_RETURN(nodePtr, panda::JSValueRef::Undefined(vm));
669     return FrameNodeBridge::MakeFrameNodeInfo(vm, nodePtr);
670 }
671 
GetPreviousSibling(ArkUIRuntimeCallInfo * runtimeCallInfo)672 ArkUINativeModuleValue FrameNodeBridge::GetPreviousSibling(ArkUIRuntimeCallInfo* runtimeCallInfo)
673 {
674     EcmaVM* vm = runtimeCallInfo->GetVM();
675     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
676     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
677     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
678     int isExpanded = GetIsExpanded(runtimeCallInfo, 1);
679     auto nodePtr = GetArkUINodeModifiers()->getFrameNodeModifier()->getPreviousSibling(nativeNode, isExpanded);
680     CHECK_NULL_RETURN(nodePtr, panda::JSValueRef::Undefined(vm));
681     return FrameNodeBridge::MakeFrameNodeInfo(vm, nodePtr);
682 }
683 
GetParent(ArkUIRuntimeCallInfo * runtimeCallInfo)684 ArkUINativeModuleValue FrameNodeBridge::GetParent(ArkUIRuntimeCallInfo* runtimeCallInfo)
685 {
686     EcmaVM* vm = runtimeCallInfo->GetVM();
687     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
688     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
689     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
690     auto nodePtr = GetArkUINodeModifiers()->getFrameNodeModifier()->getParent(nativeNode);
691     CHECK_NULL_RETURN(nodePtr, panda::JSValueRef::Undefined(vm));
692     return FrameNodeBridge::MakeFrameNodeInfo(vm, nodePtr);
693 }
MoveTo(ArkUIRuntimeCallInfo * runtimeCallInfo)694 ArkUINativeModuleValue FrameNodeBridge::MoveTo(ArkUIRuntimeCallInfo* runtimeCallInfo)
695 {
696     EcmaVM* vm = runtimeCallInfo->GetVM();
697     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
698     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::BooleanRef::New(vm, true));
699     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
700     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
701     auto targetNativeNode = nodePtr(secondArg->ToNativePointer(vm)->Value());
702     Local<JSValueRef> thirdArg = runtimeCallInfo->GetCallArgRef(2); // 2 : index of child node position
703     int index = thirdArg->ToNumber(vm)->Value();
704     GetArkUINodeModifiers()->getFrameNodeModifier()->moveNodeTo(nativeNode, targetNativeNode, index);
705     return panda::JSValueRef::Undefined(vm);
706 }
GetIdByNodePtr(ArkUIRuntimeCallInfo * runtimeCallInfo)707 ArkUINativeModuleValue FrameNodeBridge::GetIdByNodePtr(ArkUIRuntimeCallInfo* runtimeCallInfo)
708 {
709     EcmaVM* vm = runtimeCallInfo->GetVM();
710     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
711     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::NumberRef::New(vm, -1));
712     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
713     auto nodeId = GetArkUINodeModifiers()->getFrameNodeModifier()->getIdByNodePtr(nativeNode);
714     return panda::NumberRef::New(vm, nodeId);
715 }
GetOperatingHand(GestureEvent & info)716 static int32_t GetOperatingHand(GestureEvent& info)
717 {
718     int32_t left = 0;
719     int32_t right = 0;
720     for (const FingerInfo& fingerInfo : info.GetFingerList()) {
721         if (fingerInfo.operatingHand_ == HAND_LEFT) {
722             ++left;
723         } else if (fingerInfo.operatingHand_ == HAND_RIGHT) {
724             ++right;
725         }
726     }
727     if (left > right) {
728         return HAND_LEFT;
729     } else if (right > left) {
730         return HAND_RIGHT;
731     }
732     return HAND_NONE;
733 }
CreateGestureEventInfo(EcmaVM * vm,GestureEvent & info)734 Local<panda::ObjectRef> FrameNodeBridge::CreateGestureEventInfo(EcmaVM* vm, GestureEvent& info)
735 {
736     const Offset& globalOffset = info.GetGlobalLocation();
737     const Offset& localOffset = info.GetLocalLocation();
738     const Offset& screenOffset = info.GetScreenLocation();
739     double density = PipelineBase::GetCurrentDensity();
740     const Offset& globalDisplayOffset = info.GetGlobalDisplayLocation();
741     const char* keys[] = { "displayX", "displayY", "windowX", "windowY", "screenX", "screenY", "x", "y", "timestamp",
742         "source", "pressure", "deviceId", "hand", "globalDisplayX", "globalDisplayY" };
743     Local<JSValueRef> values[] = { panda::NumberRef::New(vm, screenOffset.GetX() / density),
744         panda::NumberRef::New(vm, screenOffset.GetY() / density),
745         panda::NumberRef::New(vm, globalOffset.GetX() / density),
746         panda::NumberRef::New(vm, globalOffset.GetY() / density),
747         panda::NumberRef::New(vm, globalOffset.GetX() / density),
748         panda::NumberRef::New(vm, globalOffset.GetY() / density),
749         panda::NumberRef::New(vm, localOffset.GetX() / density),
750         panda::NumberRef::New(vm, localOffset.GetY() / density),
751         panda::NumberRef::New(vm, static_cast<double>(info.GetTimeStamp().time_since_epoch().count())),
752         panda::NumberRef::New(vm, static_cast<int32_t>(info.GetSourceDevice())),
753         panda::NumberRef::New(vm, info.GetForce()),
754         panda::NumberRef::New(vm, info.GetDeviceId()),
755         panda::NumberRef::New(vm, GetOperatingHand(info)),
756         panda::NumberRef::New(vm, globalDisplayOffset.GetX() / density),
757         panda::NumberRef::New(vm, globalDisplayOffset.GetY() / density) };
758     auto obj = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
759     obj->Set(
760         vm, panda::StringRef::NewFromUtf8(vm, "targetDisplayId"), panda::NumberRef::New(vm, info.GetTargetDisplayId()));
761     obj->Set(vm, panda::StringRef::NewFromUtf8(vm, "tiltX"),
762         panda::NumberRef::New(vm, static_cast<int32_t>(info.GetTiltX().value_or(0.0f))));
763     obj->Set(vm, panda::StringRef::NewFromUtf8(vm, "tiltY"),
764         panda::NumberRef::New(vm, static_cast<int32_t>(info.GetTiltY().value_or(0.0f))));
765     obj->Set(vm, panda::StringRef::NewFromUtf8(vm, "rollAngle"),
766         panda::NumberRef::New(vm, static_cast<int32_t>(info.GetRollAngle().value_or(0.0f))));
767     obj->Set(
768         vm, panda::StringRef::NewFromUtf8(vm, "axisVertical"), panda::NumberRef::New(vm, static_cast<int32_t>(0.0f)));
769     obj->Set(
770         vm, panda::StringRef::NewFromUtf8(vm, "axisHorizontal"), panda::NumberRef::New(vm, static_cast<int32_t>(0.0f)));
771     obj->Set(vm, panda::StringRef::NewFromUtf8(vm, "sourceTool"),
772         panda::NumberRef::New(vm, static_cast<int32_t>(static_cast<int32_t>(info.GetSourceTool()))));
773     obj->Set(vm, panda::StringRef::NewFromUtf8(vm, "target"), CreateEventTargetObject(vm, info));
774     obj->Set(vm, panda::StringRef::NewFromUtf8(vm, "getModifierKeyState"),
775         panda::FunctionRef::New(vm, ArkTSUtils::JsGetModifierKeyState));
776     obj->SetNativePointerFieldCount(vm, 1);
777     obj->SetNativePointerField(vm, 0, static_cast<void*>(&info));
778     return obj;
779 }
780 
SetOnClick(ArkUIRuntimeCallInfo * runtimeCallInfo)781 ArkUINativeModuleValue FrameNodeBridge::SetOnClick(ArkUIRuntimeCallInfo* runtimeCallInfo)
782 {
783     EcmaVM* vm = runtimeCallInfo->GetVM();
784     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
785     auto* nativeNode = GetFrameNode(runtimeCallInfo);
786     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
787     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
788     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
789     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
790     if (secondeArg->IsUndefined()) {
791         NG::ViewAbstract::ClearJSFrameNodeOnClick(frameNode);
792         return panda::JSValueRef::Undefined(vm);
793     }
794     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
795     auto obj = secondeArg->ToObject(vm);
796     auto containerId = GetInstanceId(runtimeCallInfo);
797     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
798     panda::Local<panda::FunctionRef> func = obj;
799     auto flag = IsCustomFrameNode(frameNode);
800     auto onClick = [vm, func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
801                        node = AceType::WeakClaim(frameNode), containerId](GestureEvent& info) {
802         panda::JsiFastNativeScope fastNativeScope(vm);
803         panda::LocalScope pandaScope(vm);
804         panda::TryCatch trycatch(vm);
805         ContainerScope scope(containerId);
806         auto function = func.Lock();
807         CHECK_NULL_VOID(!function.IsEmpty());
808         CHECK_NULL_VOID(function->IsFunction(vm));
809         PipelineContext::SetCallBackNode(node);
810         auto obj = CreateGestureEventInfo(vm, info);
811         panda::Local<panda::JSValueRef> params[1] = { obj };
812         function->Call(vm, function.ToLocal(), params, 1);
813     };
814     NG::ViewAbstract::SetJSFrameNodeOnClick(frameNode, std::move(onClick));
815     return panda::JSValueRef::Undefined(vm);
816 }
817 
CreateTouchEventInfoObj(EcmaVM * vm,TouchEventInfo & info)818 Local<panda::ObjectRef> FrameNodeBridge::CreateTouchEventInfoObj(EcmaVM* vm, TouchEventInfo& info)
819 {
820     const char* keys[] = { "source", "timestamp", "target", "pressure", "deviceId" };
821     Local<JSValueRef> values[] = { panda::NumberRef::New(vm, static_cast<int32_t>(info.GetSourceDevice())),
822         panda::NumberRef::New(vm, static_cast<double>(info.GetTimeStamp().time_since_epoch().count())),
823         CreateEventTargetObject(vm, info), panda::NumberRef::New(vm, info.GetForce()),
824         panda::NumberRef::New(vm, info.GetDeviceId()) };
825     return panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
826 }
827 
CreateTouchEventInfo(EcmaVM * vm,TouchEventInfo & info)828 Local<panda::ObjectRef> FrameNodeBridge::CreateTouchEventInfo(EcmaVM* vm, TouchEventInfo& info)
829 {
830     panda::JsiFastNativeScope fastNativeScope(vm);
831     auto eventObj = CreateTouchEventInfoObj(vm, info);
832     eventObj->SetNativePointerFieldCount(vm, 1);
833     eventObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "tiltX"),
834         panda::NumberRef::New(vm, static_cast<int32_t>(info.GetTiltX().value_or(0.0f))));
835     eventObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "tiltY"),
836         panda::NumberRef::New(vm, static_cast<int32_t>(info.GetTiltY().value_or(0.0f))));
837     eventObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "rollAngle"),
838         panda::NumberRef::New(vm, static_cast<int32_t>(info.GetRollAngle().value_or(0.0f))));
839     eventObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "sourceTool"),
840         panda::NumberRef::New(vm, static_cast<int32_t>(static_cast<int32_t>(info.GetSourceTool()))));
841     auto touchArr = panda::ArrayRef::New(vm);
842     const std::list<TouchLocationInfo>& touchList = info.GetTouches();
843     uint32_t idx = 0;
844     for (const TouchLocationInfo& location : touchList) {
845         panda::ArrayRef::SetValueAt(vm, touchArr, idx++, CreateTouchInfo(vm, location, info));
846     }
847     eventObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "touches"), touchArr);
848     auto changeTouchArr = panda::ArrayRef::New(vm);
849     idx = 0; // reset index counter
850     const std::list<TouchLocationInfo>& changeTouch = info.GetChangedTouches();
851     for (const TouchLocationInfo& change : changeTouch) {
852         panda::ArrayRef::SetValueAt(vm, changeTouchArr, idx++, CreateTouchInfo(vm, change, info));
853     }
854     if (changeTouch.size() > 0) {
855         eventObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "type"),
856             panda::NumberRef::New(vm, static_cast<int32_t>(changeTouch.front().GetTouchType())));
857     }
858     eventObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "changedTouches"), changeTouchArr);
859     eventObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "stopPropagation"),
860         panda::FunctionRef::New(vm, Framework::JsStopPropagation));
861     eventObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "getHistoricalPoints"),
862         panda::FunctionRef::New(vm, Framework::JsGetHistoricalPoints));
863     eventObj->Set(
864         vm, panda::StringRef::NewFromUtf8(vm, "axisVertical"), panda::NumberRef::New(vm, static_cast<int32_t>(0.0f)));
865     eventObj->Set(
866         vm, panda::StringRef::NewFromUtf8(vm, "axisHorizontal"), panda::NumberRef::New(vm, static_cast<int32_t>(0.0f)));
867     eventObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "preventDefault"),
868         panda::FunctionRef::New(vm, Framework::JsTouchPreventDefault));
869     eventObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "getModifierKeyState"),
870         panda::FunctionRef::New(vm, ArkTSUtils::JsGetModifierKeyState));
871     eventObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "targetDisplayId"),
872         panda::NumberRef::New(vm, info.GetTargetDisplayId()));
873     eventObj->SetNativePointerField(vm, 0, static_cast<void*>(&info));
874     return eventObj;
875 }
876 
SetOnTouch(ArkUIRuntimeCallInfo * runtimeCallInfo)877 ArkUINativeModuleValue FrameNodeBridge::SetOnTouch(ArkUIRuntimeCallInfo* runtimeCallInfo)
878 {
879     EcmaVM* vm = runtimeCallInfo->GetVM();
880     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
881     auto* nativeNode = GetFrameNode(runtimeCallInfo);
882     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
883     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
884     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
885     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
886     if (secondeArg->IsUndefined()) {
887         NG::ViewAbstract::ClearJSFrameNodeOnTouch(frameNode);
888         return panda::JSValueRef::Undefined(vm);
889     }
890     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
891     auto obj = secondeArg->ToObject(vm);
892     auto containerId = Container::CurrentId();
893     panda::Local<panda::FunctionRef> func = obj;
894     auto flag = IsCustomFrameNode(frameNode);
895     auto onTouch = [vm, func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
896                        node = AceType::WeakClaim(frameNode), containerId](TouchEventInfo& info) {
897         panda::JsiFastNativeScope fastNativeScope(vm);
898         panda::LocalScope pandaScope(vm);
899         panda::TryCatch trycatch(vm);
900         ContainerScope scope(containerId);
901         auto function = func.Lock();
902         CHECK_NULL_VOID(!function.IsEmpty());
903         CHECK_NULL_VOID(function->IsFunction(vm));
904         PipelineContext::SetCallBackNode(node);
905         auto eventObj = CreateTouchEventInfo(vm, info);
906         panda::Local<panda::JSValueRef> params[1] = { eventObj };
907         function->Call(vm, function.ToLocal(), params, 1);
908     };
909     NG::ViewAbstract::SetJSFrameNodeOnTouch(frameNode, std::move(onTouch));
910     return panda::JSValueRef::Undefined(vm);
911 }
912 
SetOnAppear(ArkUIRuntimeCallInfo * runtimeCallInfo)913 ArkUINativeModuleValue FrameNodeBridge::SetOnAppear(ArkUIRuntimeCallInfo* runtimeCallInfo)
914 {
915     EcmaVM* vm = runtimeCallInfo->GetVM();
916     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
917     auto* nativeNode = GetFrameNode(runtimeCallInfo);
918     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
919     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
920     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
921     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
922     if (secondeArg->IsUndefined()) {
923         NG::ViewAbstract::ClearJSFrameNodeOnAppear(frameNode);
924         return panda::JSValueRef::Undefined(vm);
925     }
926     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
927     auto obj = secondeArg->ToObject(vm);
928     auto containerId = GetInstanceId(runtimeCallInfo);
929     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
930     panda::Local<panda::FunctionRef> func = obj;
931     auto flag = IsCustomFrameNode(frameNode);
932     auto onAppear = [vm, func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
933                         node = AceType::WeakClaim(frameNode), containerId]() {
934         panda::LocalScope pandaScope(vm);
935         panda::TryCatch trycatch(vm);
936         ContainerScope scope(containerId);
937         auto function = func.Lock();
938         CHECK_NULL_VOID(!function.IsEmpty());
939         CHECK_NULL_VOID(function->IsFunction(vm));
940         PipelineContext::SetCallBackNode(node);
941         function->Call(vm, function.ToLocal(), nullptr, 0);
942     };
943     NG::ViewAbstract::SetJSFrameNodeOnAppear(frameNode, std::move(onAppear));
944     return panda::JSValueRef::Undefined(vm);
945 }
946 
SetOnDisappear(ArkUIRuntimeCallInfo * runtimeCallInfo)947 ArkUINativeModuleValue FrameNodeBridge::SetOnDisappear(ArkUIRuntimeCallInfo* runtimeCallInfo)
948 {
949     EcmaVM* vm = runtimeCallInfo->GetVM();
950     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
951     auto* nativeNode = GetFrameNode(runtimeCallInfo);
952     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
953     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
954     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
955     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
956     if (secondeArg->IsUndefined()) {
957         NG::ViewAbstract::ClearJSFrameNodeOnDisappear(frameNode);
958         return panda::JSValueRef::Undefined(vm);
959     }
960     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
961     auto obj = secondeArg->ToObject(vm);
962     auto containerId = GetInstanceId(runtimeCallInfo);
963     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
964     panda::Local<panda::FunctionRef> func = obj;
965     auto flag = IsCustomFrameNode(frameNode);
966     auto onDisappear = [vm, func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
967                            node = AceType::WeakClaim(frameNode), containerId]() {
968         panda::LocalScope pandaScope(vm);
969         panda::TryCatch trycatch(vm);
970         ContainerScope scope(containerId);
971         auto function = func.Lock();
972         CHECK_NULL_VOID(!function.IsEmpty());
973         CHECK_NULL_VOID(function->IsFunction(vm));
974         PipelineContext::SetCallBackNode(node);
975         function->Call(vm, function.ToLocal(), nullptr, 0);
976     };
977     NG::ViewAbstract::SetJSFrameNodeOnDisappear(frameNode, std::move(onDisappear));
978     return panda::JSValueRef::Undefined(vm);
979 }
980 
CreateKeyEventInfoObj(EcmaVM * vm,KeyEventInfo & info)981 Local<panda::ObjectRef> FrameNodeBridge::CreateKeyEventInfoObj(EcmaVM* vm, KeyEventInfo& info)
982 {
983     const char* keys[] = { "type", "keyCode", "keyText", "keySource", "deviceId", "metaKey", "unicode",
984         "timestamp", "stopPropagation", "getModifierKeyState", "intentionCode", "isNumLockOn", "isCapsLockOn",
985         "isScrollLockOn" };
986     Local<JSValueRef> values[] = { panda::NumberRef::New(vm, static_cast<int32_t>(info.GetKeyType())),
987         panda::NumberRef::New(vm, static_cast<int32_t>(info.GetKeyCode())),
988         panda::StringRef::NewFromUtf8(vm, info.GetKeyText().c_str()),
989         panda::NumberRef::New(vm, static_cast<int32_t>(info.GetKeySource())),
990         panda::NumberRef::New(vm, info.GetDeviceId()), panda::NumberRef::New(vm, info.GetMetaKey()),
991         panda::NumberRef::New(vm, info.GetUnicode()),
992         panda::NumberRef::New(vm, static_cast<double>(info.GetTimeStamp().time_since_epoch().count())),
993         panda::FunctionRef::New(vm, Framework::JsStopPropagation),
994         panda::FunctionRef::New(vm, NG::ArkTSUtils::JsGetModifierKeyState),
995         panda::NumberRef::New(vm, static_cast<int32_t>(info.GetKeyIntention())),
996         panda::BooleanRef::New(vm, info.GetNumLock()),
997         panda::BooleanRef::New(vm, info.GetCapsLock()),
998         panda::BooleanRef::New(vm, info.GetScrollLock()) };
999     return panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
1000 }
1001 
SetOnKeyEvent(ArkUIRuntimeCallInfo * runtimeCallInfo)1002 ArkUINativeModuleValue FrameNodeBridge::SetOnKeyEvent(ArkUIRuntimeCallInfo* runtimeCallInfo)
1003 {
1004     EcmaVM* vm = runtimeCallInfo->GetVM();
1005     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1006     auto* nativeNode = GetFrameNode(runtimeCallInfo);
1007     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
1008     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
1009     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
1010     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
1011     if (secondeArg->IsUndefined()) {
1012         NG::ViewAbstract::ClearJSFrameNodeOnKeyCallback(frameNode);
1013         return panda::JSValueRef::Undefined(vm);
1014     }
1015     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
1016     auto obj = secondeArg->ToObject(vm);
1017     auto containerId = GetInstanceId(runtimeCallInfo);
1018     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
1019     panda::Local<panda::FunctionRef> func = obj;
1020     auto flag = IsCustomFrameNode(frameNode);
1021     auto onKeyEvent = [vm, func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
1022                           node = AceType::WeakClaim(frameNode), containerId](KeyEventInfo& info) {
1023         panda::LocalScope pandaScope(vm);
1024         panda::TryCatch trycatch(vm);
1025         ContainerScope scope(containerId);
1026         auto function = func.Lock();
1027         CHECK_NULL_VOID(!function.IsEmpty());
1028         CHECK_NULL_VOID(function->IsFunction(vm));
1029         PipelineContext::SetCallBackNode(node);
1030         auto obj = CreateKeyEventInfoObj(vm, info);
1031         obj->SetNativePointerFieldCount(vm, 1);
1032         obj->SetNativePointerField(vm, 0, static_cast<void*>(&info));
1033         panda::Local<panda::JSValueRef> params[] = { obj };
1034         function->Call(vm, function.ToLocal(), params, 1);
1035     };
1036 
1037     NG::ViewAbstract::SetJSFrameNodeOnKeyCallback(frameNode, std::move(onKeyEvent));
1038     return panda::JSValueRef::Undefined(vm);
1039 }
1040 
SetOnFocus(ArkUIRuntimeCallInfo * runtimeCallInfo)1041 ArkUINativeModuleValue FrameNodeBridge::SetOnFocus(ArkUIRuntimeCallInfo* runtimeCallInfo)
1042 {
1043     EcmaVM* vm = runtimeCallInfo->GetVM();
1044     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1045     auto* nativeNode = GetFrameNode(runtimeCallInfo);
1046     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
1047     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
1048     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
1049     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
1050     if (secondeArg->IsUndefined()) {
1051         NG::ViewAbstract::ClearJSFrameNodeOnFocusCallback(frameNode);
1052         return panda::JSValueRef::Undefined(vm);
1053     }
1054     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
1055     auto obj = secondeArg->ToObject(vm);
1056     auto containerId = GetInstanceId(runtimeCallInfo);
1057     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
1058     panda::Local<panda::FunctionRef> func = obj;
1059     auto flag = IsCustomFrameNode(frameNode);
1060     auto onFocus = [vm, func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
1061                        node = AceType::WeakClaim(frameNode), containerId]() {
1062         panda::LocalScope pandaScope(vm);
1063         panda::TryCatch trycatch(vm);
1064         ContainerScope scope(containerId);
1065         auto function = func.Lock();
1066         CHECK_NULL_VOID(!function.IsEmpty());
1067         CHECK_NULL_VOID(function->IsFunction(vm));
1068         PipelineContext::SetCallBackNode(node);
1069         function->Call(vm, function.ToLocal(), nullptr, 0);
1070     };
1071     NG::ViewAbstract::SetJSFrameNodeOnFocusCallback(frameNode, std::move(onFocus));
1072     return panda::JSValueRef::Undefined(vm);
1073 }
1074 
SetOnBlur(ArkUIRuntimeCallInfo * runtimeCallInfo)1075 ArkUINativeModuleValue FrameNodeBridge::SetOnBlur(ArkUIRuntimeCallInfo* runtimeCallInfo)
1076 {
1077     EcmaVM* vm = runtimeCallInfo->GetVM();
1078     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1079     auto* nativeNode = GetFrameNode(runtimeCallInfo);
1080     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
1081     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
1082     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
1083     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
1084     if (secondeArg->IsUndefined()) {
1085         NG::ViewAbstract::ClearJSFrameNodeOnBlurCallback(frameNode);
1086         return panda::JSValueRef::Undefined(vm);
1087     }
1088     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
1089     auto obj = secondeArg->ToObject(vm);
1090     auto containerId = GetInstanceId(runtimeCallInfo);
1091     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
1092     panda::Local<panda::FunctionRef> func = obj;
1093     auto flag = IsCustomFrameNode(frameNode);
1094     auto onBlur = [vm, func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag), node = AceType::WeakClaim(frameNode),
1095                       containerId]() {
1096         panda::LocalScope pandaScope(vm);
1097         panda::TryCatch trycatch(vm);
1098         ContainerScope scope(containerId);
1099         auto function = func.Lock();
1100         CHECK_NULL_VOID(!function.IsEmpty());
1101         CHECK_NULL_VOID(function->IsFunction(vm));
1102         PipelineContext::SetCallBackNode(node);
1103         function->Call(vm, function.ToLocal(), nullptr, 0);
1104     };
1105     NG::ViewAbstract::SetJSFrameNodeOnBlurCallback(frameNode, std::move(onBlur));
1106     return panda::JSValueRef::Undefined(vm);
1107 }
1108 
CreateHoverInfo(EcmaVM * vm,HoverInfo & hoverInfo)1109 Local<panda::ObjectRef> FrameNodeBridge::CreateHoverInfo(EcmaVM* vm, HoverInfo& hoverInfo)
1110 {
1111     const char* keys[] = { "stopPropagation", "getModifierKeyState", "timestamp", "source", "target", "deviceId",
1112         "displayX", "displayY", "windowX", "windowY", "x", "y", "globalDisplayX", "globalDisplayY", };
1113     double density = PipelineBase::GetCurrentDensity();
1114     const Offset& globalOffset = hoverInfo.GetGlobalLocation();
1115     const Offset& localOffset = hoverInfo.GetLocalLocation();
1116     const Offset& screenOffset = hoverInfo.GetScreenLocation();
1117     const Offset& globalDisplayOffset = hoverInfo.GetGlobalDisplayLocation();
1118     Local<JSValueRef> values[] = { panda::FunctionRef::New(vm, Framework::JsStopPropagation),
1119         panda::FunctionRef::New(vm, ArkTSUtils::JsGetModifierKeyState),
1120         panda::NumberRef::New(vm, static_cast<double>(hoverInfo.GetTimeStamp().time_since_epoch().count())),
1121         panda::NumberRef::New(vm, static_cast<int32_t>(hoverInfo.GetSourceDevice())),
1122         CreateEventTargetObject(vm, hoverInfo),
1123         panda::NumberRef::New(vm, static_cast<int32_t>(hoverInfo.GetDeviceId())),
1124         panda::NumberRef::New(vm, density != 0 ? screenOffset.GetX() / density : 0),
1125         panda::NumberRef::New(vm, density != 0 ? screenOffset.GetY() / density : 0),
1126         panda::NumberRef::New(vm, density != 0 ? globalOffset.GetX() / density : 0),
1127         panda::NumberRef::New(vm, density != 0 ? globalOffset.GetY() / density : 0),
1128         panda::NumberRef::New(vm, density != 0 ? localOffset.GetX() / density : 0),
1129         panda::NumberRef::New(vm, density != 0 ? localOffset.GetY() / density : 0),
1130         panda::NumberRef::New(vm, density != 0 ? globalDisplayOffset.GetX() / density : 0),
1131         panda::NumberRef::New(vm, density != 0 ? globalDisplayOffset.GetY() / density : 0) };
1132     auto eventObj = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
1133     eventObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "rollAngle"),
1134         panda::NumberRef::New(vm, static_cast<int32_t>(hoverInfo.GetRollAngle().value_or(0.0f))));
1135     return eventObj;
1136 }
1137 
SetOnHover(ArkUIRuntimeCallInfo * runtimeCallInfo)1138 ArkUINativeModuleValue FrameNodeBridge::SetOnHover(ArkUIRuntimeCallInfo* runtimeCallInfo)
1139 {
1140     EcmaVM* vm = runtimeCallInfo->GetVM();
1141     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1142     auto* nativeNode = GetFrameNode(runtimeCallInfo);
1143     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
1144     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
1145     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
1146     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
1147     if (secondeArg->IsUndefined()) {
1148         NG::ViewAbstract::ClearJSFrameNodeOnHover(frameNode);
1149         return panda::JSValueRef::Undefined(vm);
1150     }
1151     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
1152     auto obj = secondeArg->ToObject(vm);
1153     auto containerId = GetInstanceId(runtimeCallInfo);
1154     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
1155     panda::Local<panda::FunctionRef> func = obj;
1156     auto flag = IsCustomFrameNode(frameNode);
1157     auto onHover = [vm, func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
1158                        node = AceType::WeakClaim(frameNode), containerId](bool isHover, HoverInfo& hoverInfo) {
1159         panda::LocalScope pandaScope(vm);
1160         panda::TryCatch trycatch(vm);
1161         ContainerScope scope(containerId);
1162         auto function = func.Lock();
1163         CHECK_NULL_VOID(!function.IsEmpty());
1164         CHECK_NULL_VOID(function->IsFunction(vm));
1165         PipelineContext::SetCallBackNode(node);
1166         auto isHoverParam = panda::BooleanRef::New(vm, isHover);
1167         auto obj = CreateHoverInfo(vm, hoverInfo);
1168         obj->SetNativePointerFieldCount(vm, 1);
1169         obj->SetNativePointerField(vm, 0, static_cast<void*>(&hoverInfo));
1170         panda::Local<panda::JSValueRef> params[] = { isHoverParam, obj };
1171         function->Call(vm, function.ToLocal(), params, ArraySize(params));
1172     };
1173     NG::ViewAbstract::SetJSFrameNodeOnHover(frameNode, std::move(onHover));
1174     return panda::JSValueRef::Undefined(vm);
1175 }
1176 
SetOnHoverMove(ArkUIRuntimeCallInfo * runtimeCallInfo)1177 ArkUINativeModuleValue FrameNodeBridge::SetOnHoverMove(ArkUIRuntimeCallInfo* runtimeCallInfo)
1178 {
1179     EcmaVM* vm = runtimeCallInfo->GetVM();
1180     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1181     auto* nativeNode = GetFrameNode(runtimeCallInfo);
1182     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
1183     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
1184     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
1185     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
1186     if (secondeArg->IsUndefined()) {
1187         NG::ViewAbstract::ClearJSFrameNodeOnHoverMove(frameNode);
1188         return panda::JSValueRef::Undefined(vm);
1189     }
1190     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
1191     auto obj = secondeArg->ToObject(vm);
1192     auto containerId = GetInstanceId(runtimeCallInfo);
1193     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
1194     panda::Local<panda::FunctionRef> func = obj;
1195     auto flag = IsCustomFrameNode(frameNode);
1196     auto onHoverMove = [vm, func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
1197                        node = AceType::WeakClaim(frameNode), containerId](HoverInfo& hoverInfo) {
1198         panda::LocalScope pandaScope(vm);
1199         panda::TryCatch trycatch(vm);
1200         ContainerScope scope(containerId);
1201         auto function = func.Lock();
1202         CHECK_NULL_VOID(!function.IsEmpty());
1203         CHECK_NULL_VOID(function->IsFunction(vm));
1204         PipelineContext::SetCallBackNode(node);
1205         auto obj = CreateHoverInfo(vm, hoverInfo);
1206         obj->SetNativePointerFieldCount(vm, 1);
1207         obj->SetNativePointerField(vm, 0, static_cast<void*>(&hoverInfo));
1208         panda::Local<panda::JSValueRef> params[] = { obj };
1209         function->Call(vm, function.ToLocal(), params, ArraySize(params));
1210     };
1211     NG::ViewAbstract::SetJSFrameNodeOnHoverMove(frameNode, std::move(onHoverMove));
1212     return panda::JSValueRef::Undefined(vm);
1213 }
1214 
CreateMouseInfoObj(EcmaVM * vm,MouseInfo & info)1215 Local<panda::ObjectRef> FrameNodeBridge::CreateMouseInfoObj(EcmaVM* vm, MouseInfo& info)
1216 {
1217     const Offset& globalOffset = info.GetGlobalLocation();
1218     const Offset& localOffset = info.GetLocalLocation();
1219     const Offset& screenOffset = info.GetScreenLocation();
1220     const Offset& globalDisplayOffset = info.GetGlobalDisplayLocation();
1221     double density = PipelineBase::GetCurrentDensity();
1222     const char* keys[] = { "button", "action", "displayX", "displayY", "windowX", "windowY", "screenX", "screenY", "x",
1223         "y", "timestamp", "stopPropagation", "getModifierKeyState", "source", "pressure", "deviceId", "rawDeltaX",
1224         "rawDeltaY", "targetDisplayId", "globalDisplayX", "globalDisplayY" };
1225     Local<JSValueRef> values[] = { panda::NumberRef::New(vm, static_cast<int32_t>(info.GetButton())),
1226         panda::NumberRef::New(vm, static_cast<int32_t>(info.GetAction())),
1227         panda::NumberRef::New(vm, screenOffset.GetX() / density),
1228         panda::NumberRef::New(vm, screenOffset.GetY() / density),
1229         panda::NumberRef::New(vm, globalOffset.GetX() / density),
1230         panda::NumberRef::New(vm, globalOffset.GetY() / density),
1231         panda::NumberRef::New(vm, globalOffset.GetX() / density),
1232         panda::NumberRef::New(vm, globalOffset.GetY() / density),
1233         panda::NumberRef::New(vm, localOffset.GetX() / density),
1234         panda::NumberRef::New(vm, localOffset.GetY() / density),
1235         panda::NumberRef::New(vm, static_cast<double>(info.GetTimeStamp().time_since_epoch().count())),
1236         panda::FunctionRef::New(vm, Framework::JsStopPropagation),
1237         panda::FunctionRef::New(vm, ArkTSUtils::JsGetModifierKeyState),
1238         panda::NumberRef::New(vm, static_cast<int32_t>(info.GetSourceDevice())),
1239         panda::NumberRef::New(vm, info.GetForce()), panda::NumberRef::New(vm, info.GetDeviceId()),
1240         panda::NumberRef::New(vm, info.GetRawDeltaX() / density),
1241         panda::NumberRef::New(vm, info.GetRawDeltaY() / density),
1242         panda::NumberRef::New(vm, info.GetTargetDisplayId()),
1243         panda::NumberRef::New(vm, globalDisplayOffset.GetX() / density),
1244         panda::NumberRef::New(vm, globalDisplayOffset.GetY() / density) };
1245     return panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
1246 }
1247 
CreateMouseInfo(EcmaVM * vm,MouseInfo & info)1248 Local<panda::ObjectRef> FrameNodeBridge::CreateMouseInfo(EcmaVM* vm, MouseInfo& info)
1249 {
1250     auto obj = CreateMouseInfoObj(vm, info);
1251     obj->SetNativePointerFieldCount(vm, 1);
1252     obj->Set(vm, panda::StringRef::NewFromUtf8(vm, "tiltX"),
1253         panda::NumberRef::New(vm, static_cast<int32_t>(info.GetTiltX().value_or(0.0f))));
1254     obj->Set(vm, panda::StringRef::NewFromUtf8(vm, "tiltY"),
1255         panda::NumberRef::New(vm, static_cast<int32_t>(info.GetTiltY().value_or(0.0f))));
1256     obj->Set(vm, panda::StringRef::NewFromUtf8(vm, "rollAngle"),
1257         panda::NumberRef::New(vm, static_cast<int32_t>(info.GetRollAngle().value_or(0.0f))));
1258     obj->Set(
1259         vm, panda::StringRef::NewFromUtf8(vm, "axisVertical"), panda::NumberRef::New(vm, static_cast<int32_t>(0.0f)));
1260     obj->Set(
1261         vm, panda::StringRef::NewFromUtf8(vm, "axisHorizontal"), panda::NumberRef::New(vm, static_cast<int32_t>(0.0f)));
1262     obj->Set(vm, panda::StringRef::NewFromUtf8(vm, "sourceTool"),
1263         panda::NumberRef::New(vm, static_cast<int32_t>(static_cast<int32_t>(info.GetSourceTool()))));
1264     obj->Set(vm, panda::StringRef::NewFromUtf8(vm, "target"), CreateEventTargetObject(vm, info));
1265     obj->SetNativePointerField(vm, 0, static_cast<void*>(&info));
1266     auto pressedButtonArr = panda::ArrayRef::New(vm);
1267     uint32_t idx = 0;
1268     for (const auto& button : info.GetPressedButtons()) {
1269         panda::ArrayRef::SetValueAt(
1270             vm, pressedButtonArr, idx++, panda::NumberRef::New(vm, static_cast<int32_t>(button)));
1271     }
1272     obj->Set(vm, panda::StringRef::NewFromUtf8(vm, "pressedButtons"), pressedButtonArr);
1273     return obj;
1274 }
1275 
SetOnMouse(ArkUIRuntimeCallInfo * runtimeCallInfo)1276 ArkUINativeModuleValue FrameNodeBridge::SetOnMouse(ArkUIRuntimeCallInfo* runtimeCallInfo)
1277 {
1278     EcmaVM* vm = runtimeCallInfo->GetVM();
1279     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1280     auto* nativeNode = GetFrameNode(runtimeCallInfo);
1281     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
1282     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
1283     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
1284     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
1285     if (secondeArg->IsUndefined()) {
1286         NG::ViewAbstract::ClearJSFrameNodeOnMouse(frameNode);
1287         return panda::JSValueRef::Undefined(vm);
1288     }
1289     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
1290     auto obj = secondeArg->ToObject(vm);
1291     auto containerId = GetInstanceId(runtimeCallInfo);
1292     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
1293     panda::Local<panda::FunctionRef> func = obj;
1294     auto flag = IsCustomFrameNode(frameNode);
1295     auto onMouse = [vm, func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
1296                        node = AceType::WeakClaim(frameNode), containerId](MouseInfo& info) {
1297         panda::LocalScope pandaScope(vm);
1298         panda::TryCatch trycatch(vm);
1299         ContainerScope scope(containerId);
1300         auto function = func.Lock();
1301         CHECK_NULL_VOID(!function.IsEmpty());
1302         CHECK_NULL_VOID(function->IsFunction(vm));
1303         PipelineContext::SetCallBackNode(node);
1304         auto obj = CreateMouseInfo(vm, info);
1305         panda::Local<panda::JSValueRef> params[1] = { obj };
1306         function->Call(vm, function.ToLocal(), params, 1);
1307     };
1308     NG::ViewAbstract::SetJSFrameNodeOnMouse(frameNode, std::move(onMouse));
1309     return panda::JSValueRef::Undefined(vm);
1310 }
1311 
GetPositionToParent(ArkUIRuntimeCallInfo * runtimeCallInfo)1312 ArkUINativeModuleValue FrameNodeBridge::GetPositionToParent(ArkUIRuntimeCallInfo* runtimeCallInfo)
1313 {
1314     EcmaVM* vm = runtimeCallInfo->GetVM();
1315     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1316     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1317     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
1318     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1319     Local<Framework::ArrayRef> valueArray = Framework::ArrayRef::New(vm, 2);
1320     ArkUI_Float32 parentOffset[2];
1321     GetArkUINodeModifiers()->getFrameNodeModifier()->getPositionToParent(nativeNode, &parentOffset, true);
1322     CHECK_NULL_RETURN(parentOffset, panda::JSValueRef::Undefined(vm));
1323     Framework::ArrayRef::SetValueAt(vm, valueArray, 0, panda::NumberRef::New(vm, parentOffset[0]));
1324     Framework::ArrayRef::SetValueAt(vm, valueArray, 1, panda::NumberRef::New(vm, parentOffset[1]));
1325     return valueArray;
1326 }
1327 
GetPositionToWindow(ArkUIRuntimeCallInfo * runtimeCallInfo)1328 ArkUINativeModuleValue FrameNodeBridge::GetPositionToWindow(ArkUIRuntimeCallInfo* runtimeCallInfo)
1329 {
1330     EcmaVM* vm = runtimeCallInfo->GetVM();
1331     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1332     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1333     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
1334     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1335     Local<Framework::ArrayRef> valueArray = Framework::ArrayRef::New(vm, 2);
1336     ArkUI_Float32 windowOffset[2];
1337     GetArkUINodeModifiers()->getFrameNodeModifier()->getPositionToWindow(nativeNode, &windowOffset, true);
1338     CHECK_NULL_RETURN(windowOffset, panda::JSValueRef::Undefined(vm));
1339     Framework::ArrayRef::SetValueAt(vm, valueArray, 0, panda::NumberRef::New(vm, windowOffset[0]));
1340     Framework::ArrayRef::SetValueAt(vm, valueArray, 1, panda::NumberRef::New(vm, windowOffset[1]));
1341     return valueArray;
1342 }
1343 
GetPositionToScreen(ArkUIRuntimeCallInfo * runtimeCallInfo)1344 ArkUINativeModuleValue FrameNodeBridge::GetPositionToScreen(ArkUIRuntimeCallInfo* runtimeCallInfo)
1345 {
1346     EcmaVM* vm = runtimeCallInfo->GetVM();
1347     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1348     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1349     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
1350     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1351     Local<Framework::ArrayRef> valueArray = Framework::ArrayRef::New(vm, 2);
1352     ArkUI_Float32 screenPosition[2];
1353     GetArkUINodeModifiers()->getFrameNodeModifier()->getPositionToScreen(nativeNode, &screenPosition, true);
1354     CHECK_NULL_RETURN(screenPosition, panda::JSValueRef::Undefined(vm));
1355     Framework::ArrayRef::SetValueAt(vm, valueArray, 0, panda::NumberRef::New(vm, screenPosition[0]));
1356     Framework::ArrayRef::SetValueAt(vm, valueArray, 1, panda::NumberRef::New(vm, screenPosition[1]));
1357     return valueArray;
1358 }
1359 
GetGlobalPositionOnDisplay(ArkUIRuntimeCallInfo * runtimeCallInfo)1360 ArkUINativeModuleValue FrameNodeBridge::GetGlobalPositionOnDisplay(ArkUIRuntimeCallInfo* runtimeCallInfo)
1361 {
1362     EcmaVM* vm = runtimeCallInfo->GetVM();
1363     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1364     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1365     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
1366     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1367     Local<Framework::ArrayRef> valueArray = Framework::ArrayRef::New(vm, SIZE_OF_ARRAY);
1368     ArkUI_Float32 globalDisplayPosition[SIZE_OF_ARRAY];
1369     GetArkUINodeModifiers()->getFrameNodeModifier()->getGlobalPositionOnDisplay(
1370         nativeNode, &globalDisplayPosition, true);
1371     CHECK_NULL_RETURN(globalDisplayPosition, panda::JSValueRef::Undefined(vm));
1372     Framework::ArrayRef::SetValueAt(vm, valueArray, 0, panda::NumberRef::New(vm, globalDisplayPosition[0]));
1373     Framework::ArrayRef::SetValueAt(vm, valueArray, 1, panda::NumberRef::New(vm, globalDisplayPosition[1]));
1374     return valueArray;
1375 }
1376 
GetPositionToParentWithTransform(ArkUIRuntimeCallInfo * runtimeCallInfo)1377 ArkUINativeModuleValue FrameNodeBridge::GetPositionToParentWithTransform(ArkUIRuntimeCallInfo* runtimeCallInfo)
1378 {
1379     EcmaVM* vm = runtimeCallInfo->GetVM();
1380     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1381     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1382     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
1383     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1384     Local<Framework::ArrayRef> valueArray = Framework::ArrayRef::New(vm, 2);
1385     ArkUI_Float32 parentPosition[2];
1386     GetArkUINodeModifiers()->getFrameNodeModifier()->getPositionToParentWithTransform(
1387         nativeNode, &parentPosition, true);
1388     CHECK_NULL_RETURN(parentPosition, panda::JSValueRef::Undefined(vm));
1389     Framework::ArrayRef::SetValueAt(vm, valueArray, 0, panda::NumberRef::New(vm, parentPosition[0]));
1390     Framework::ArrayRef::SetValueAt(vm, valueArray, 1, panda::NumberRef::New(vm, parentPosition[1]));
1391     return valueArray;
1392 }
1393 
GetPositionToScreenWithTransform(ArkUIRuntimeCallInfo * runtimeCallInfo)1394 ArkUINativeModuleValue FrameNodeBridge::GetPositionToScreenWithTransform(ArkUIRuntimeCallInfo* runtimeCallInfo)
1395 {
1396     EcmaVM* vm = runtimeCallInfo->GetVM();
1397     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1398     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1399     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
1400     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1401     Local<Framework::ArrayRef> valueArray = Framework::ArrayRef::New(vm, 2);
1402     ArkUI_Float32 screenPosition[2];
1403     GetArkUINodeModifiers()->getFrameNodeModifier()->getPositionToScreenWithTransform(
1404         nativeNode, &screenPosition, true);
1405     CHECK_NULL_RETURN(screenPosition, panda::JSValueRef::Undefined(vm));
1406     Framework::ArrayRef::SetValueAt(vm, valueArray, 0, panda::NumberRef::New(vm, screenPosition[0]));
1407     Framework::ArrayRef::SetValueAt(vm, valueArray, 1, panda::NumberRef::New(vm, screenPosition[1]));
1408     return valueArray;
1409 }
1410 
GetPositionToWindowWithTransform(ArkUIRuntimeCallInfo * runtimeCallInfo)1411 ArkUINativeModuleValue FrameNodeBridge::GetPositionToWindowWithTransform(ArkUIRuntimeCallInfo* runtimeCallInfo)
1412 {
1413     EcmaVM* vm = runtimeCallInfo->GetVM();
1414     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1415     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1416     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
1417     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1418     Local<Framework::ArrayRef> valueArray = Framework::ArrayRef::New(vm, 2);
1419     ArkUI_Float32 windowPosition[2];
1420     GetArkUINodeModifiers()->getFrameNodeModifier()->getPositionToWindowWithTransform(
1421         nativeNode, &windowPosition, true);
1422     CHECK_NULL_RETURN(windowPosition, panda::JSValueRef::Undefined(vm));
1423     Framework::ArrayRef::SetValueAt(vm, valueArray, 0, panda::NumberRef::New(vm, windowPosition[0]));
1424     Framework::ArrayRef::SetValueAt(vm, valueArray, 1, panda::NumberRef::New(vm, windowPosition[1]));
1425     return valueArray;
1426 }
1427 
GetMeasuredSize(ArkUIRuntimeCallInfo * runtimeCallInfo)1428 ArkUINativeModuleValue FrameNodeBridge::GetMeasuredSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
1429 {
1430     EcmaVM* vm = runtimeCallInfo->GetVM();
1431     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1432     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1433     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
1434     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1435     Local<Framework::ArrayRef> valueArray = Framework::ArrayRef::New(vm, 2);
1436     auto size = GetArkUINodeModifiers()->getFrameNodeModifier()->getMeasuredSize(nativeNode);
1437     CHECK_NULL_RETURN(size, panda::JSValueRef::Undefined(vm));
1438     Framework::ArrayRef::SetValueAt(vm, valueArray, 0, panda::NumberRef::New(vm, size[0]));
1439     Framework::ArrayRef::SetValueAt(vm, valueArray, 1, panda::NumberRef::New(vm, size[1]));
1440     return valueArray;
1441 }
SetOnAttach(ArkUIRuntimeCallInfo * runtimeCallInfo)1442 ArkUINativeModuleValue FrameNodeBridge::SetOnAttach(ArkUIRuntimeCallInfo* runtimeCallInfo)
1443 {
1444     EcmaVM* vm = runtimeCallInfo->GetVM();
1445     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1446     auto* nativeNode = GetFrameNode(runtimeCallInfo);
1447     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
1448     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
1449     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
1450     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
1451     if (secondeArg->IsUndefined()) {
1452         NG::ViewAbstract::DisableOnAttach(frameNode);
1453         return panda::JSValueRef::Undefined(vm);
1454     }
1455     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
1456     auto obj = secondeArg->ToObject(vm);
1457     auto containerId = GetInstanceId(runtimeCallInfo);
1458     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
1459     panda::Local<panda::FunctionRef> func = obj;
1460     auto onAttach = [vm, func = JsWeak(panda::CopyableGlobal(vm, func)), node = AceType::WeakClaim(frameNode),
1461                         containerId]() {
1462         panda::LocalScope pandaScope(vm);
1463         panda::TryCatch trycatch(vm);
1464         ContainerScope scope(containerId);
1465         auto function = func.Lock();
1466         CHECK_NULL_VOID(!function.IsEmpty());
1467         CHECK_NULL_VOID(function->IsFunction(vm));
1468         PipelineContext::SetCallBackNode(node);
1469         function->Call(vm, function.ToLocal(), nullptr, 0);
1470     };
1471     NG::ViewAbstract::SetOnAttach(frameNode, std::move(onAttach));
1472     return panda::JSValueRef::Undefined(vm);
1473 }
1474 
SetOnDetach(ArkUIRuntimeCallInfo * runtimeCallInfo)1475 ArkUINativeModuleValue FrameNodeBridge::SetOnDetach(ArkUIRuntimeCallInfo* runtimeCallInfo)
1476 {
1477     EcmaVM* vm = runtimeCallInfo->GetVM();
1478     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1479     auto* nativeNode = GetFrameNode(runtimeCallInfo);
1480     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
1481     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
1482     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
1483     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
1484     if (secondeArg->IsUndefined()) {
1485         NG::ViewAbstract::DisableOnDetach(frameNode);
1486         return panda::JSValueRef::Undefined(vm);
1487     }
1488     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
1489     auto obj = secondeArg->ToObject(vm);
1490     auto containerId = GetInstanceId(runtimeCallInfo);
1491     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
1492     panda::Local<panda::FunctionRef> func = obj;
1493     auto onDetach = [vm, func = JsWeak(panda::CopyableGlobal(vm, func)), node = AceType::WeakClaim(frameNode),
1494                         containerId]() {
1495         panda::LocalScope pandaScope(vm);
1496         panda::TryCatch trycatch(vm);
1497         ContainerScope scope(containerId);
1498         auto function = func.Lock();
1499         CHECK_NULL_VOID(!function.IsEmpty());
1500         CHECK_NULL_VOID(function->IsFunction(vm));
1501         PipelineContext::SetCallBackNode(node);
1502         function->Call(vm, function.ToLocal(), nullptr, 0);
1503     };
1504     NG::ViewAbstract::SetOnDetach(frameNode, std::move(onDetach));
1505     return panda::JSValueRef::Undefined(vm);
1506 }
1507 
GetLayoutPosition(ArkUIRuntimeCallInfo * runtimeCallInfo)1508 ArkUINativeModuleValue FrameNodeBridge::GetLayoutPosition(ArkUIRuntimeCallInfo* runtimeCallInfo)
1509 {
1510     EcmaVM* vm = runtimeCallInfo->GetVM();
1511     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1512     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1513     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
1514     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1515     Local<Framework::ArrayRef> valueArray = Framework::ArrayRef::New(vm, 2);
1516     auto position = GetArkUINodeModifiers()->getFrameNodeModifier()->getLayoutPosition(nativeNode);
1517     CHECK_NULL_RETURN(position, panda::JSValueRef::Undefined(vm));
1518     Framework::ArrayRef::SetValueAt(vm, valueArray, 0, panda::NumberRef::New(vm, position[0]));
1519     Framework::ArrayRef::SetValueAt(vm, valueArray, 1, panda::NumberRef::New(vm, position[1]));
1520     return valueArray;
1521 }
GetConfigBorderWidth(ArkUIRuntimeCallInfo * runtimeCallInfo)1522 ArkUINativeModuleValue FrameNodeBridge::GetConfigBorderWidth(ArkUIRuntimeCallInfo* runtimeCallInfo)
1523 {
1524     EcmaVM* vm = runtimeCallInfo->GetVM();
1525     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1526     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1527     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
1528     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1529     Local<Framework::ArrayRef> valueArray = Framework::ArrayRef::New(vm, 8);
1530     ArkUI_Float32 borderWidthValue[4];
1531     ArkUI_Int32 borderWidthUnit[4];
1532     GetArkUINodeModifiers()->getCommonModifier()->getBorderWidthDimension(
1533         nativeNode, &borderWidthValue, &borderWidthUnit);
1534     for (int i = 0; i < 4; i++) {
1535         Framework::ArrayRef::SetValueAt(vm, valueArray, i * 2, panda::NumberRef::New(vm, borderWidthValue[i]));
1536         Framework::ArrayRef::SetValueAt(vm, valueArray, i * 2 + 1, panda::NumberRef::New(vm, borderWidthUnit[i]));
1537     }
1538     return valueArray;
1539 }
GetConfigPadding(ArkUIRuntimeCallInfo * runtimeCallInfo)1540 ArkUINativeModuleValue FrameNodeBridge::GetConfigPadding(ArkUIRuntimeCallInfo* runtimeCallInfo)
1541 {
1542     EcmaVM* vm = runtimeCallInfo->GetVM();
1543     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1544     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1545     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
1546     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1547     Local<Framework::ArrayRef> valueArray = Framework::ArrayRef::New(vm, 8);
1548     ArkUI_Float32 paddingValue[4];
1549     ArkUI_Int32 paddingUnit[4];
1550     GetArkUINodeModifiers()->getCommonModifier()->getPaddingDimension(nativeNode, &paddingValue, &paddingUnit);
1551     for (int i = 0; i < 4; i++) {
1552         Framework::ArrayRef::SetValueAt(vm, valueArray, i * 2, panda::NumberRef::New(vm, paddingValue[i]));
1553         Framework::ArrayRef::SetValueAt(vm, valueArray, i * 2 + 1, panda::NumberRef::New(vm, paddingUnit[i]));
1554     }
1555     return valueArray;
1556 }
GetConfigMargin(ArkUIRuntimeCallInfo * runtimeCallInfo)1557 ArkUINativeModuleValue FrameNodeBridge::GetConfigMargin(ArkUIRuntimeCallInfo* runtimeCallInfo)
1558 {
1559     EcmaVM* vm = runtimeCallInfo->GetVM();
1560     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1561     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1562     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
1563     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1564     Local<Framework::ArrayRef> valueArray = Framework::ArrayRef::New(vm, 8);
1565     ArkUI_Float32 marginValue[4];
1566     ArkUI_Int32 marginUnit[4];
1567     GetArkUINodeModifiers()->getCommonModifier()->getMarginDimension(nativeNode, &marginValue, &marginUnit);
1568     for (int i = 0; i < 4; i++) {
1569         Framework::ArrayRef::SetValueAt(vm, valueArray, i * 2, panda::NumberRef::New(vm, marginValue[i]));
1570         Framework::ArrayRef::SetValueAt(vm, valueArray, i * 2 + 1, panda::NumberRef::New(vm, marginUnit[i]));
1571     }
1572     return valueArray;
1573 }
GetConfigSize(ArkUIRuntimeCallInfo * runtimeCallInfo)1574 ArkUINativeModuleValue FrameNodeBridge::GetConfigSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
1575 {
1576     EcmaVM* vm = runtimeCallInfo->GetVM();
1577     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1578     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1579     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
1580     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1581     Local<Framework::ArrayRef> valueArray = Framework::ArrayRef::New(vm, 4);
1582     ArkUI_Float32 sizeValue[2];
1583     ArkUI_Int32 sizeUnit[2];
1584     GetArkUINodeModifiers()->getCommonModifier()->getConfigSize(nativeNode, &sizeValue, &sizeUnit);
1585     for (int i = 0; i < 2; i++) {
1586         Framework::ArrayRef::SetValueAt(vm, valueArray, i * 2, panda::NumberRef::New(vm, sizeValue[i]));
1587         Framework::ArrayRef::SetValueAt(vm, valueArray, i * 2 + 1, panda::NumberRef::New(vm, sizeUnit[i]));
1588     }
1589     return valueArray;
1590 }
GetId(ArkUIRuntimeCallInfo * runtimeCallInfo)1591 ArkUINativeModuleValue FrameNodeBridge::GetId(ArkUIRuntimeCallInfo* runtimeCallInfo)
1592 {
1593     EcmaVM* vm = runtimeCallInfo->GetVM();
1594     CHECK_NULL_RETURN(vm, panda::StringRef::NewFromUtf8(vm, ""));
1595     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1596     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::StringRef::NewFromUtf8(vm, ""));
1597     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1598     auto inspectorId = GetArkUINodeModifiers()->getFrameNodeModifier()->getInspectorId(nativeNode);
1599     return panda::StringRef::NewFromUtf8(vm, inspectorId);
1600 }
GetNodeType(ArkUIRuntimeCallInfo * runtimeCallInfo)1601 ArkUINativeModuleValue FrameNodeBridge::GetNodeType(ArkUIRuntimeCallInfo* runtimeCallInfo)
1602 {
1603     EcmaVM* vm = runtimeCallInfo->GetVM();
1604     CHECK_NULL_RETURN(vm, panda::StringRef::NewFromUtf8(vm, ""));
1605     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1606     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::StringRef::NewFromUtf8(vm, ""));
1607     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1608     auto nodeType = GetArkUINodeModifiers()->getFrameNodeModifier()->getNodeType(nativeNode);
1609     return panda::StringRef::NewFromUtf8(vm, nodeType);
1610 }
GetOpacity(ArkUIRuntimeCallInfo * runtimeCallInfo)1611 ArkUINativeModuleValue FrameNodeBridge::GetOpacity(ArkUIRuntimeCallInfo* runtimeCallInfo)
1612 {
1613     EcmaVM* vm = runtimeCallInfo->GetVM();
1614     CHECK_NULL_RETURN(vm, panda::NumberRef::New(vm, 0));
1615     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1616     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::NumberRef::New(vm, 0));
1617     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1618     auto opacity = GetArkUINodeModifiers()->getCommonModifier()->getOpacity(nativeNode);
1619     return panda::NumberRef::New(vm, opacity);
1620 }
IsVisible(ArkUIRuntimeCallInfo * runtimeCallInfo)1621 ArkUINativeModuleValue FrameNodeBridge::IsVisible(ArkUIRuntimeCallInfo* runtimeCallInfo)
1622 {
1623     EcmaVM* vm = runtimeCallInfo->GetVM();
1624     CHECK_NULL_RETURN(vm, panda::BooleanRef::New(vm, false));
1625     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1626     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::BooleanRef::New(vm, false));
1627     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1628     auto visible = GetArkUINodeModifiers()->getFrameNodeModifier()->isVisible(nativeNode);
1629     return panda::BooleanRef::New(vm, visible);
1630 }
IsClipToFrame(ArkUIRuntimeCallInfo * runtimeCallInfo)1631 ArkUINativeModuleValue FrameNodeBridge::IsClipToFrame(ArkUIRuntimeCallInfo* runtimeCallInfo)
1632 {
1633     EcmaVM* vm = runtimeCallInfo->GetVM();
1634     CHECK_NULL_RETURN(vm, panda::BooleanRef::New(vm, false));
1635     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1636     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::BooleanRef::New(vm, false));
1637     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1638     auto clip = GetArkUINodeModifiers()->getCommonModifier()->getClip(nativeNode);
1639     return panda::BooleanRef::New(vm, clip != 0);
1640 }
IsAttached(ArkUIRuntimeCallInfo * runtimeCallInfo)1641 ArkUINativeModuleValue FrameNodeBridge::IsAttached(ArkUIRuntimeCallInfo* runtimeCallInfo)
1642 {
1643     EcmaVM* vm = runtimeCallInfo->GetVM();
1644     CHECK_NULL_RETURN(vm, panda::BooleanRef::New(vm, false));
1645     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1646     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::BooleanRef::New(vm, false));
1647     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1648     bool isAttached = GetArkUINodeModifiers()->getFrameNodeModifier()->isVisible(nativeNode);
1649     return panda::BooleanRef::New(vm, isAttached);
1650 }
GetInspectorInfo(ArkUIRuntimeCallInfo * runtimeCallInfo)1651 ArkUINativeModuleValue FrameNodeBridge::GetInspectorInfo(ArkUIRuntimeCallInfo* runtimeCallInfo)
1652 {
1653     EcmaVM* vm = runtimeCallInfo->GetVM();
1654     CHECK_NULL_RETURN(vm, panda::StringRef::NewFromUtf8(vm, "{}"));
1655     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1656     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::StringRef::NewFromUtf8(vm, "{}"));
1657     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1658     auto inspectorInfo = GetArkUINodeModifiers()->getFrameNodeModifier()->getInspectorInfo(nativeNode);
1659     return panda::StringRef::NewFromUtf8(vm, inspectorInfo);
1660 }
GetCustomPropertyCapiByKey(ArkUIRuntimeCallInfo * runtimeCallInfo)1661 ArkUINativeModuleValue FrameNodeBridge::GetCustomPropertyCapiByKey(ArkUIRuntimeCallInfo* runtimeCallInfo)
1662 {
1663     EcmaVM* vm = runtimeCallInfo->GetVM();
1664     auto defaultReturnValue = panda::JSValueRef::Undefined(vm);
1665     CHECK_NULL_RETURN(vm, defaultReturnValue);
1666     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1667     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
1668     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), defaultReturnValue);
1669     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1670     CHECK_NULL_RETURN(!secondArg.IsNull(), defaultReturnValue);
1671     if (!secondArg->IsString(vm)) {
1672         return defaultReturnValue;
1673     }
1674     auto key = secondArg->ToString(vm)->ToString(vm);
1675     uint32_t size = 0;
1676     char* valuePtr = nullptr;
1677     if (GetArkUINodeModifiers()->getFrameNodeModifier()->getCustomPropertyCapiByKey(
1678         nativeNode, key.c_str(), &valuePtr, &size)) {
1679         CHECK_NULL_RETURN(valuePtr, defaultReturnValue);
1680         auto returnValue = panda::StringRef::NewFromUtf8(vm, valuePtr);
1681         GetArkUINodeModifiers()->getFrameNodeModifier()->freeCustomPropertyCharPtr(valuePtr, size);
1682         return returnValue;
1683     }
1684     GetArkUINodeModifiers()->getFrameNodeModifier()->freeCustomPropertyCharPtr(valuePtr, size);
1685     return defaultReturnValue;
1686 }
1687 
ParseGetFunc(ArkUIRuntimeCallInfo * runtimeCallInfo,int32_t nodeId)1688 std::function<std::string(const std::string&)> ParseGetFunc(ArkUIRuntimeCallInfo* runtimeCallInfo, int32_t nodeId)
1689 {
1690     EcmaVM* vm = runtimeCallInfo->GetVM();
1691     return [vm, nodeId](const std::string& key) -> std::string {
1692         std::string resultString = std::string();
1693         CHECK_NULL_RETURN(vm, resultString);
1694         panda::LocalScope scope(vm);
1695         auto global = JSNApi::GetGlobalObject(vm);
1696         if (global.IsNull()) {
1697             return resultString;
1698         }
1699         auto getCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__getCustomPropertyString__"));
1700         if (getCustomProperty->IsUndefined() || !getCustomProperty->IsFunction(vm)) {
1701             return resultString;
1702         }
1703         auto obj = getCustomProperty->ToObject(vm);
1704         panda::Local<panda::FunctionRef> func = obj;
1705         panda::Local<panda::JSValueRef> params2[2] = { panda::NumberRef::New(vm, nodeId), // 2 number of parameters
1706             panda::StringRef::NewFromUtf8(vm, key.c_str()) };
1707         auto function = panda::CopyableGlobal(vm, func);
1708         auto callValue = function->Call(vm, function.ToLocal(), params2, 2);
1709         if (callValue.IsNull() || callValue->IsUndefined() || !callValue->IsString(vm)) {
1710             return resultString;
1711         }
1712         auto value = callValue->ToString(vm)->ToString(vm);
1713         return value;
1714     };
1715 }
1716 
JsGetCustomMapFunc(ArkUIRuntimeCallInfo * runtimeCallInfo,int32_t nodeId)1717 std::function<std::string()> JsGetCustomMapFunc(ArkUIRuntimeCallInfo* runtimeCallInfo, int32_t nodeId)
1718 {
1719     EcmaVM* vm = runtimeCallInfo->GetVM();
1720     return [vm, nodeId]() -> std::string {
1721         std::string resultString = std::string();
1722         CHECK_NULL_RETURN(vm, resultString);
1723         panda::LocalScope scope(vm);
1724         auto global = JSNApi::GetGlobalObject(vm);
1725         if (global.IsNull()) {
1726             return resultString;
1727         }
1728         auto getCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__getCustomPropertyMapString__"));
1729         if (getCustomProperty->IsUndefined() || !getCustomProperty->IsFunction(vm)) {
1730             return resultString;
1731         }
1732         auto obj = getCustomProperty->ToObject(vm);
1733         panda::Local<panda::FunctionRef> func = obj;
1734         panda::Local<panda::JSValueRef> params[1] = { panda::NumberRef::New(vm, nodeId) };
1735         auto function = panda::CopyableGlobal(vm, func);
1736         auto callValue = function->Call(vm, function.ToLocal(), params, 1);
1737         if (callValue.IsNull() || callValue->IsUndefined() || !callValue->IsString(vm)) {
1738             return resultString;
1739         }
1740         auto value = callValue->ToString(vm)->ToString(vm);
1741         return value;
1742     };
1743 }
1744 
ParseFunc(ArkUIRuntimeCallInfo * runtimeCallInfo)1745 std::function<bool()> ParseFunc(ArkUIRuntimeCallInfo* runtimeCallInfo)
1746 {
1747     EcmaVM* vm = runtimeCallInfo->GetVM();
1748     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1749     Local<JSValueRef> keyArg = runtimeCallInfo->GetCallArgRef(1); // 1 key
1750     Local<JSValueRef> valueArg = runtimeCallInfo->GetCallArgRef(2); // 2 value
1751     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), nullptr);
1752     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1753     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
1754     CHECK_NULL_RETURN(frameNode, nullptr);
1755     auto nodeId = frameNode->GetId();
1756     panda::Local<panda::JSValueRef> params3[3] = { panda::NumberRef::New(vm, nodeId), keyArg, // 3 number of parameters
1757         valueArg };
1758     return [vm, frameNode, params3]() -> bool {
1759         CHECK_NULL_RETURN(vm, false);
1760         panda::LocalScope scope(vm);
1761         auto global = JSNApi::GetGlobalObject(vm);
1762         auto setCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__setCustomProperty__"));
1763         if (setCustomProperty->IsUndefined() || !setCustomProperty->IsFunction(vm)) {
1764             return false;
1765         }
1766         auto obj = setCustomProperty->ToObject(vm);
1767         panda::Local<panda::FunctionRef> func = obj;
1768         auto nodeId = frameNode->GetId();
1769         auto function = panda::CopyableGlobal(vm, func);
1770         auto customPropertyExisted = function->Call(vm, function.ToLocal(), params3, 3)->ToBoolean(vm)->Value();
1771         if (customPropertyExisted) {
1772             frameNode->SetCustomPropertyMapFlagByKey(params3[1]->ToString(vm)->ToString(vm));
1773             frameNode->SetRemoveCustomProperties([vm, nodeId]() -> void {
1774                 CHECK_NULL_VOID(vm);
1775                 panda::LocalScope scope(vm);
1776                 auto global = JSNApi::GetGlobalObject(vm);
1777                 auto removeCustomProperty =
1778                     global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__removeCustomProperties__"));
1779                 if (removeCustomProperty->IsUndefined() || !removeCustomProperty->IsFunction(vm)) {
1780                     return;
1781                 }
1782                 auto obj = removeCustomProperty->ToObject(vm);
1783                 panda::Local<panda::FunctionRef> func = obj;
1784                 panda::Local<panda::JSValueRef> params[1] = { panda::NumberRef::New(vm, nodeId) };
1785                 auto function = panda::CopyableGlobal(vm, func);
1786                 function->Call(vm, function.ToLocal(), params, 1);
1787             });
1788         }
1789         return true;
1790     };
1791 }
1792 
SetCustomPropertyModiferByKey(ArkUIRuntimeCallInfo * runtimeCallInfo)1793 ArkUINativeModuleValue FrameNodeBridge::SetCustomPropertyModiferByKey(ArkUIRuntimeCallInfo* runtimeCallInfo)
1794 {
1795     EcmaVM* vm = runtimeCallInfo->GetVM();
1796     CHECK_NULL_RETURN(vm, panda::BooleanRef::New(vm, false));
1797     if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_THIRTEEN)) {
1798         return panda::BooleanRef::New(vm, false);
1799     }
1800     auto defaultReturnValue = panda::BooleanRef::New(vm, true);
1801     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1802     Local<JSValueRef> keyArg = runtimeCallInfo->GetCallArgRef(1); // 1 key
1803     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::BooleanRef::New(vm, false));
1804     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1805     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
1806     CHECK_NULL_RETURN(frameNode, defaultReturnValue);
1807     if (keyArg->IsUndefined() || keyArg->IsNull() || !keyArg->IsString(vm)) {
1808         return defaultReturnValue;
1809     }
1810     auto nodeId = frameNode->GetId();
1811     std::function<bool()> funcCallback = ParseFunc(runtimeCallInfo);
1812     CHECK_NULL_RETURN(funcCallback, panda::BooleanRef::New(vm, false));
1813     std::function<std::string(const std::string&)> getFuncCallback = ParseGetFunc(runtimeCallInfo, nodeId);
1814     std::function<std::string()> getCustomPropertyMapCallback = JsGetCustomMapFunc(runtimeCallInfo, nodeId);
1815     GetArkUINodeModifiers()->getFrameNodeModifier()->setCustomPropertyModiferByKey(
1816         nativeNode, reinterpret_cast<void*>(&funcCallback), reinterpret_cast<void*>(&getFuncCallback),
1817             reinterpret_cast<void*>(&getCustomPropertyMapCallback));
1818     return defaultReturnValue;
1819 }
1820 
SetRemoveCustomProperties(ArkUIRuntimeCallInfo * runtimeCallInfo)1821 ArkUINativeModuleValue FrameNodeBridge::SetRemoveCustomProperties(ArkUIRuntimeCallInfo* runtimeCallInfo)
1822 {
1823     EcmaVM* vm = runtimeCallInfo->GetVM();
1824     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1825     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1826     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
1827     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1828     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
1829     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
1830     auto nodeId = frameNode->GetId();
1831     frameNode->SetRemoveCustomProperties([vm, nodeId]() -> void {
1832         CHECK_NULL_VOID(vm);
1833         panda::LocalScope scope(vm);
1834         auto global = JSNApi::GetGlobalObject(vm);
1835         auto removeCustomProperty =
1836             global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__removeCustomProperties__"));
1837         if (removeCustomProperty->IsUndefined() || !removeCustomProperty->IsFunction(vm)) {
1838             return;
1839         }
1840         auto obj = removeCustomProperty->ToObject(vm);
1841         panda::Local<panda::FunctionRef> func = obj;
1842         panda::Local<panda::JSValueRef> params[1] = { panda::NumberRef::New(vm, nodeId) };
1843         auto function = panda::CopyableGlobal(vm, func);
1844         function->Call(vm, function.ToLocal(), params, 1);
1845     });
1846     return panda::JSValueRef::Undefined(vm);
1847 }
1848 
SetMeasuredSize(ArkUIRuntimeCallInfo * runtimeCallInfo)1849 ArkUINativeModuleValue FrameNodeBridge::SetMeasuredSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
1850 {
1851     EcmaVM* vm = runtimeCallInfo->GetVM();
1852     auto defaultReturnValue = panda::JSValueRef::Undefined(vm);
1853     CHECK_NULL_RETURN(vm, defaultReturnValue);
1854     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1855     CHECK_NULL_RETURN(!firstArg.IsNull(), defaultReturnValue);
1856     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1857     Local<JSValueRef> width = runtimeCallInfo->GetCallArgRef(1);
1858     CHECK_NULL_RETURN(width->IsNumber(), defaultReturnValue);
1859     Local<JSValueRef> height = runtimeCallInfo->GetCallArgRef(2);
1860     CHECK_NULL_RETURN(height->IsNumber(), defaultReturnValue);
1861     GetArkUIFullNodeAPI()->getExtendedAPI()->setMeasureWidth(nativeNode, width->ToNumber(vm)->Value());
1862     GetArkUIFullNodeAPI()->getExtendedAPI()->setMeasureHeight(nativeNode, height->ToNumber(vm)->Value());
1863     return defaultReturnValue;
1864 }
SetLayoutPosition(ArkUIRuntimeCallInfo * runtimeCallInfo)1865 ArkUINativeModuleValue FrameNodeBridge::SetLayoutPosition(ArkUIRuntimeCallInfo* runtimeCallInfo)
1866 {
1867     EcmaVM* vm = runtimeCallInfo->GetVM();
1868     auto defaultReturnValue = panda::JSValueRef::Undefined(vm);
1869     CHECK_NULL_RETURN(vm, defaultReturnValue);
1870     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1871     CHECK_NULL_RETURN(!firstArg.IsNull(), defaultReturnValue);
1872     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1873     Local<JSValueRef> x = runtimeCallInfo->GetCallArgRef(1);
1874     CHECK_NULL_RETURN(x->IsNumber(), defaultReturnValue);
1875     Local<JSValueRef> y = runtimeCallInfo->GetCallArgRef(2);
1876     CHECK_NULL_RETURN(y->IsNumber(), defaultReturnValue);
1877     GetArkUIFullNodeAPI()->getExtendedAPI()->setX(nativeNode, x->ToNumber(vm)->Value());
1878     GetArkUIFullNodeAPI()->getExtendedAPI()->setY(nativeNode, y->ToNumber(vm)->Value());
1879     return defaultReturnValue;
1880 }
GetObjectValueByKey(EcmaVM * vm,Local<JSValueRef> object,const char * key)1881 Local<JSValueRef> FrameNodeBridge::GetObjectValueByKey(EcmaVM* vm, Local<JSValueRef> object, const char* key)
1882 {
1883     CHECK_NULL_RETURN(object->IsObject(vm), panda::JSValueRef::Undefined(vm));
1884     return object->ToObject(vm)->Get(vm, panda::StringRef::NewFromUtf8(vm, key));
1885 }
MeasureNode(ArkUIRuntimeCallInfo * runtimeCallInfo)1886 ArkUINativeModuleValue FrameNodeBridge::MeasureNode(ArkUIRuntimeCallInfo* runtimeCallInfo)
1887 {
1888     EcmaVM* vm = runtimeCallInfo->GetVM();
1889     auto defaultReturnValue = panda::JSValueRef::Undefined(vm);
1890     CHECK_NULL_RETURN(vm, defaultReturnValue);
1891     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1892     CHECK_NULL_RETURN(!firstArg.IsNull(), defaultReturnValue);
1893     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1894     ArkUI_Float32 constraintValues[6];
1895     for (int i = 0; i < 6; i++) {
1896         Local<JSValueRef> constraintValue = runtimeCallInfo->GetCallArgRef(i + 1);
1897         CHECK_NULL_RETURN(constraintValue->IsNumber(), defaultReturnValue);
1898         constraintValues[i] = constraintValue->ToNumber(vm)->Value();
1899     }
1900 
1901     ArkUIVMContext vmContext = nullptr;
1902     GetArkUIFullNodeAPI()->getExtendedAPI()->measureNode(vmContext, nativeNode, constraintValues);
1903     return defaultReturnValue;
1904 }
LayoutNode(ArkUIRuntimeCallInfo * runtimeCallInfo)1905 ArkUINativeModuleValue FrameNodeBridge::LayoutNode(ArkUIRuntimeCallInfo* runtimeCallInfo)
1906 {
1907     EcmaVM* vm = runtimeCallInfo->GetVM();
1908     auto defaultReturnValue = panda::JSValueRef::Undefined(vm);
1909     CHECK_NULL_RETURN(vm, defaultReturnValue);
1910     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1911     CHECK_NULL_RETURN(!firstArg.IsNull(), defaultReturnValue);
1912     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1913     Local<JSValueRef> x = runtimeCallInfo->GetCallArgRef(1);
1914     CHECK_NULL_RETURN(x->IsNumber(), defaultReturnValue);
1915     Local<JSValueRef> y = runtimeCallInfo->GetCallArgRef(2);
1916     CHECK_NULL_RETURN(y->IsNumber(), defaultReturnValue);
1917     ArkUI_Float32 positionValue[2] = { static_cast<ArkUI_Float32>(x->ToNumber(vm)->Value()),
1918         static_cast<ArkUI_Float32>(y->ToNumber(vm)->Value()) };
1919 
1920     ArkUIVMContext vmContext = nullptr;
1921     GetArkUIFullNodeAPI()->getExtendedAPI()->layoutNode(vmContext, nativeNode, &positionValue);
1922     return defaultReturnValue;
1923 }
SetNeedsLayout(ArkUIRuntimeCallInfo * runtimeCallInfo)1924 ArkUINativeModuleValue FrameNodeBridge::SetNeedsLayout(ArkUIRuntimeCallInfo* runtimeCallInfo)
1925 {
1926     EcmaVM* vm = runtimeCallInfo->GetVM();
1927     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1928     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
1929     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
1930     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
1931     GetArkUIFullNodeAPI()->getBasicAPI()->markDirty(nativeNode, ARKUI_DIRTY_FLAG_MEASURE_SELF_AND_PARENT);
1932     return panda::JSValueRef::Undefined(vm);
1933 }
1934 
SetOnSizeChange(ArkUIRuntimeCallInfo * runtimeCallInfo)1935 ArkUINativeModuleValue FrameNodeBridge::SetOnSizeChange(ArkUIRuntimeCallInfo* runtimeCallInfo)
1936 {
1937     EcmaVM* vm = runtimeCallInfo->GetVM();
1938     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
1939     auto* nativeNode = GetFrameNode(runtimeCallInfo);
1940     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
1941     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
1942     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
1943     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
1944     if (secondeArg->IsUndefined()) {
1945         NG::ViewAbstract::ClearJSFrameNodeOnSizeChange(frameNode);
1946         return panda::JSValueRef::Undefined(vm);
1947     }
1948     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
1949     auto obj = secondeArg->ToObject(vm);
1950     auto containerId = GetInstanceId(runtimeCallInfo);
1951     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
1952     panda::Local<panda::FunctionRef> func = obj;
1953     auto flag = IsCustomFrameNode(frameNode);
1954     auto onSizeChange = [vm, func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
1955                             node = AceType::WeakClaim(frameNode),
1956                             containerId](const NG::RectF& oldRect, const NG::RectF& rect) {
1957         panda::LocalScope pandaScope(vm);
1958         panda::TryCatch trycatch(vm);
1959         ContainerScope scope(containerId);
1960         auto function = func.Lock();
1961         CHECK_NULL_VOID(!function.IsEmpty());
1962         CHECK_NULL_VOID(function->IsFunction(vm));
1963         PipelineContext::SetCallBackNode(node);
1964         double density = PipelineBase::GetCurrentDensity();
1965         const char* keys[] = { "width", "height" };
1966         Local<JSValueRef> oldValues[] = { panda::NumberRef::New(vm, oldRect.Width() / density),
1967             panda::NumberRef::New(vm, oldRect.Height() / density) };
1968         auto oldSize = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, oldValues);
1969         Local<JSValueRef> newValues[] = { panda::NumberRef::New(vm, rect.Width() / density),
1970             panda::NumberRef::New(vm, rect.Height() / density) };
1971         auto newSize = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, newValues);
1972         panda::Local<panda::JSValueRef> params[2] = { oldSize, newSize };
1973         function->Call(vm, function.ToLocal(), params, 2);
1974     };
1975     NG::ViewAbstract::SetJSFrameNodeOnSizeChange(frameNode, std::move(onSizeChange));
1976     return panda::JSValueRef::Undefined(vm);
1977 }
1978 
SetOnVisibleAreaApproximateChange(ArkUIRuntimeCallInfo * runtimeCallInfo)1979 ArkUINativeModuleValue FrameNodeBridge::SetOnVisibleAreaApproximateChange(ArkUIRuntimeCallInfo* runtimeCallInfo)
1980 {
1981     EcmaVM* vm = runtimeCallInfo->GetVM();
1982     auto* nativeNode = GetFrameNode(runtimeCallInfo);
1983     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
1984     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
1985     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
1986     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
1987     if (secondArg->IsUndefined()) {
1988         NG::ViewAbstract::ClearJSFrameNodeOnVisibleAreaApproximateChange(frameNode);
1989         return panda::JSValueRef::Undefined(vm);
1990     }
1991     CHECK_NULL_RETURN(secondArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
1992     auto obj = secondArg->ToObject(vm);
1993     auto containerId = GetInstanceId(runtimeCallInfo);
1994     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
1995     panda::Local<panda::FunctionRef> func = obj;
1996     auto flag = IsCustomFrameNode(frameNode);
1997     auto onVisibleAreaApproximateChange = [vm, func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
1998                                               node = AceType::WeakClaim(frameNode),
1999                                               containerId](bool visible, double ratio) {
2000         panda::LocalScope pandaScope(vm);
2001         panda::TryCatch trycatch(vm);
2002         ContainerScope scope(containerId);
2003         auto function = func.Lock();
2004         CHECK_NULL_VOID(!function.IsEmpty() && function->IsFunction(vm));
2005 
2006         Local<JSValueRef> visibleValues = panda::BooleanRef::New(vm, visible);
2007         Local<JSValueRef> ratioValues = panda::NumberRef::New(vm, ratio);
2008         panda::Local<panda::JSValueRef> params[2] = { visibleValues, ratioValues };
2009         function->Call(vm, function.ToLocal(), params, 2);
2010     };
2011     Local<JSValueRef> ratiosArg = runtimeCallInfo->GetCallArgRef(INDEX_OF_OPTION_OF_VISIBLE);
2012     if (ratiosArg->IsUndefined() || !ratiosArg->IsArray(vm)) {
2013         return panda::JSValueRef::Undefined(vm);
2014     }
2015     panda::Local<panda::ArrayRef> ratioList = ratiosArg;
2016     uint32_t size = ratioList->Length(vm);
2017     std::vector<double> ratioVec(size);
2018     for (uint32_t i = 0; i < size; i++) {
2019         double radioNumber = 0.0;
2020         auto const radio = panda::ArrayRef::GetValueAt(vm, ratioList, i);
2021         radioNumber = radio->IsNumber() ? radio->ToNumber(vm)->Value() : 0.0;
2022         radioNumber = std::clamp(radioNumber, VISIBLE_RATIO_MIN, VISIBLE_RATIO_MAX);
2023         ratioVec.push_back(radioNumber);
2024     }
2025     Local<JSValueRef> intervalArg = runtimeCallInfo->GetCallArgRef(INDEX_OF_INTERVAL);
2026     if (intervalArg->IsUndefined() || !intervalArg->IsNumber()) {
2027         return panda::JSValueRef::Undefined(vm);
2028     }
2029     int32_t intervalMs = static_cast<int32_t>(intervalArg->ToNumber(vm)->Value());
2030     if (intervalMs < 0) {
2031         intervalMs = DEFAULT_EXPECTED_UPDATE_INTERVAL;
2032     }
2033     NG::ViewAbstract::SetJSFrameNodeOnVisibleAreaApproximateChange(
2034         frameNode, std::move(onVisibleAreaApproximateChange), ratioVec, intervalMs);
2035     return panda::JSValueRef::Undefined(vm);
2036 }
2037 
PropertyUpdate(ArkUIRuntimeCallInfo * runtimeCallInfo)2038 ArkUINativeModuleValue FrameNodeBridge::PropertyUpdate(ArkUIRuntimeCallInfo* runtimeCallInfo)
2039 {
2040     EcmaVM* vm = runtimeCallInfo->GetVM();
2041     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
2042     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
2043     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
2044     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
2045     GetArkUINodeModifiers()->getFrameNodeModifier()->propertyUpdate(nativeNode);
2046     return panda::JSValueRef::Undefined(vm);
2047 }
2048 
RegisterFrameCallback(ArkUIRuntimeCallInfo * runtimeCallInfo)2049 ArkUINativeModuleValue FrameNodeBridge::RegisterFrameCallback(ArkUIRuntimeCallInfo* runtimeCallInfo)
2050 {
2051     EcmaVM* vm = runtimeCallInfo->GetVM();
2052     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
2053     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
2054     CHECK_NULL_RETURN(firstArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
2055     auto obj = firstArg->ToObject(vm);
2056     auto containerId = Container::CurrentIdSafely();
2057     panda::Local<panda::FunctionRef> func = obj;
2058     auto getVsyncFunc = [vm, func = panda::CopyableGlobal(vm, func), containerId]() {
2059         panda::LocalScope pandaScope(vm);
2060         ContainerScope scope(containerId);
2061         auto container = Container::Current();
2062         CHECK_NULL_VOID(container);
2063         auto frontend = container->GetFrontend();
2064         CHECK_NULL_VOID(frontend);
2065         func->Call(vm, func.ToLocal(), nullptr, 0);
2066     };
2067     auto pipelineContext = PipelineContext::GetCurrentContextSafely();
2068     CHECK_NULL_RETURN(pipelineContext, panda::JSValueRef::Undefined(vm));
2069     pipelineContext->SetOnceVsyncListener(std::move(getVsyncFunc));
2070     return panda::JSValueRef::Undefined(vm);
2071 }
2072 
MarkDirty(ArkUIRuntimeCallInfo * runtimeCallInfo)2073 ArkUINativeModuleValue FrameNodeBridge::MarkDirty(ArkUIRuntimeCallInfo* runtimeCallInfo)
2074 {
2075     EcmaVM* vm = runtimeCallInfo->GetVM();
2076     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
2077     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
2078     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
2079     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
2080     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
2081     CHECK_NULL_RETURN(secondeArg->IsNumber(), panda::JSValueRef::Undefined(vm));
2082     ArkUIDirtyFlag dirtyFlag = static_cast<ArkUIDirtyFlag>(secondeArg->ToNumber(vm)->Value());
2083     GetArkUIFullNodeAPI()->getBasicAPI()->markDirty(nativeNode, dirtyFlag);
2084     return panda::JSValueRef::Undefined(vm);
2085 }
2086 
CreateNodeContent(ArkUIRuntimeCallInfo * runtimeCallInfo)2087 ArkUINativeModuleValue FrameNodeBridge::CreateNodeContent(ArkUIRuntimeCallInfo* runtimeCallInfo)
2088 {
2089     EcmaVM* vm = runtimeCallInfo->GetVM();
2090     auto content = Referenced::MakeRefPtr<NodeContent>();
2091     return NativeUtilsBridge::CreateStrongRef(vm, content);
2092 }
2093 
AddFrameNodeToNodeContent(ArkUIRuntimeCallInfo * runtimeCallInfo)2094 ArkUINativeModuleValue FrameNodeBridge::AddFrameNodeToNodeContent(ArkUIRuntimeCallInfo* runtimeCallInfo)
2095 {
2096     EcmaVM* vm = runtimeCallInfo->GetVM();
2097     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
2098     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::BooleanRef::New(vm, true));
2099     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
2100     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
2101     auto nativeContent = reinterpret_cast<ArkUINodeContentHandle>(secondArg->ToNativePointer(vm)->Value());
2102     auto result = GetArkUINodeModifiers()->getNodeContentModifier()->addChild(nativeContent, nativeNode);
2103     GetArkUIFullNodeAPI()->getBasicAPI()->markDirty(nativeNode, ARKUI_DIRTY_FLAG_MEASURE_SELF_AND_PARENT);
2104     if (result != ERROR_CODE_NO_ERROR) {
2105         LOGW("AddFrameNodeToNodeContent failed error:%{public}d", result);
2106     }
2107     return panda::BooleanRef::New(vm, !result);
2108 }
2109 
RemoveFrameNodeFromNodeContent(ArkUIRuntimeCallInfo * runtimeCallInfo)2110 ArkUINativeModuleValue FrameNodeBridge::RemoveFrameNodeFromNodeContent(ArkUIRuntimeCallInfo* runtimeCallInfo)
2111 {
2112     EcmaVM* vm = runtimeCallInfo->GetVM();
2113     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
2114     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::BooleanRef::New(vm, true));
2115     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
2116     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
2117     auto nativeContent = reinterpret_cast<ArkUINodeContentHandle>(secondArg->ToNativePointer(vm)->Value());
2118     GetArkUIFullNodeAPI()->getBasicAPI()->markDirty(nativeNode, ARKUI_DIRTY_FLAG_MEASURE_SELF_AND_PARENT);
2119     auto result = GetArkUINodeModifiers()->getNodeContentModifier()->removeChild(nativeContent, nativeNode);
2120     if (result != ERROR_CODE_NO_ERROR) {
2121         LOGW("RemoveFrameNodeFromNodeContent failed error:%{public}d", result);
2122     }
2123     return panda::BooleanRef::New(vm, !result);
2124 }
2125 
GetFirstUINode(ArkUIRuntimeCallInfo * runtimeCallInfo)2126 ArkUINativeModuleValue FrameNodeBridge::GetFirstUINode(ArkUIRuntimeCallInfo* runtimeCallInfo)
2127 {
2128     EcmaVM* vm = runtimeCallInfo->GetVM();
2129     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
2130     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
2131     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
2132     auto nodePtr = GetArkUINodeModifiers()->getFrameNodeModifier()->getFirstUINode(nativeNode);
2133     CHECK_NULL_RETURN(nodePtr, panda::JSValueRef::Undefined(vm));
2134     return panda::NativePointerRef::New(vm, nodePtr);
2135 }
2136 
GetStackTopNode(ArkUIRuntimeCallInfo * runtimeCallInfo)2137 ArkUINativeModuleValue FrameNodeBridge::GetStackTopNode(ArkUIRuntimeCallInfo* runtimeCallInfo)
2138 {
2139     EcmaVM* vm = runtimeCallInfo->GetVM();
2140     auto* node = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
2141     CHECK_NULL_RETURN(node, panda::JSValueRef::Undefined(vm));
2142     return panda::NativePointerRef::New(vm, node);
2143 }
2144 
TriggerOnReuse(ArkUIRuntimeCallInfo * runtimeCallInfo)2145 ArkUINativeModuleValue FrameNodeBridge::TriggerOnReuse(ArkUIRuntimeCallInfo* runtimeCallInfo)
2146 {
2147     EcmaVM* vm = runtimeCallInfo->GetVM();
2148     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
2149     auto* nativeNode = GetFrameNode(runtimeCallInfo);
2150     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
2151     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
2152     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
2153     frameNode->OnReuse();
2154     return panda::JSValueRef::Undefined(vm);
2155 }
2156 
TriggerOnRecycle(ArkUIRuntimeCallInfo * runtimeCallInfo)2157 ArkUINativeModuleValue FrameNodeBridge::TriggerOnRecycle(ArkUIRuntimeCallInfo* runtimeCallInfo)
2158 {
2159     EcmaVM* vm = runtimeCallInfo->GetVM();
2160     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
2161     auto* nativeNode = GetFrameNode(runtimeCallInfo);
2162     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
2163     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
2164     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
2165     frameNode->OnRecycle();
2166     return panda::JSValueRef::Undefined(vm);
2167 }
2168 
SetCrossLanguageOptions(ArkUIRuntimeCallInfo * runtimeCallInfo)2169 ArkUINativeModuleValue FrameNodeBridge::SetCrossLanguageOptions(ArkUIRuntimeCallInfo* runtimeCallInfo)
2170 {
2171     EcmaVM* vm = runtimeCallInfo->GetVM();
2172     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
2173     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::NumberRef::New(vm, ERROR_CODE_PARAM_INVALID));
2174     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
2175     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
2176     bool attributeSetting = secondArg->ToBoolean(vm)->Value();
2177     int result = GetArkUINodeModifiers()->getFrameNodeModifier()->setCrossLanguageOptions(nativeNode, attributeSetting);
2178     return panda::NumberRef::New(vm, result);
2179 }
2180 
GetCrossLanguageOptions(ArkUIRuntimeCallInfo * runtimeCallInfo)2181 ArkUINativeModuleValue FrameNodeBridge::GetCrossLanguageOptions(ArkUIRuntimeCallInfo* runtimeCallInfo)
2182 {
2183     EcmaVM* vm = runtimeCallInfo->GetVM();
2184     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
2185     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::BooleanRef::New(vm, false));
2186     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
2187     bool result = GetArkUINodeModifiers()->getFrameNodeModifier()->getCrossLanguageOptions(nativeNode);
2188     return panda::BooleanRef::New(vm, result);
2189 }
2190 
CheckIfCanCrossLanguageAttributeSetting(ArkUIRuntimeCallInfo * runtimeCallInfo)2191 ArkUINativeModuleValue FrameNodeBridge::CheckIfCanCrossLanguageAttributeSetting(ArkUIRuntimeCallInfo* runtimeCallInfo)
2192 {
2193     EcmaVM* vm = runtimeCallInfo->GetVM();
2194     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
2195     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::BooleanRef::New(vm, false));
2196     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
2197     bool result = GetArkUINodeModifiers()->getFrameNodeModifier()->checkIfCanCrossLanguageAttributeSetting(nativeNode);
2198     return panda::BooleanRef::New(vm, result);
2199 }
2200 
GetInteractionEventBindingInfo(ArkUIRuntimeCallInfo * runtimeCallInfo)2201 ArkUINativeModuleValue FrameNodeBridge::GetInteractionEventBindingInfo(ArkUIRuntimeCallInfo* runtimeCallInfo)
2202 {
2203     EcmaVM* vm = runtimeCallInfo->GetVM();
2204     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
2205     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
2206     CHECK_NULL_RETURN(!firstArg.IsNull(), panda::JSValueRef::Undefined(vm));
2207     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
2208     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
2209     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
2210     CHECK_NULL_RETURN(!secondArg.IsNull(), panda::JSValueRef::Undefined(vm));
2211     int eventQueryType = secondArg->ToNumber(vm)->Value();
2212     auto result =
2213         GetArkUINodeModifiers()->getFrameNodeModifier()->getInteractionEventBindingInfo(nativeNode, eventQueryType);
2214     const char* keys[] = { "baseEventRegistered", "nodeEventRegistered", "nativeEventRegistered",
2215         "builtInEventRegistered" };
2216     Local<JSValueRef> values[] = { panda::BooleanRef::New(vm, result.baseEventRegistered),
2217         panda::BooleanRef::New(vm, result.nodeEventRegistered),
2218         panda::BooleanRef::New(vm, result.nativeEventRegistered),
2219         panda::BooleanRef::New(vm, result.builtInEventRegistered) };
2220     auto obj = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
2221     return obj;
2222 }
2223 
AddSupportedStates(ArkUIRuntimeCallInfo * runtimeCallInfo)2224 ArkUINativeModuleValue FrameNodeBridge::AddSupportedStates(ArkUIRuntimeCallInfo* runtimeCallInfo)
2225 {
2226     EcmaVM* vm = runtimeCallInfo->GetVM();
2227     auto defaultReturnValue = panda::JSValueRef::Undefined(vm);
2228     CHECK_NULL_RETURN(vm, defaultReturnValue);
2229     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
2230     CHECK_NULL_RETURN(!firstArg.IsNull(), defaultReturnValue);
2231     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
2232     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
2233     CHECK_NULL_RETURN(secondArg->IsNumber(), defaultReturnValue);
2234     auto state = secondArg->ToNumber(vm)->Value();
2235     const int32_t thirdArgIndex = 2;
2236     Local<JSValueRef> thirdArg = runtimeCallInfo->GetCallArgRef(thirdArgIndex);
2237     CHECK_NULL_RETURN(thirdArg->IsFunction(vm), defaultReturnValue);
2238     auto obj = thirdArg->ToObject(vm);
2239     auto containerId = Container::CurrentIdSafely();
2240     panda::Local<panda::FunctionRef> func = obj;
2241     std::function<void(int64_t)> callback = [vm, func = panda::CopyableGlobal(vm, func), containerId](
2242                                                 int64_t currentState) {
2243         panda::LocalScope pandaScope(vm);
2244         ContainerScope scope(containerId);
2245         auto container = Container::Current();
2246         CHECK_NULL_VOID(container);
2247         auto frontend = container->GetFrontend();
2248         CHECK_NULL_VOID(frontend);
2249         Local<JSValueRef> stateValues = panda::NumberRef::New(vm, currentState);
2250         panda::Local<panda::JSValueRef> params[1] = { stateValues };
2251         func->Call(vm, func.ToLocal(), params, 1);
2252     };
2253     int isExcludeInner = GetIsExcludeInner(runtimeCallInfo, 3);
2254     GetArkUINodeModifiers()->getUIStateModifier()->addSupportedUIState(
2255         nativeNode, state, reinterpret_cast<void*>(&callback), isExcludeInner);
2256     return defaultReturnValue;
2257 }
2258 
RemoveSupportedStates(ArkUIRuntimeCallInfo * runtimeCallInfo)2259 ArkUINativeModuleValue FrameNodeBridge::RemoveSupportedStates(ArkUIRuntimeCallInfo* runtimeCallInfo)
2260 {
2261     EcmaVM* vm = runtimeCallInfo->GetVM();
2262     auto defaultReturnValue = panda::JSValueRef::Undefined(vm);
2263     CHECK_NULL_RETURN(vm, defaultReturnValue);
2264     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
2265     CHECK_NULL_RETURN(!firstArg.IsNull(), defaultReturnValue);
2266     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
2267     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
2268     CHECK_NULL_RETURN(secondArg->IsNumber(), defaultReturnValue);
2269     auto state = secondArg->ToNumber(vm)->Value();
2270     GetArkUINodeModifiers()->getUIStateModifier()->removeSupportedUIState(nativeNode, state);
2271     return defaultReturnValue;
2272 }
2273 
CreateAnimation(ArkUIRuntimeCallInfo * runtimeCallInfo)2274 ArkUINativeModuleValue FrameNodeBridge::CreateAnimation(ArkUIRuntimeCallInfo* runtimeCallInfo)
2275 {
2276     EcmaVM* vm = runtimeCallInfo->GetVM();
2277     panda::Local<panda::JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
2278     if (nodeArg.IsNull()) {
2279         TAG_LOGW(AceLogTag::ACE_ANIMATION, "FrameNode::createAnimation, node is null");
2280         return panda::BooleanRef::New(vm, false);
2281     }
2282     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
2283     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
2284     CHECK_NULL_RETURN(frameNode, panda::BooleanRef::New(vm, false));
2285     auto containerId = Container::CurrentIdSafelyWithCheck();
2286     ContainerScope scope(containerId);
2287     panda::Local<panda::JSValueRef> propertyArg = runtimeCallInfo->GetCallArgRef(1);
2288     AnimationPropertyType propertyType = AnimationPropertyType::ROTATION;
2289     if (!ParseAnimationProperty(vm, propertyArg, propertyType)) {
2290         TAG_LOGW(AceLogTag::ACE_ANIMATION, "FrameNode::createAnimation, property is invalid");
2291         return panda::BooleanRef::New(vm, false);
2292     }
2293     panda::Local<panda::JSValueRef> startValueArg = runtimeCallInfo->GetCallArgRef(2);
2294     std::vector<float> startValue;
2295     if (startValueArg->IsArray(vm)) {
2296         if (!ParseFloatArray(vm, panda::Local<panda::ArrayRef>(startValueArg), startValue)) {
2297             TAG_LOGW(AceLogTag::ACE_ANIMATION, "FrameNode::createAnimation, start value parse failed");
2298             return panda::BooleanRef::New(vm, false);
2299         }
2300     }
2301     std::vector<float> endValue;
2302     panda::Local<panda::JSValueRef> endValueArg = runtimeCallInfo->GetCallArgRef(3);
2303     if (!(endValueArg->IsArray(vm) && ParseFloatArray(vm, panda::Local<panda::ArrayRef>(endValueArg), endValue))) {
2304         TAG_LOGW(AceLogTag::ACE_ANIMATION, "FrameNode::createAnimation, end value parse failed");
2305         return panda::BooleanRef::New(vm, false);
2306     }
2307     if (!(CheckAnimationPropertyLength(propertyType, startValue.size(), true) &&
2308             CheckAnimationPropertyLength(propertyType, endValue.size(), false))) {
2309         return panda::BooleanRef::New(vm, false);
2310     }
2311     AdjustPropertyValue(propertyType, startValue, endValue);
2312     panda::Local<panda::JSValueRef> localParamArg = runtimeCallInfo->GetCallArgRef(4);
2313     if (!localParamArg->IsObject(vm)) {
2314         TAG_LOGI(AceLogTag::ACE_ANIMATION, "FrameNode::createAnimation, animate param is not object");
2315         return panda::BooleanRef::New(vm, false);
2316     }
2317     panda::Local<panda::ObjectRef> localParamObj = localParamArg->ToObject(vm);
2318     Framework::JSRef<Framework::JSObject> paramObj { Framework::JSObject(vm, localParamObj) };
2319     // not support form now, the second param is false
2320     AnimationOption option = Framework::JSViewContext::CreateAnimation(paramObj, false);
2321     std::optional<int32_t> finishCount;
2322     option.SetOnFinishEvent(ParseFinishCallback(localParamObj, frameNode, vm, finishCount));
2323     auto result = ViewAbstract::CreatePropertyAnimation(frameNode, propertyType, startValue, endValue, option);
2324     if (result && finishCount.has_value()) {
2325         TAG_LOGI(AceLogTag::ACE_ANIMATION, "FrameNode::createAnimation starts, property:%{public}d, cnt:%{public}d",
2326             static_cast<int32_t>(propertyType), finishCount.value());
2327     }
2328     return panda::BooleanRef::New(vm, result);
2329 }
2330 
CancelAnimations(ArkUIRuntimeCallInfo * runtimeCallInfo)2331 ArkUINativeModuleValue FrameNodeBridge::CancelAnimations(ArkUIRuntimeCallInfo* runtimeCallInfo)
2332 {
2333     EcmaVM* vm = runtimeCallInfo->GetVM();
2334     panda::Local<panda::JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
2335     if (nodeArg.IsNull()) {
2336         TAG_LOGW(AceLogTag::ACE_ANIMATION, "FrameNode::cancelAnimations, node is null");
2337         return panda::BooleanRef::New(vm, false);
2338     }
2339     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
2340     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
2341     CHECK_NULL_RETURN(frameNode, panda::BooleanRef::New(vm, false));
2342     auto containerId = Container::CurrentIdSafelyWithCheck();
2343     ContainerScope scope(containerId);
2344     panda::Local<panda::JSValueRef> propertiesArg = runtimeCallInfo->GetCallArgRef(1);
2345     CHECK_NULL_RETURN(propertiesArg->IsArray(vm), panda::BooleanRef::New(vm, false));
2346     panda::Local<panda::ArrayRef> propertiesArrArg = panda::Local<panda::ArrayRef>(propertiesArg);
2347     std::vector<AnimationPropertyType> properties;
2348     auto length = propertiesArrArg->Length(vm);
2349     for (uint32_t i = 0; i != length; ++i) {
2350         panda::Local<panda::JSValueRef> propertyArg = panda::ArrayRef::GetValueAt(vm, propertiesArrArg, i);
2351         AnimationPropertyType propertyType = AnimationPropertyType::ROTATION;
2352         if (!ParseAnimationProperty(vm, propertyArg, propertyType)) {
2353             TAG_LOGW(AceLogTag::ACE_ANIMATION, "FrameNode::cancelAnimations, property is invalid");
2354             return panda::BooleanRef::New(vm, false);
2355         }
2356         if (std::find(properties.begin(), properties.end(), propertyType) == properties.end()) {
2357             properties.emplace_back(propertyType);
2358         }
2359     }
2360     auto result = ViewAbstract::CancelPropertyAnimations(frameNode, properties);
2361     return panda::BooleanRef::New(vm, result);
2362 }
2363 
GetNodePropertyValue(ArkUIRuntimeCallInfo * runtimeCallInfo)2364 ArkUINativeModuleValue FrameNodeBridge::GetNodePropertyValue(ArkUIRuntimeCallInfo* runtimeCallInfo)
2365 {
2366     EcmaVM* vm = runtimeCallInfo->GetVM();
2367     panda::Local<panda::JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
2368     if (nodeArg.IsNull()) {
2369         TAG_LOGW(AceLogTag::ACE_ANIMATION, "FrameNode::getNodePropertyValue, node is null");
2370         return panda::ArrayRef::New(vm, 0);
2371     }
2372     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
2373     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
2374     CHECK_NULL_RETURN(frameNode, panda::ArrayRef::New(vm, 0));
2375     panda::Local<panda::JSValueRef> propertyArg = runtimeCallInfo->GetCallArgRef(1);
2376     AnimationPropertyType propertyType = AnimationPropertyType::ROTATION;
2377     if (!ParseAnimationProperty(vm, propertyArg, propertyType)) {
2378         TAG_LOGW(AceLogTag::ACE_ANIMATION, "FrameNode::getNodePropertyValue, property is invalid");
2379         return panda::ArrayRef::New(vm, 0);
2380     }
2381     auto resultVector = ViewAbstract::GetRenderNodePropertyValue(frameNode, propertyType);
2382     uint32_t resultLength = resultVector.size();
2383     panda::Local<panda::ArrayRef> result = panda::ArrayRef::New(vm, static_cast<uint32_t>(resultVector.size()));
2384     for (uint32_t index = 0; index != resultLength; ++index) {
2385         result->SetValueAt(vm, result, index, panda::NumberRef::New(vm, resultVector[index]));
2386     }
2387     return result;
2388 }
2389 
SetOnReachStart(ArkUIRuntimeCallInfo * runtimeCallInfo)2390 ArkUINativeModuleValue FrameNodeBridge::SetOnReachStart(ArkUIRuntimeCallInfo* runtimeCallInfo)
2391 {
2392     EcmaVM* vm = runtimeCallInfo->GetVM();
2393     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
2394     auto* nativeNode = GetFrameNode(runtimeCallInfo);
2395     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
2396     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
2397     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
2398     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
2399     if (secondeArg->IsUndefined()) {
2400         NG::ViewAbstract::ClearJSFrameNodeOnReachStart(frameNode);
2401         return panda::JSValueRef::Undefined(vm);
2402     }
2403 
2404     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
2405     panda::Local<panda::FunctionRef> func = secondeArg->ToObject(vm);
2406     auto containerId = GetInstanceId(runtimeCallInfo);
2407     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
2408     auto flag = IsCustomFrameNode(frameNode);
2409     std::function<void(void)> callback = [vm, node = AceType::WeakClaim(frameNode),
2410                                              func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
2411                                              containerId]() {
2412         panda::LocalScope pandaScope(vm);
2413         panda::TryCatch trycatch(vm);
2414         ContainerScope scope(containerId);
2415         auto function = func.Lock();
2416         CHECK_NULL_VOID(!function.IsEmpty());
2417         CHECK_NULL_VOID(function->IsFunction(vm));
2418         PipelineContext::SetCallBackNode(node);
2419         function->Call(vm, function.ToLocal(), nullptr, 0);
2420     };
2421     NG::ViewAbstract::SetJSFrameNodeOnReachStart(frameNode, std::move(callback));
2422     return panda::JSValueRef::Undefined(vm);
2423 }
2424 
SetOnReachEnd(ArkUIRuntimeCallInfo * runtimeCallInfo)2425 ArkUINativeModuleValue FrameNodeBridge::SetOnReachEnd(ArkUIRuntimeCallInfo* runtimeCallInfo)
2426 {
2427     EcmaVM* vm = runtimeCallInfo->GetVM();
2428     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
2429     auto* nativeNode = GetFrameNode(runtimeCallInfo);
2430     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
2431     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
2432     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
2433     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
2434     if (secondeArg->IsUndefined()) {
2435         NG::ViewAbstract::ClearJSFrameNodeOnReachEnd(frameNode);
2436         return panda::JSValueRef::Undefined(vm);
2437     }
2438 
2439     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
2440     panda::Local<panda::FunctionRef> func = secondeArg->ToObject(vm);
2441     auto containerId = GetInstanceId(runtimeCallInfo);
2442     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
2443     auto flag = IsCustomFrameNode(frameNode);
2444     std::function<void(void)> callback = [vm, node = AceType::WeakClaim(frameNode),
2445                                              func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
2446                                              containerId]() {
2447         panda::LocalScope pandaScope(vm);
2448         panda::TryCatch trycatch(vm);
2449         ContainerScope scope(containerId);
2450         auto function = func.Lock();
2451         CHECK_NULL_VOID(!function.IsEmpty());
2452         CHECK_NULL_VOID(function->IsFunction(vm));
2453         PipelineContext::SetCallBackNode(node);
2454         function->Call(vm, function.ToLocal(), nullptr, 0);
2455     };
2456     NG::ViewAbstract::SetJSFrameNodeOnReachEnd(frameNode, std::move(callback));
2457     return panda::JSValueRef::Undefined(vm);
2458 }
2459 
SetOnScrollStart(ArkUIRuntimeCallInfo * runtimeCallInfo)2460 ArkUINativeModuleValue FrameNodeBridge::SetOnScrollStart(ArkUIRuntimeCallInfo* runtimeCallInfo)
2461 {
2462     EcmaVM* vm = runtimeCallInfo->GetVM();
2463     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
2464     auto* nativeNode = GetFrameNode(runtimeCallInfo);
2465     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
2466     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
2467     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
2468     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
2469     if (secondeArg->IsUndefined()) {
2470         NG::ViewAbstract::ClearJSFrameNodeOnScrollStart(frameNode);
2471         return panda::JSValueRef::Undefined(vm);
2472     }
2473 
2474     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
2475     panda::Local<panda::FunctionRef> func = secondeArg->ToObject(vm);
2476     auto containerId = GetInstanceId(runtimeCallInfo);
2477     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
2478     auto flag = IsCustomFrameNode(frameNode);
2479     std::function<void()> callback = [vm, node = AceType::WeakClaim(frameNode),
2480                                          func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag), containerId]() {
2481         panda::LocalScope pandaScope(vm);
2482         panda::TryCatch trycatch(vm);
2483         ContainerScope scope(containerId);
2484         auto function = func.Lock();
2485         CHECK_NULL_VOID(!function.IsEmpty());
2486         CHECK_NULL_VOID(function->IsFunction(vm));
2487         PipelineContext::SetCallBackNode(node);
2488         function->Call(vm, function.ToLocal(), nullptr, 0);
2489     };
2490     NG::ViewAbstract::SetJSFrameNodeOnScrollStart(frameNode, std::move(callback));
2491     return panda::JSValueRef::Undefined(vm);
2492 }
2493 
SetOnScrollStop(ArkUIRuntimeCallInfo * runtimeCallInfo)2494 ArkUINativeModuleValue FrameNodeBridge::SetOnScrollStop(ArkUIRuntimeCallInfo* runtimeCallInfo)
2495 {
2496     EcmaVM* vm = runtimeCallInfo->GetVM();
2497     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
2498     auto* nativeNode = GetFrameNode(runtimeCallInfo);
2499     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
2500     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
2501     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
2502     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
2503     if (secondeArg->IsUndefined()) {
2504         NG::ViewAbstract::ClearJSFrameNodeOnScrollStop(frameNode);
2505         return panda::JSValueRef::Undefined(vm);
2506     }
2507 
2508     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
2509     panda::Local<panda::FunctionRef> func = secondeArg->ToObject(vm);
2510     auto containerId = GetInstanceId(runtimeCallInfo);
2511     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
2512     auto flag = IsCustomFrameNode(frameNode);
2513     std::function<void(void)> callback = [vm, node = AceType::WeakClaim(frameNode),
2514                                              func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
2515                                              containerId]() {
2516         panda::LocalScope pandaScope(vm);
2517         panda::TryCatch trycatch(vm);
2518         ContainerScope scope(containerId);
2519         auto function = func.Lock();
2520         CHECK_NULL_VOID(!function.IsEmpty());
2521         CHECK_NULL_VOID(function->IsFunction(vm));
2522         PipelineContext::SetCallBackNode(node);
2523         function->Call(vm, function.ToLocal(), nullptr, 0);
2524     };
2525     NG::ViewAbstract::SetJSFrameNodeOnScrollStop(frameNode, std::move(callback));
2526     return panda::JSValueRef::Undefined(vm);
2527 }
2528 
SetOnScrollFrameBegin(ArkUIRuntimeCallInfo * runtimeCallInfo)2529 ArkUINativeModuleValue FrameNodeBridge::SetOnScrollFrameBegin(ArkUIRuntimeCallInfo* runtimeCallInfo)
2530 {
2531     EcmaVM* vm = runtimeCallInfo->GetVM();
2532     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
2533     auto* nativeNode = GetFrameNode(runtimeCallInfo);
2534     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
2535     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
2536     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
2537     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
2538     if (secondeArg->IsUndefined()) {
2539         NG::ViewAbstract::ClearJSFrameNodeOnScrollFrameBegin(frameNode);
2540         return panda::JSValueRef::Undefined(vm);
2541     }
2542 
2543     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
2544     panda::Local<panda::FunctionRef> func = secondeArg->ToObject(vm);
2545     auto containerId = GetInstanceId(runtimeCallInfo);
2546     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
2547     auto flag = IsCustomFrameNode(frameNode);
2548     std::function<ScrollFrameResult(Dimension, ScrollState)> callback =
2549         [vm, node = AceType::WeakClaim(frameNode), func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
2550             containerId](Dimension offset, ScrollState state) {
2551             panda::LocalScope pandaScope(vm);
2552             panda::TryCatch trycatch(vm);
2553             ContainerScope scope(containerId);
2554             auto function = func.Lock();
2555             OHOS::Ace::ScrollFrameResult scrollRes { .offset = offset };
2556             CHECK_NULL_RETURN(!function.IsEmpty(), scrollRes);
2557             CHECK_NULL_RETURN(function->IsFunction(vm), scrollRes);
2558             PipelineContext::SetCallBackNode(node);
2559 
2560             panda::Local<panda::NumberRef> offsetParam =
2561                 panda::NumberRef::New(vm, static_cast<double>(offset.ConvertToVp()));
2562             panda::Local<panda::NumberRef> stateParam = panda::NumberRef::New(vm, static_cast<double>(state));
2563             // 2: Array length
2564             panda::Local<panda::JSValueRef> params[2] = { offsetParam, stateParam };
2565             auto value = function->Call(vm, function.ToLocal(), params, 2); // 2: Array length
2566             if (value->IsObject(vm)) {
2567                 auto resultObj = value->ToObject(vm);
2568                 panda::Local<panda::JSValueRef> remain =
2569                     resultObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "offsetRemain"));
2570                 if (remain->IsNumber()) {
2571                     scrollRes.offset = Dimension(remain->ToNumber(vm)->Value(), DimensionUnit::VP);
2572                 }
2573             }
2574             return scrollRes;
2575         };
2576     NG::ViewAbstract::SetJSFrameNodeOnScrollFrameBegin(frameNode, std::move(callback));
2577     return panda::JSValueRef::Undefined(vm);
2578 }
2579 
SetOnWillScroll(ArkUIRuntimeCallInfo * runtimeCallInfo)2580 ArkUINativeModuleValue FrameNodeBridge::SetOnWillScroll(ArkUIRuntimeCallInfo* runtimeCallInfo)
2581 {
2582     EcmaVM* vm = runtimeCallInfo->GetVM();
2583     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
2584     auto* nativeNode = GetFrameNode(runtimeCallInfo);
2585     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
2586     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
2587     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
2588     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
2589     if (secondeArg->IsUndefined()) {
2590         NG::ViewAbstract::ClearJSFrameNodeOnWillScroll(frameNode);
2591         return panda::JSValueRef::Undefined(vm);
2592     }
2593 
2594     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
2595     panda::Local<panda::FunctionRef> func = secondeArg->ToObject(vm);
2596     auto containerId = GetInstanceId(runtimeCallInfo);
2597     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
2598     auto flag = IsCustomFrameNode(frameNode);
2599     std::function<ScrollFrameResult(CalcDimension, ScrollState, ScrollSource)> callback =
2600         [vm, node = AceType::WeakClaim(frameNode), func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
2601             containerId](const CalcDimension& scrollOffset, const ScrollState& scrollState, ScrollSource scrollSource) {
2602             panda::LocalScope pandaScope(vm);
2603             panda::TryCatch trycatch(vm);
2604             ContainerScope scope(containerId);
2605             auto function = func.Lock();
2606             ScrollFrameResult scrollRes { .offset = scrollOffset };
2607             CHECK_NULL_RETURN(!function.IsEmpty(), scrollRes);
2608             CHECK_NULL_RETURN(function->IsFunction(vm), scrollRes);
2609             PipelineContext::SetCallBackNode(node);
2610 
2611             panda::Local<panda::NumberRef> offsetParam =
2612                 panda::NumberRef::New(vm, static_cast<double>(scrollOffset.ConvertToVp()));
2613             panda::Local<panda::NumberRef> stateParam = panda::NumberRef::New(vm, static_cast<int32_t>(scrollState));
2614             panda::Local<panda::NumberRef> sourceParam = panda::NumberRef::New(vm, static_cast<int32_t>(scrollSource));
2615             // 3: Array length
2616             panda::Local<panda::JSValueRef> params[3] = { offsetParam, stateParam, sourceParam };
2617             auto result = function->Call(vm, function.ToLocal(), params, 3); // 3: Array length
2618             if (result->IsObject(vm)) {
2619                 auto resultObj = result->ToObject(vm);
2620                 panda::Local<panda::JSValueRef> dxRemainValue =
2621                     resultObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "offsetRemain"));
2622                 if (dxRemainValue->IsNumber()) {
2623                     scrollRes.offset = Dimension(dxRemainValue->ToNumber(vm)->Value(), DimensionUnit::VP);
2624                 }
2625             }
2626             return scrollRes;
2627         };
2628     NG::ViewAbstract::SetJSFrameNodeOnWillScroll(frameNode, std::move(callback));
2629     return panda::JSValueRef::Undefined(vm);
2630 }
2631 
SetOnDidScroll(ArkUIRuntimeCallInfo * runtimeCallInfo)2632 ArkUINativeModuleValue FrameNodeBridge::SetOnDidScroll(ArkUIRuntimeCallInfo* runtimeCallInfo)
2633 {
2634     EcmaVM* vm = runtimeCallInfo->GetVM();
2635     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
2636     auto* nativeNode = GetFrameNode(runtimeCallInfo);
2637     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
2638     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
2639     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
2640     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
2641     if (secondeArg->IsUndefined()) {
2642         NG::ViewAbstract::ClearJSFrameNodeOnDidScroll(frameNode);
2643         return panda::JSValueRef::Undefined(vm);
2644     }
2645 
2646     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
2647     panda::Local<panda::FunctionRef> func = secondeArg->ToObject(vm);
2648     auto containerId = GetInstanceId(runtimeCallInfo);
2649     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
2650     auto flag = IsCustomFrameNode(frameNode);
2651     std::function<void(Dimension, ScrollState)> callback =
2652         [vm, node = AceType::WeakClaim(frameNode), func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
2653             containerId](const CalcDimension& scrollOffset, const ScrollState& scrollState) {
2654             panda::LocalScope pandaScope(vm);
2655             panda::TryCatch trycatch(vm);
2656             ContainerScope scope(containerId);
2657             auto function = func.Lock();
2658             CHECK_NULL_VOID(!function.IsEmpty());
2659             CHECK_NULL_VOID(function->IsFunction(vm));
2660             PipelineContext::SetCallBackNode(node);
2661 
2662             panda::Local<panda::NumberRef> offsetParam =
2663                 panda::NumberRef::New(vm, static_cast<double>(scrollOffset.ConvertToVp()));
2664             panda::Local<panda::NumberRef> stateParam = panda::NumberRef::New(vm, static_cast<int32_t>(scrollState));
2665             // 2: Array length
2666             panda::Local<panda::JSValueRef> params[2] = { offsetParam, stateParam };
2667             function->Call(vm, function.ToLocal(), params, 2); // 2: Array length
2668         };
2669     NG::ViewAbstract::SetJSFrameNodeOnDidScroll(frameNode, std::move(callback));
2670     return panda::JSValueRef::Undefined(vm);
2671 }
2672 
SetOnListScrollIndex(ArkUIRuntimeCallInfo * runtimeCallInfo)2673 ArkUINativeModuleValue FrameNodeBridge::SetOnListScrollIndex(ArkUIRuntimeCallInfo* runtimeCallInfo)
2674 {
2675     EcmaVM* vm = runtimeCallInfo->GetVM();
2676     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
2677     auto* nativeNode = GetFrameNode(runtimeCallInfo);
2678     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
2679     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
2680     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
2681     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
2682     if (secondeArg->IsUndefined()) {
2683         NG::ViewAbstract::ClearJSFrameNodeOnListScrollIndex(frameNode);
2684         return panda::JSValueRef::Undefined(vm);
2685     }
2686 
2687     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
2688     panda::Local<panda::FunctionRef> func = secondeArg->ToObject(vm);
2689     auto containerId = GetInstanceId(runtimeCallInfo);
2690     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
2691     auto flag = IsCustomFrameNode(frameNode);
2692     std::function<void(int32_t, int32_t, int32_t)> callback =
2693         [vm, node = AceType::WeakClaim(frameNode), func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
2694             containerId](const int32_t start, const int32_t end, const int32_t center) {
2695             panda::LocalScope pandaScope(vm);
2696             panda::TryCatch trycatch(vm);
2697             ContainerScope scope(containerId);
2698             auto function = func.Lock();
2699             CHECK_NULL_VOID(!function.IsEmpty());
2700             CHECK_NULL_VOID(function->IsFunction(vm));
2701             PipelineContext::SetCallBackNode(node);
2702 
2703             panda::Local<panda::NumberRef> startParam = panda::NumberRef::New(vm, start);
2704             panda::Local<panda::NumberRef> endParam = panda::NumberRef::New(vm, end);
2705             panda::Local<panda::NumberRef> centerParam = panda::NumberRef::New(vm, center);
2706             // 3: Array length
2707             panda::Local<panda::JSValueRef> params[3] = { startParam, endParam, centerParam };
2708             function->Call(vm, function.ToLocal(), params, 3); // 3: Array length
2709         };
2710     NG::ViewAbstract::SetJSFrameNodeOnListScrollIndex(frameNode, std::move(callback));
2711     return panda::JSValueRef::Undefined(vm);
2712 }
2713 
SetListItemIndex(const EcmaVM * vm,const ListItemIndex indexInfo)2714 Local<panda::ObjectRef> FrameNodeBridge::SetListItemIndex(const EcmaVM* vm, const ListItemIndex indexInfo)
2715 {
2716     const char* keys[] = { "index", "itemIndexInGroup", "itemGroupArea" };
2717     auto indexInGroup = panda::NumberRef::Undefined(vm);
2718     if (indexInfo.indexInGroup != -1) {
2719         indexInGroup = panda::NumberRef::New(vm, static_cast<int32_t>(indexInfo.indexInGroup));
2720     }
2721     auto area = panda::NumberRef::Undefined(vm);
2722     if (indexInfo.area != -1) {
2723         area = panda::NumberRef::New(vm, static_cast<int32_t>(indexInfo.area));
2724     }
2725     Local<JSValueRef> values[] = { panda::NumberRef::New(vm, static_cast<int32_t>(indexInfo.index)), indexInGroup,
2726         area };
2727     return panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
2728 }
2729 
SetOnScrollVisibleContentChange(ArkUIRuntimeCallInfo * runtimeCallInfo)2730 ArkUINativeModuleValue FrameNodeBridge::SetOnScrollVisibleContentChange(ArkUIRuntimeCallInfo* runtimeCallInfo)
2731 {
2732     EcmaVM* vm = runtimeCallInfo->GetVM();
2733     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
2734     auto* nativeNode = GetFrameNode(runtimeCallInfo);
2735     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
2736     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
2737     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
2738     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
2739     if (secondeArg->IsUndefined()) {
2740         NG::ViewAbstract::ClearJSFrameNodeOnScrollVisibleContentChange(frameNode);
2741         return panda::JSValueRef::Undefined(vm);
2742     }
2743 
2744     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
2745     panda::Local<panda::FunctionRef> func = secondeArg->ToObject(vm);
2746     auto containerId = GetInstanceId(runtimeCallInfo);
2747     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
2748     auto flag = IsCustomFrameNode(frameNode);
2749     std::function<void(ListItemIndex, ListItemIndex)> callback =
2750         [vm, node = AceType::WeakClaim(frameNode), func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
2751             containerId](const ListItemIndex start, const ListItemIndex end) {
2752             panda::LocalScope pandaScope(vm);
2753             panda::TryCatch trycatch(vm);
2754             ContainerScope scope(containerId);
2755             auto function = func.Lock();
2756             CHECK_NULL_VOID(!function.IsEmpty());
2757             CHECK_NULL_VOID(function->IsFunction(vm));
2758             PipelineContext::SetCallBackNode(node);
2759 
2760             auto startParam = SetListItemIndex(vm, start);
2761             auto endParam = SetListItemIndex(vm, end);
2762             startParam->SetNativePointerFieldCount(vm, 1);
2763             startParam->SetNativePointerField(vm, 0, static_cast<void*>(&startParam));
2764             endParam->SetNativePointerFieldCount(vm, 1);
2765             endParam->SetNativePointerField(vm, 0, static_cast<void*>(&endParam));
2766             // 2: Array length
2767             panda::Local<panda::JSValueRef> params[2] = { startParam, endParam };
2768             function->Call(vm, function.ToLocal(), params, 2); // 2: Array length
2769         };
2770     NG::ViewAbstract::SetJSFrameNodeOnScrollVisibleContentChange(frameNode, std::move(callback));
2771     return panda::JSValueRef::Undefined(vm);
2772 }
2773 
SetOnScrollWillScroll(ArkUIRuntimeCallInfo * runtimeCallInfo)2774 ArkUINativeModuleValue FrameNodeBridge::SetOnScrollWillScroll(ArkUIRuntimeCallInfo* runtimeCallInfo)
2775 {
2776     EcmaVM* vm = runtimeCallInfo->GetVM();
2777     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
2778     auto* nativeNode = GetFrameNode(runtimeCallInfo);
2779     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
2780     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
2781     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
2782     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
2783     if (secondeArg->IsUndefined()) {
2784         NG::ViewAbstract::ClearJSFrameNodeOnScrollWillScroll(frameNode);
2785         return panda::JSValueRef::Undefined(vm);
2786     }
2787     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
2788     panda::Local<panda::FunctionRef> func = secondeArg->ToObject(vm);
2789     auto containerId = GetInstanceId(runtimeCallInfo);
2790     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
2791     auto flag = IsCustomFrameNode(frameNode);
2792     std::function<TwoDimensionScrollResult(Dimension, Dimension, ScrollState, ScrollSource)> callback =
2793         [vm, node = AceType::WeakClaim(frameNode), func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
2794             containerId](Dimension xOffset, Dimension yOffset, ScrollState state, ScrollSource scrollState) {
2795             panda::LocalScope pandaScope(vm);
2796             panda::TryCatch trycatch(vm);
2797             ContainerScope scope(containerId);
2798             auto function = func.Lock();
2799             NG::TwoDimensionScrollResult scrollRes { .xOffset = xOffset, .yOffset = yOffset };
2800             CHECK_NULL_RETURN(!function.IsEmpty(), scrollRes);
2801             CHECK_NULL_RETURN(function->IsFunction(vm), scrollRes);
2802             PipelineContext::SetCallBackNode(node);
2803 
2804             panda::Local<panda::NumberRef> xOffsetParam =
2805                 panda::NumberRef::New(vm, static_cast<double>(xOffset.ConvertToVp()));
2806             panda::Local<panda::NumberRef> yOffsetParam =
2807                 panda::NumberRef::New(vm, static_cast<double>(yOffset.ConvertToVp()));
2808             panda::Local<panda::NumberRef> stateParam = panda::NumberRef::New(vm, static_cast<double>(state));
2809             panda::Local<panda::NumberRef> sourceParam = panda::NumberRef::New(vm, static_cast<double>(scrollState));
2810             // 4: Array length
2811             panda::Local<panda::JSValueRef> params[4] = { xOffsetParam, yOffsetParam, stateParam, sourceParam };
2812             auto result = function->Call(vm, function.ToLocal(), params, 4); // 4: Array length
2813             if (result->IsObject(vm)) {
2814                 auto resultObj = result->ToObject(vm);
2815                 panda::Local<panda::JSValueRef> x = resultObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "xOffset"));
2816                 panda::Local<panda::JSValueRef> y = resultObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "yOffset"));
2817                 scrollRes.xOffset =
2818                     x->IsNumber() ? Dimension(x->ToNumber(vm)->Value(), DimensionUnit::VP) : scrollRes.xOffset;
2819                 scrollRes.yOffset =
2820                     y->IsNumber() ? Dimension(y->ToNumber(vm)->Value(), DimensionUnit::VP) : scrollRes.yOffset;
2821             }
2822             return scrollRes;
2823         };
2824     NG::ViewAbstract::SetJSFrameNodeOnScrollWillScroll(frameNode, std::move(callback));
2825     return panda::JSValueRef::Undefined(vm);
2826 }
2827 
SetOnScrollDidScroll(ArkUIRuntimeCallInfo * runtimeCallInfo)2828 ArkUINativeModuleValue FrameNodeBridge::SetOnScrollDidScroll(ArkUIRuntimeCallInfo* runtimeCallInfo)
2829 {
2830     EcmaVM* vm = runtimeCallInfo->GetVM();
2831     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
2832     auto* nativeNode = GetFrameNode(runtimeCallInfo);
2833     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
2834     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
2835     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
2836     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
2837     if (secondeArg->IsUndefined()) {
2838         NG::ViewAbstract::ClearJSFrameNodeOnScrollDidScroll(frameNode);
2839         return panda::JSValueRef::Undefined(vm);
2840     }
2841 
2842     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
2843     panda::Local<panda::FunctionRef> func = secondeArg->ToObject(vm);
2844     auto containerId = GetInstanceId(runtimeCallInfo);
2845     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
2846     auto flag = IsCustomFrameNode(frameNode);
2847     std::function<void(Dimension, Dimension, ScrollState)> callback =
2848         [vm, node = AceType::WeakClaim(frameNode), func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
2849             containerId](Dimension xOffset, Dimension yOffset, ScrollState state) {
2850             panda::LocalScope pandaScope(vm);
2851             panda::TryCatch trycatch(vm);
2852             ContainerScope scope(containerId);
2853             auto function = func.Lock();
2854             CHECK_NULL_VOID(!function.IsEmpty());
2855             CHECK_NULL_VOID(function->IsFunction(vm));
2856             PipelineContext::SetCallBackNode(node);
2857 
2858             panda::Local<panda::NumberRef> xOffsetParam =
2859                 panda::NumberRef::New(vm, static_cast<int32_t>(xOffset.ConvertToVp()));
2860             panda::Local<panda::NumberRef> yOffsetParam =
2861                 panda::NumberRef::New(vm, static_cast<int32_t>(yOffset.ConvertToVp()));
2862             panda::Local<panda::NumberRef> stateParam = panda::NumberRef::New(vm, static_cast<int32_t>(state));
2863             // 3: Array length
2864             panda::Local<panda::JSValueRef> params[3] = { xOffsetParam, yOffsetParam, stateParam };
2865             function->Call(vm, function.ToLocal(), params, 3); // 3: Array length
2866         };
2867     NG::ViewAbstract::SetJSFrameNodeOnScrollDidScroll(frameNode, std::move(callback));
2868     return panda::JSValueRef::Undefined(vm);
2869 }
2870 
SetOnGridScrollIndex(ArkUIRuntimeCallInfo * runtimeCallInfo)2871 ArkUINativeModuleValue FrameNodeBridge::SetOnGridScrollIndex(ArkUIRuntimeCallInfo* runtimeCallInfo)
2872 {
2873     EcmaVM* vm = runtimeCallInfo->GetVM();
2874     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
2875     auto* nativeNode = GetFrameNode(runtimeCallInfo);
2876     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
2877     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
2878     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
2879     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
2880     if (secondeArg->IsUndefined()) {
2881         NG::ViewAbstract::ClearJSFrameNodeOnGridScrollIndex(frameNode);
2882         return panda::JSValueRef::Undefined(vm);
2883     }
2884 
2885     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
2886     panda::Local<panda::FunctionRef> func = secondeArg->ToObject(vm);
2887     auto containerId = GetInstanceId(runtimeCallInfo);
2888     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
2889     auto flag = IsCustomFrameNode(frameNode);
2890     std::function<void(int32_t, int32_t)> callback = [vm, node = AceType::WeakClaim(frameNode),
2891                                                          func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
2892                                                          containerId](const int32_t first, const int32_t last) {
2893         panda::LocalScope pandaScope(vm);
2894         panda::TryCatch trycatch(vm);
2895         ContainerScope scope(containerId);
2896         auto function = func.Lock();
2897         CHECK_NULL_VOID(!function.IsEmpty());
2898         CHECK_NULL_VOID(function->IsFunction(vm));
2899         PipelineContext::SetCallBackNode(node);
2900 
2901         panda::Local<panda::NumberRef> firstParam = panda::NumberRef::New(vm, first);
2902         panda::Local<panda::NumberRef> lastParam = panda::NumberRef::New(vm, last);
2903         // 2: Array length
2904         panda::Local<panda::JSValueRef> params[2] = { firstParam, lastParam };
2905         function->Call(vm, function.ToLocal(), params, 2); // 2: Array length
2906     };
2907     NG::ViewAbstract::SetJSFrameNodeOnGridScrollIndex(frameNode, std::move(callback));
2908     return panda::JSValueRef::Undefined(vm);
2909 }
2910 
SetOnWaterFlowScrollIndex(ArkUIRuntimeCallInfo * runtimeCallInfo)2911 ArkUINativeModuleValue FrameNodeBridge::SetOnWaterFlowScrollIndex(ArkUIRuntimeCallInfo* runtimeCallInfo)
2912 {
2913     EcmaVM* vm = runtimeCallInfo->GetVM();
2914     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
2915     auto* nativeNode = GetFrameNode(runtimeCallInfo);
2916     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
2917     auto* frameNode = reinterpret_cast<NG::FrameNode*>(nativeNode);
2918     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
2919     Local<JSValueRef> secondeArg = runtimeCallInfo->GetCallArgRef(1);
2920     if (secondeArg->IsUndefined()) {
2921         NG::ViewAbstract::ClearJSFrameNodeOnWaterFlowScrollIndex(frameNode);
2922         return panda::JSValueRef::Undefined(vm);
2923     }
2924 
2925     CHECK_NULL_RETURN(secondeArg->IsFunction(vm), panda::JSValueRef::Undefined(vm));
2926     panda::Local<panda::FunctionRef> func = secondeArg->ToObject(vm);
2927     auto containerId = GetInstanceId(runtimeCallInfo);
2928     CHECK_NULL_RETURN(containerId != -1, panda::JSValueRef::Undefined(vm));
2929     auto flag = IsCustomFrameNode(frameNode);
2930     std::function<void(int32_t, int32_t)> callback = [vm, node = AceType::WeakClaim(frameNode),
2931                                                          func = JSFuncObjRef(panda::CopyableGlobal(vm, func), flag),
2932                                                          containerId](const int32_t first, const int32_t last) {
2933         panda::LocalScope pandaScope(vm);
2934         panda::TryCatch trycatch(vm);
2935         ContainerScope scope(containerId);
2936         auto function = func.Lock();
2937         CHECK_NULL_VOID(!function.IsEmpty());
2938         CHECK_NULL_VOID(function->IsFunction(vm));
2939         PipelineContext::SetCallBackNode(node);
2940 
2941         panda::Local<panda::NumberRef> firstParam = panda::NumberRef::New(vm, first);
2942         panda::Local<panda::NumberRef> lastParam = panda::NumberRef::New(vm, last);
2943         // 2: Array length
2944         panda::Local<panda::JSValueRef> params[2] = { firstParam, lastParam };
2945         function->Call(vm, function.ToLocal(), params, 2); // 2: Array length
2946     };
2947     NG::ViewAbstract::SetJSFrameNodeOnWaterFlowScrollIndex(frameNode, std::move(callback));
2948     return panda::JSValueRef::Undefined(vm);
2949 }
2950 
UpdateConfiguration(ArkUIRuntimeCallInfo * runtimeCallInfo)2951 ArkUINativeModuleValue FrameNodeBridge::UpdateConfiguration(ArkUIRuntimeCallInfo* runtimeCallInfo)
2952 {
2953     EcmaVM* vm = runtimeCallInfo->GetVM();
2954     auto defaultReturnValue = panda::JSValueRef::Undefined(vm);
2955     CHECK_NULL_RETURN(vm, defaultReturnValue);
2956     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
2957     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), defaultReturnValue);
2958     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
2959     GetArkUINodeModifiers()->getFrameNodeModifier()->updateConfiguration(nativeNode);
2960     return defaultReturnValue;
2961 }
2962 
FireArkUIObjectLifecycleCallback(ArkUIRuntimeCallInfo * runtimeCallInfo)2963 ArkUINativeModuleValue FrameNodeBridge::FireArkUIObjectLifecycleCallback(ArkUIRuntimeCallInfo* runtimeCallInfo)
2964 {
2965     EcmaVM* vm = runtimeCallInfo->GetVM();
2966     auto defaultReturnValue = panda::JSValueRef::Undefined(vm);
2967     CHECK_NULL_RETURN(vm, defaultReturnValue);
2968     Local<JSValueRef> arg = runtimeCallInfo->GetCallArgRef(3);
2969     CHECK_NULL_RETURN(!arg.IsNull() && arg->IsNativePointer(vm), defaultReturnValue);
2970     auto* nativeNode = nodePtr(arg->ToNativePointer(vm)->Value());
2971     CHECK_NULL_RETURN(nativeNode, defaultReturnValue);
2972     auto* frameNode = reinterpret_cast<FrameNode*>(nativeNode);
2973     CHECK_NULL_RETURN(frameNode, defaultReturnValue);
2974     auto context = frameNode->GetContext();
2975     CHECK_NULL_RETURN(context, defaultReturnValue);
2976     void* data = static_cast<void*>(runtimeCallInfo);
2977     context->FireArkUIObjectLifecycleCallback(data);
2978     return defaultReturnValue;
2979 }
2980 } // namespace OHOS::Ace::NG
2981