• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "core/common/builder_util.h"
16 
17 #include "core/components_ng/base/view_stack_processor.h"
18 #include "core/pipeline_ng/pipeline_context.h"
19 
20 namespace OHOS::Ace::BuilderUtils {
21 
IsBuilderRootNode(const RefPtr<NG::UINode> & node)22 bool IsBuilderRootNode(const RefPtr<NG::UINode>& node)
23 {
24     return node ? node->GetJsBuilderNodeId() != -1 : false;
25 }
26 
GetBuilderNodes(const RefPtr<NG::UINode> & node,std::list<RefPtr<NG::UINode>> & nodes)27 void GetBuilderNodes(const RefPtr<NG::UINode>& node, std::list<RefPtr<NG::UINode>>& nodes)
28 {
29     CHECK_NULL_VOID(node && !node->IsCNode());
30     if (IsBuilderRootNode(node)) {
31         nodes.push_back(node);
32     } else {
33         GetFirstBuilderNode(node, nodes);
34     }
35 }
36 
IsBuilderContainer(const RefPtr<NG::UINode> & node)37 bool IsBuilderContainer(const RefPtr<NG::UINode>& node)
38 {
39     CHECK_NULL_RETURN(node, false);
40     return node->GetTag() == V2::NODE_CONTAINER_ETS_TAG || node->GetTag() == V2::JS_NODE_SLOT_ETS_TAG;
41 }
42 
AddBuilderToContainer(const RefPtr<NG::UINode> & node,const std::list<RefPtr<NG::UINode>> & nodes)43 void AddBuilderToContainer(const RefPtr<NG::UINode>& node, const std::list<RefPtr<NG::UINode>>& nodes)
44 {
45     NG::ScopedViewStackProcessor builder;
46     CHECK_NULL_VOID(node);
47     auto context = node->GetContext();
48     CHECK_NULL_VOID(context);
49     auto frontend = context->GetFrontend();
50     CHECK_NULL_VOID(frontend);
51     std::vector<int32_t> argv = { node->GetId() };
52     for (const auto& child : nodes) {
53         argv.push_back(child->GetJsBuilderNodeId());
54     }
55     frontend->BuilderNodeFunc("__addBuilderNode__", argv);
56 }
57 
AddBuilderToBuilder(const RefPtr<NG::UINode> & node,const std::list<RefPtr<NG::UINode>> & nodes)58 void AddBuilderToBuilder(const RefPtr<NG::UINode>& node, const std::list<RefPtr<NG::UINode>>& nodes)
59 {
60     NG::ScopedViewStackProcessor builder;
61     CHECK_NULL_VOID(node);
62     auto context = node->GetContext();
63     CHECK_NULL_VOID(context);
64     auto frontend = context->GetFrontend();
65     CHECK_NULL_VOID(frontend);
66     std::vector<int32_t> argv = { node->GetJsBuilderNodeId() };
67     for (const auto& child : nodes) {
68         argv.push_back(child->GetJsBuilderNodeId());
69     }
70     frontend->BuilderNodeFunc("__addBuilderNodeToBuilder__", argv);
71 }
72 
RemoveBuilderFromContainer(const RefPtr<NG::UINode> & node,const std::list<RefPtr<NG::UINode>> & nodes)73 void RemoveBuilderFromContainer(const RefPtr<NG::UINode>& node, const std::list<RefPtr<NG::UINode>>& nodes)
74 {
75     NG::ScopedViewStackProcessor builder;
76     CHECK_NULL_VOID(node);
77     auto context = node->GetContext();
78     CHECK_NULL_VOID(context);
79     auto frontend = context->GetFrontend();
80     CHECK_NULL_VOID(frontend);
81     std::vector<int32_t> argv = { node->GetId() };
82     for (const auto& child : nodes) {
83         argv.push_back(child->GetJsBuilderNodeId());
84     }
85     frontend->BuilderNodeFunc("__deleteBuilderNode__", argv);
86 }
87 
ClearChildInBuilderContainer(int32_t nodeId,std::list<RefPtr<NG::UINode>> & nodes)88 void ClearChildInBuilderContainer(int32_t nodeId, std::list<RefPtr<NG::UINode>>& nodes)
89 {
90     NG::ScopedViewStackProcessor builder;
91     CHECK_NULL_VOID(!nodes.empty());
92     auto node = nodes.front();
93     CHECK_NULL_VOID(node);
94     auto context = node->GetContext();
95     CHECK_NULL_VOID(context);
96     auto frontend = context->GetFrontend();
97     CHECK_NULL_VOID(frontend);
98     std::vector<int32_t> argv = { nodeId };
99     for (const auto& child : nodes) {
100         argv.push_back(child->GetJsBuilderNodeId());
101     }
102     frontend->BuilderNodeFunc("__deleteBuilderNode__", argv);
103 }
104 
RemoveBuilderFromBuilder(const RefPtr<NG::UINode> & node,const std::list<RefPtr<NG::UINode>> & nodes)105 void RemoveBuilderFromBuilder(const RefPtr<NG::UINode>& node, const std::list<RefPtr<NG::UINode>>& nodes)
106 {
107     NG::ScopedViewStackProcessor builder;
108     CHECK_NULL_VOID(node);
109     auto context = node->GetContext();
110     CHECK_NULL_VOID(context);
111     auto frontend = context->GetFrontend();
112     CHECK_NULL_VOID(frontend);
113     std::vector<int32_t> argv = { node->GetJsBuilderNodeId() };
114     for (const auto& child : nodes) {
115         argv.push_back(child->GetJsBuilderNodeId());
116     }
117     frontend->BuilderNodeFunc("__deleteBuilderNodeFromBuilder__", argv);
118 }
119 
AddBuilderToParent(const RefPtr<NG::UINode> & node,std::list<RefPtr<NG::UINode>> nodes)120 void AddBuilderToParent(const RefPtr<NG::UINode>& node, std::list<RefPtr<NG::UINode>> nodes)
121 {
122     auto parent = node;
123     CHECK_NULL_VOID(parent && !nodes.empty());
124     while (parent && !parent->IsCNode()) {
125         if (IsBuilderContainer(parent)) {
126             AddBuilderToContainer(parent, nodes);
127             return;
128         }
129         if (IsBuilderRootNode(parent)) {
130             AddBuilderToBuilder(parent, nodes);
131             return;
132         }
133         parent = parent->GetParent();
134     }
135 }
136 
AddBuilderToParent(const RefPtr<NG::UINode> & parentNode,const RefPtr<NG::UINode> & childNode)137 void AddBuilderToParent(const RefPtr<NG::UINode>& parentNode, const RefPtr<NG::UINode>& childNode)
138 {
139     CHECK_NULL_VOID(childNode && parentNode);
140     std::list<RefPtr<NG::UINode>> nodes;
141     BuilderUtils::GetBuilderNodes(childNode, nodes);
142     BuilderUtils::AddBuilderToParent(parentNode, nodes);
143 }
144 
RemoveBuilderFromParent(const RefPtr<NG::UINode> & node,std::list<RefPtr<NG::UINode>> nodes)145 void RemoveBuilderFromParent(const RefPtr<NG::UINode>& node, std::list<RefPtr<NG::UINode>> nodes)
146 {
147     auto parent = node;
148     CHECK_NULL_VOID(parent && !nodes.empty());
149     while (parent && !parent->IsCNode()) {
150         if (IsBuilderContainer(parent)) {
151             RemoveBuilderFromContainer(parent, nodes);
152             return;
153         }
154         if (IsBuilderRootNode(parent)) {
155             RemoveBuilderFromBuilder(parent, nodes);
156             return;
157         }
158         parent = parent->GetParent();
159     }
160 }
161 
RemoveBuilderFromParent(const RefPtr<NG::UINode> & parentNode,const RefPtr<NG::UINode> & childNode)162 void RemoveBuilderFromParent(const RefPtr<NG::UINode>& parentNode, const RefPtr<NG::UINode>& childNode)
163 {
164     CHECK_NULL_VOID(childNode && parentNode);
165     std::list<RefPtr<NG::UINode>> nodes;
166     BuilderUtils::GetBuilderNodes(childNode, nodes);
167     BuilderUtils::RemoveBuilderFromParent(parentNode, nodes);
168 }
169 
GetFirstBuilderNode(const RefPtr<NG::UINode> & node,std::list<RefPtr<NG::UINode>> & nodes)170 void GetFirstBuilderNode(const RefPtr<NG::UINode>& node, std::list<RefPtr<NG::UINode>>& nodes)
171 {
172     CHECK_NULL_VOID(node);
173     std::stack<RefPtr<NG::UINode>> nodeStack;
174     auto children = node->GetChildren();
175     for (auto it = children.rbegin(); it != children.rend(); ++it) {
176         nodeStack.push(*it);
177     }
178     while (!nodeStack.empty()) {
179         auto currentNode = nodeStack.top();
180         nodeStack.pop();
181         if (IsBuilderRootNode(currentNode)) {
182             nodes.push_back(currentNode);
183             continue;
184         }
185         if (IsBuilderContainer(currentNode) || currentNode->IsCNode()) {
186             continue;
187         }
188         auto currentChildren = currentNode->GetChildren();
189         for (auto it = currentChildren.rbegin(); it != currentChildren.rend(); ++it) {
190             nodeStack.push(*it);
191         }
192     }
193 }
194 
195 } // namespace OHOS::Ace::BuilderUtils
196