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 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <string>
17
18 #include "base/memory/referenced.h"
19 #include "core/components_ng/syntax/repeat_model_ng.h"
20 #include "bridge/declarative_frontend/jsview/js_repeat.h"
21 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
22
23
24 namespace OHOS::Ace {
GetInstance()25 RepeatModel* RepeatModel::GetInstance()
26 {
27 static NG::RepeatModelNG instance;
28 return &instance;
29 }
30 } // namespace OHOS::Ace
31
32
33 namespace OHOS::Ace::Framework {
34
StartRender()35 void JSRepeat::StartRender()
36 {
37 RepeatModel::GetInstance()->StartRender();
38 }
39
FinishRender(const JSCallbackInfo & info)40 void JSRepeat::FinishRender(const JSCallbackInfo& info)
41 {
42 std::list<int32_t> removedElmtIds;
43
44 if ((info.Length() != 1) || !info[0]->IsArray()) {
45 TAG_LOGW(AceLogTag::ACE_REPEAT, "Invalid arguments for Repeat.FinishRender");
46 return;
47 }
48 RepeatModel::GetInstance()->FinishRender(removedElmtIds);
49
50 if (!removedElmtIds.size()) {
51 return;
52 }
53
54 // convert list of removed elmtIds: std::list to JSArray<number>
55 JSRef<JSArray> jsArr = JSRef<JSArray>::Cast(info[0]);
56 size_t index = jsArr->Length();
57 for (const auto& rmElmtId : removedElmtIds) {
58 jsArr->SetValueAt(index++, JSRef<JSVal>::Make(ToJSValue(rmElmtId)));
59 }
60 }
61
62 // signature is
63 // fromIndex: number
MoveChild(const JSCallbackInfo & info)64 void JSRepeat::MoveChild(const JSCallbackInfo& info)
65 {
66 if ((info.Length() != 1) || !info[0]->IsNumber()) {
67 TAG_LOGW(AceLogTag::ACE_REPEAT, "Invalid arguments for Repeat.MoveChild");
68 return;
69 }
70
71 const auto fromIndex = info[0]->ToNumber<uint32_t>();
72 RepeatModel::GetInstance()->MoveChild(fromIndex);
73 }
74
75 // signature is
76 // id: string
77 // parentView? : JSView
CreateNewChildStart(const JSCallbackInfo & info)78 void JSRepeat::CreateNewChildStart(const JSCallbackInfo& info)
79 {
80 if ((info.Length() < 1) || !info[0]->IsString()) {
81 TAG_LOGW(AceLogTag::ACE_REPEAT, "Invalid arguments for Repeat.CreateNewChildStart");
82 return;
83 }
84
85 const auto key = info[0]->ToString();
86 RepeatModel::GetInstance()->CreateNewChildStart(key);
87 }
88
89 // signature is
90 // id: string
91 // parentView? : JSView
CreateNewChildFinish(const JSCallbackInfo & info)92 void JSRepeat::CreateNewChildFinish(const JSCallbackInfo& info)
93 {
94 if ((info.Length() < 1) || !info[0]->IsString()) {
95 TAG_LOGW(AceLogTag::ACE_REPEAT, "Invalid arguments for Repeat.CreateNewChildFinish");
96 return;
97 }
98
99 const auto key = info[0]->ToString();
100 RepeatModel::GetInstance()->CreateNewChildFinish(key);
101 }
102
OnMove(const JSCallbackInfo & info)103 void JSRepeat::OnMove(const JSCallbackInfo& info)
104 {
105 if (info[0]->IsFunction()) {
106 auto onMove = [execCtx = info.GetExecutionContext(), func = JSRef<JSFunc>::Cast(info[0])]
107 (int32_t from, int32_t to) {
108 auto params = ConvertToJSValues(from, to);
109 func->Call(JSRef<JSObject>(), params.size(), params.data());
110 };
111 RepeatModel::GetInstance()->OnMove(std::move(onMove));
112 } else {
113 RepeatModel::GetInstance()->OnMove(nullptr);
114 }
115 }
116
JSBind(BindingTarget globalObj)117 void JSRepeat::JSBind(BindingTarget globalObj)
118 {
119 JSClass<JSRepeat>::Declare("RepeatNative");
120 JSClass<JSRepeat>::StaticMethod("startRender", &JSRepeat::StartRender);
121 JSClass<JSRepeat>::StaticMethod("finishRender", &JSRepeat::FinishRender);
122 JSClass<JSRepeat>::StaticMethod("moveChild", &JSRepeat::MoveChild);
123 JSClass<JSRepeat>::StaticMethod("createNewChildStart", &JSRepeat::CreateNewChildStart);
124 JSClass<JSRepeat>::StaticMethod("createNewChildFinish", &JSRepeat::CreateNewChildFinish);
125 JSClass<JSRepeat>::StaticMethod("onMove", &JSRepeat::OnMove);
126 JSClass<JSRepeat>::Bind<>(globalObj);
127 }
128
129 } // namespace OHOS::Ace::Framework
130