• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "bridge/declarative_frontend/view_stack_processor.h"
17 
18 #include <string>
19 
20 #include "base/log/ace_trace.h"
21 #include "base/utils/system_properties.h"
22 #include "core/accessibility/accessibility_node.h"
23 #include "core/common/ace_application_info.h"
24 #include "core/components/button/button_component.h"
25 #include "core/components/common/layout/constants.h"
26 #include "core/components/form/form_component.h"
27 #include "core/components/grid_layout/grid_layout_item_component.h"
28 #include "core/components/image/image_component.h"
29 #include "core/components/menu/menu_component.h"
30 #include "core/components/remote_window/remote_window_component.h"
31 #include "core/components/scoring/scoring_component.h"
32 #include "core/components/stepper/stepper_item_component_v2.h"
33 #include "core/components/text/text_component.h"
34 #include "core/components/text_field/text_field_component.h"
35 #include "core/components/text_span/text_span_component.h"
36 #include "core/components/video/video_component_v2.h"
37 #include "core/components/web/web_component.h"
38 #include "core/components/xcomponent/xcomponent_component.h"
39 #include "core/components_v2/list/list_item_component.h"
40 #include "core/components_v2/water_flow/water_flow_item_component.h"
41 #include "core/pipeline/base/component.h"
42 #include "core/pipeline/base/multi_composed_component.h"
43 #include "core/pipeline/base/sole_child_component.h"
44 
45 namespace OHOS::Ace::Framework {
46 thread_local std::unique_ptr<ViewStackProcessor> ViewStackProcessor::instance = nullptr;
47 
GetInstance()48 ViewStackProcessor* ViewStackProcessor::GetInstance()
49 {
50     if (!instance) {
51         instance.reset(new ViewStackProcessor);
52     }
53     return instance.get();
54 }
55 
ViewStackProcessor()56 ViewStackProcessor::ViewStackProcessor()
57 {
58     radioGroups_ = std::make_shared<JsPageRadioGroups>();
59     checkboxGroups_ = std::make_shared<JsPageCheckboxGroups>();
60 }
61 
GetRadioGroupComponent()62 std::shared_ptr<JsPageRadioGroups> ViewStackProcessor::GetRadioGroupComponent()
63 {
64     return radioGroups_;
65 }
66 
GetCheckboxGroupComponent()67 std::shared_ptr<JsPageCheckboxGroups> ViewStackProcessor::GetCheckboxGroupComponent()
68 {
69     return checkboxGroups_;
70 }
71 
GetRootComponent(const std::string & id,const std::string & name)72 RefPtr<ComposedComponent> ViewStackProcessor::GetRootComponent(const std::string& id, const std::string& name)
73 {
74     auto& wrappingComponentsMap = componentsStack_.top();
75     if (wrappingComponentsMap.find("root") != wrappingComponentsMap.end()) {
76         return AceType::DynamicCast<ComposedComponent>(wrappingComponentsMap["root"]);
77     }
78 
79     RefPtr<ComposedComponent> rootComponent = AceType::MakeRefPtr<OHOS::Ace::ComposedComponent>(id, name);
80     wrappingComponentsMap.emplace("root", rootComponent);
81     return rootComponent;
82 }
83 
GetCoverageComponent()84 RefPtr<CoverageComponent> ViewStackProcessor::GetCoverageComponent()
85 {
86     auto& wrappingComponentsMap = componentsStack_.top();
87     if (wrappingComponentsMap.find("coverage") != wrappingComponentsMap.end()) {
88         return AceType::DynamicCast<CoverageComponent>(wrappingComponentsMap["coverage"]);
89     }
90 
91     std::list<RefPtr<Component>> children;
92     RefPtr<CoverageComponent> coverageComponent = AceType::MakeRefPtr<OHOS::Ace::CoverageComponent>(children);
93     wrappingComponentsMap.emplace("coverage", coverageComponent);
94     return coverageComponent;
95 }
96 
97 #ifndef WEARABLE_PRODUCT
GetPopupComponent(bool createNewComponent)98 RefPtr<PopupComponentV2> ViewStackProcessor::GetPopupComponent(bool createNewComponent)
99 {
100     auto& wrappingComponentsMap = componentsStack_.top();
101     if (wrappingComponentsMap.find("popup") != wrappingComponentsMap.end()) {
102         return AceType::DynamicCast<PopupComponentV2>(wrappingComponentsMap["popup"]);
103     }
104 
105     if (!createNewComponent) {
106         return nullptr;
107     }
108 
109     RefPtr<PopupComponentV2> popupComponent =
110         AceType::MakeRefPtr<OHOS::Ace::PopupComponentV2>(V2::InspectorComposedComponent::GenerateId(), "popup");
111     wrappingComponentsMap.emplace("popup", popupComponent);
112     return popupComponent;
113 }
114 #endif
115 
GetMenuComponent(bool createNewComponent)116 RefPtr<MenuComponent> ViewStackProcessor::GetMenuComponent(bool createNewComponent)
117 {
118     auto& wrappingComponentsMap = componentsStack_.top();
119     if (wrappingComponentsMap.find("menu") != wrappingComponentsMap.end()) {
120         return AceType::DynamicCast<MenuComponent>(wrappingComponentsMap["menu"]);
121     }
122 
123     if (!createNewComponent) {
124         return nullptr;
125     }
126 
127     RefPtr<MenuComponent> menuComponent =
128         AceType::MakeRefPtr<OHOS::Ace::MenuComponent>(V2::InspectorComposedComponent::GenerateId(), "menu");
129     wrappingComponentsMap.emplace("menu", menuComponent);
130     return menuComponent;
131 }
132 
GetPositionedComponent()133 RefPtr<PositionedComponent> ViewStackProcessor::GetPositionedComponent()
134 {
135     auto& wrappingComponentsMap = componentsStack_.top();
136     if (wrappingComponentsMap.find("position") != wrappingComponentsMap.end()) {
137         return AceType::DynamicCast<PositionedComponent>(wrappingComponentsMap["position"]);
138     }
139 
140     RefPtr<PositionedComponent> positionedComponent = AceType::MakeRefPtr<OHOS::Ace::PositionedComponent>();
141     wrappingComponentsMap.emplace("position", positionedComponent);
142     return positionedComponent;
143 }
144 
GetFlexItemComponent()145 RefPtr<FlexItemComponent> ViewStackProcessor::GetFlexItemComponent()
146 {
147     auto& wrappingComponentsMap = componentsStack_.top();
148     if (wrappingComponentsMap.find("flexItem") != wrappingComponentsMap.end()) {
149         return AceType::DynamicCast<FlexItemComponent>(wrappingComponentsMap["flexItem"]);
150     }
151     // flex values are all changed to 0.0 in Render.
152     RefPtr<FlexItemComponent> flexItem = AceType::MakeRefPtr<OHOS::Ace::FlexItemComponent>(0.0, -1.0, 0.0);
153     wrappingComponentsMap.emplace("flexItem", flexItem);
154     return flexItem;
155 }
156 
GetStepperItemComponent()157 RefPtr<StepperItemComponent> ViewStackProcessor::GetStepperItemComponent()
158 {
159     auto& wrappingComponentsMap = componentsStack_.top();
160     if (wrappingComponentsMap.find("stepperItem") != wrappingComponentsMap.end()) {
161         return AceType::DynamicCast<StepperItemComponent>(wrappingComponentsMap["stepperItem"]);
162     }
163 
164     RefPtr<StepperItemComponent> stepperItem = AceType::MakeRefPtr<StepperItemComponent>(RefPtr<Component>());
165     wrappingComponentsMap.emplace("stepperItem", stepperItem);
166     return stepperItem;
167 }
168 
GetStepperDisplayComponent()169 RefPtr<DisplayComponent> ViewStackProcessor::GetStepperDisplayComponent()
170 {
171     auto& wrappingComponentsMap = componentsStack_.top();
172     if (wrappingComponentsMap.find("stepperDisplay") != wrappingComponentsMap.end()) {
173         return AceType::DynamicCast<DisplayComponent>(wrappingComponentsMap["stepperDisplay"]);
174     }
175 
176     RefPtr<DisplayComponent> stepperDisplay = AceType::MakeRefPtr<DisplayComponent>();
177     wrappingComponentsMap.emplace("stepperDisplay", stepperDisplay);
178     return stepperDisplay;
179 }
180 
GetStepperScrollComponent()181 RefPtr<ScrollComponent> ViewStackProcessor::GetStepperScrollComponent()
182 {
183     auto& wrappingComponentsMap = componentsStack_.top();
184     if (wrappingComponentsMap.find("stepperScroll") != wrappingComponentsMap.end()) {
185         return AceType::DynamicCast<ScrollComponent>(wrappingComponentsMap["stepperScroll"]);
186     }
187 
188     RefPtr<ScrollComponent> stepperScroll = AceType::MakeRefPtr<ScrollComponent>(RefPtr<Component>());
189     wrappingComponentsMap.emplace("stepperScroll", stepperScroll);
190     return stepperScroll;
191 }
192 
GetBoxComponent()193 RefPtr<BoxComponent> ViewStackProcessor::GetBoxComponent()
194 {
195 #if defined(PREVIEW)
196     if (componentsStack_.empty()) {
197         RefPtr<BoxComponent> boxComponent = AceType::MakeRefPtr<OHOS::Ace::BoxComponent>();
198         std::unordered_map<std::string, RefPtr<Component>> wrappingComponentsMap;
199         wrappingComponentsMap.emplace("box", boxComponent);
200         componentsStack_.push(wrappingComponentsMap);
201         return boxComponent;
202     }
203 #endif
204     auto& wrappingComponentsMap = componentsStack_.top();
205     if (wrappingComponentsMap.find("box") != wrappingComponentsMap.end()) {
206         auto boxComponent = AceType::DynamicCast<BoxComponent>(wrappingComponentsMap["box"]);
207         if (boxComponent) {
208             return boxComponent;
209         }
210     }
211 
212     RefPtr<BoxComponent> boxComponent = AceType::MakeRefPtr<OHOS::Ace::BoxComponent>();
213     boxComponent->SetEnableDebugBoundary(true);
214     wrappingComponentsMap.emplace("box", boxComponent);
215     return boxComponent;
216 }
217 
GetMainComponent() const218 RefPtr<Component> ViewStackProcessor::GetMainComponent() const
219 {
220     if (componentsStack_.empty()) {
221         return nullptr;
222     }
223     auto& wrappingComponentsMap = componentsStack_.top();
224     auto main = wrappingComponentsMap.find("main");
225     if (main == wrappingComponentsMap.end()) {
226         return nullptr;
227     }
228     return main->second;
229 }
230 
HasDisplayComponent() const231 bool ViewStackProcessor::HasDisplayComponent() const
232 {
233     auto& wrappingComponentsMap = componentsStack_.top();
234     if (wrappingComponentsMap.find("display") != wrappingComponentsMap.end()) {
235         return true;
236     }
237     return false;
238 }
239 
GetDisplayComponent()240 RefPtr<DisplayComponent> ViewStackProcessor::GetDisplayComponent()
241 {
242     auto& wrappingComponentsMap = componentsStack_.top();
243     if (wrappingComponentsMap.find("display") != wrappingComponentsMap.end()) {
244         auto displayComponent = AceType::DynamicCast<DisplayComponent>(wrappingComponentsMap["display"]);
245         if (displayComponent) {
246             return displayComponent;
247         }
248     }
249 
250     RefPtr<DisplayComponent> displayComponent = AceType::MakeRefPtr<OHOS::Ace::DisplayComponent>();
251     wrappingComponentsMap.emplace("display", displayComponent);
252     return displayComponent;
253 }
254 
GetTransformComponent()255 RefPtr<TransformComponent> ViewStackProcessor::GetTransformComponent()
256 {
257     auto& wrappingComponentsMap = componentsStack_.top();
258     if (wrappingComponentsMap.find("transform") != wrappingComponentsMap.end()) {
259         auto transformComponent = AceType::DynamicCast<TransformComponent>(wrappingComponentsMap["transform"]);
260         if (transformComponent) {
261             return transformComponent;
262         }
263     }
264 
265     RefPtr<TransformComponent> transformComponent = AceType::MakeRefPtr<OHOS::Ace::TransformComponent>();
266     wrappingComponentsMap.emplace("transform", transformComponent);
267     return transformComponent;
268 }
269 
HasTouchListenerComponent() const270 bool ViewStackProcessor::HasTouchListenerComponent() const
271 {
272     auto& wrappingComponentsMap = componentsStack_.top();
273     if (wrappingComponentsMap.find("touch") != wrappingComponentsMap.end()) {
274         return true;
275     }
276     return false;
277 }
278 
GetTouchListenerComponent()279 RefPtr<TouchListenerComponent> ViewStackProcessor::GetTouchListenerComponent()
280 {
281     auto& wrappingComponentsMap = componentsStack_.top();
282     if (wrappingComponentsMap.find("touch") != wrappingComponentsMap.end()) {
283         auto touchListenerComponent = AceType::DynamicCast<TouchListenerComponent>(wrappingComponentsMap["touch"]);
284         if (touchListenerComponent) {
285             return touchListenerComponent;
286         }
287     }
288 
289     RefPtr<TouchListenerComponent> touchComponent = AceType::MakeRefPtr<OHOS::Ace::TouchListenerComponent>();
290     wrappingComponentsMap.emplace("touch", touchComponent);
291     return touchComponent;
292 }
293 
GetMouseListenerComponent()294 RefPtr<MouseListenerComponent> ViewStackProcessor::GetMouseListenerComponent()
295 {
296     auto& wrappingComponentsMap = componentsStack_.top();
297     if (wrappingComponentsMap.find("mouse") != wrappingComponentsMap.end()) {
298         auto mouseListenerComponent = AceType::DynamicCast<MouseListenerComponent>(wrappingComponentsMap["mouse"]);
299         if (mouseListenerComponent) {
300             return mouseListenerComponent;
301         }
302     }
303 
304     RefPtr<MouseListenerComponent> mouseComponent = AceType::MakeRefPtr<OHOS::Ace::MouseListenerComponent>();
305     wrappingComponentsMap.emplace("mouse", mouseComponent);
306     return mouseComponent;
307 }
308 
HasClickGestureListenerComponent() const309 bool ViewStackProcessor::HasClickGestureListenerComponent() const
310 {
311     auto& wrappingComponentsMap = componentsStack_.top();
312     if (wrappingComponentsMap.find("click_gesture") != wrappingComponentsMap.end()) {
313         return true;
314     }
315     return false;
316 }
317 
GetClickGestureListenerComponent()318 RefPtr<GestureListenerComponent> ViewStackProcessor::GetClickGestureListenerComponent()
319 {
320     auto& wrappingComponentsMap = componentsStack_.top();
321     if (wrappingComponentsMap.find("click_gesture") != wrappingComponentsMap.end()) {
322         auto gestureListenerComponent =
323             AceType::DynamicCast<GestureListenerComponent>(wrappingComponentsMap["click_gesture"]);
324         if (gestureListenerComponent) {
325             return gestureListenerComponent;
326         }
327     }
328 
329     RefPtr<GestureListenerComponent> clickGestureComponent =
330         AceType::MakeRefPtr<OHOS::Ace::GestureListenerComponent>();
331     wrappingComponentsMap.emplace("click_gesture", clickGestureComponent);
332     return clickGestureComponent;
333 }
334 
GetFocusableComponent(bool createIfNotExist)335 RefPtr<FocusableComponent> ViewStackProcessor::GetFocusableComponent(bool createIfNotExist)
336 {
337     auto& wrappingComponentsMap = componentsStack_.top();
338     if (wrappingComponentsMap.find("focusable") != wrappingComponentsMap.end()) {
339         return AceType::DynamicCast<FocusableComponent>(wrappingComponentsMap["focusable"]);
340     }
341     if (createIfNotExist) {
342         RefPtr<FocusableComponent> focusableComponent = AceType::MakeRefPtr<OHOS::Ace::FocusableComponent>();
343         wrappingComponentsMap.emplace("focusable", focusableComponent);
344         Component::MergeRSNode(focusableComponent);
345         return focusableComponent;
346     }
347     return nullptr;
348 }
349 
GetPanGestureListenerComponent()350 RefPtr<GestureListenerComponent> ViewStackProcessor::GetPanGestureListenerComponent()
351 {
352     auto& wrappingComponentsMap = componentsStack_.top();
353     if (wrappingComponentsMap.find("pan_gesture") != wrappingComponentsMap.end()) {
354         auto gestureListenerComponent =
355             AceType::DynamicCast<GestureListenerComponent>(wrappingComponentsMap["pan_gesture"]);
356         if (gestureListenerComponent) {
357             return gestureListenerComponent;
358         }
359     }
360 
361     RefPtr<GestureListenerComponent> panGestureComponent = AceType::MakeRefPtr<OHOS::Ace::GestureListenerComponent>();
362     wrappingComponentsMap.emplace("pan_gesture", panGestureComponent);
363     return panGestureComponent;
364 }
365 
GetSharedTransitionComponent()366 RefPtr<SharedTransitionComponent> ViewStackProcessor::GetSharedTransitionComponent()
367 {
368     auto& wrappingComponentsMap = componentsStack_.top();
369     if (wrappingComponentsMap.find("shared_transition") != wrappingComponentsMap.end()) {
370         auto sharedTransitionComponent =
371             AceType::DynamicCast<SharedTransitionComponent>(wrappingComponentsMap["shared_transition"]);
372         if (sharedTransitionComponent) {
373             return sharedTransitionComponent;
374         }
375     }
376 
377     RefPtr<SharedTransitionComponent> sharedTransitionComponent =
378         AceType::MakeRefPtr<OHOS::Ace::SharedTransitionComponent>("", "", "");
379     wrappingComponentsMap.emplace("shared_transition", sharedTransitionComponent);
380     return sharedTransitionComponent;
381 }
382 
GetGestureComponent()383 RefPtr<GestureComponent> ViewStackProcessor::GetGestureComponent()
384 {
385     auto& wrappingComponentsMap = componentsStack_.top();
386     if (wrappingComponentsMap.find("gesture") != wrappingComponentsMap.end()) {
387         auto gestureComponent = AceType::DynamicCast<GestureComponent>(wrappingComponentsMap["gesture"]);
388         if (gestureComponent) {
389             return gestureComponent;
390         }
391     }
392 
393     RefPtr<GestureComponent> gestureComponent = AceType::MakeRefPtr<OHOS::Ace::GestureComponent>();
394     wrappingComponentsMap.emplace("gesture", gestureComponent);
395     return gestureComponent;
396 }
397 
GetPageTransitionComponent()398 RefPtr<PageTransitionComponent> ViewStackProcessor::GetPageTransitionComponent()
399 {
400     if (!pageTransitionComponent_) {
401         pageTransitionComponent_ = AceType::MakeRefPtr<PageTransitionComponent>();
402     }
403     return pageTransitionComponent_;
404 }
405 
ClearPageTransitionComponent()406 void ViewStackProcessor::ClearPageTransitionComponent()
407 {
408     if (pageTransitionComponent_) {
409         pageTransitionComponent_.Reset();
410     }
411 }
412 
Push(const RefPtr<Component> & component,bool isCustomView)413 void ViewStackProcessor::Push(const RefPtr<Component>& component, bool isCustomView)
414 {
415     CHECK_NULL_VOID(component);
416     std::unordered_map<std::string, RefPtr<Component>> wrappingComponentsMap;
417     if (componentsStack_.size() > 1 && ShouldPopImmediately()) {
418         Pop();
419     }
420     wrappingComponentsMap.emplace("main", component);
421     componentsStack_.push(wrappingComponentsMap);
422     std::string name;
423     auto composedComponent = AceType::DynamicCast<ComposedComponent>(component);
424     if (composedComponent) {
425         name = composedComponent->GetName();
426     }
427     auto tag = component->GetInspectorTag();
428     tag = tag.empty() ? (name.empty() ? AceType::TypeName(component) : name) : tag;
429     CreateInspectorComposedComponent(tag);
430     CreateScoringComponent(tag);
431 
432 #if defined(PREVIEW)
433     if (!isCustomView && !AceType::InstanceOf<MultiComposedComponent>(component) &&
434         !AceType::InstanceOf<TextSpanComponent>(component)) {
435         GetBoxComponent();
436     }
437 #else
438     bool isAccessEnable =
439         AceApplicationInfo::GetInstance().IsAccessibilityEnabled()
440         || SystemProperties::GetAccessibilityEnabled()
441         || SystemProperties::GetDebugBoundaryEnabled();
442     if (!isCustomView && !AceType::InstanceOf<MultiComposedComponent>(component) &&
443         !AceType::InstanceOf<TextSpanComponent>(component) && isAccessEnable) {
444         GetBoxComponent();
445     }
446 #endif
447 }
448 
ShouldPopImmediately()449 bool ViewStackProcessor::ShouldPopImmediately()
450 {
451     auto type = AceType::TypeName(GetMainComponent());
452     auto componentGroup = AceType::DynamicCast<ComponentGroup>(GetMainComponent());
453     auto multiComposedComponent = AceType::DynamicCast<MultiComposedComponent>(GetMainComponent());
454     auto soleChildComponent = AceType::DynamicCast<SoleChildComponent>(GetMainComponent());
455     auto menuComponent = AceType::DynamicCast<MenuComponent>(GetMainComponent());
456     return (strcmp(type, AceType::TypeName<TextSpanComponent>()) == 0 ||
457             !(componentGroup || multiComposedComponent || soleChildComponent || menuComponent));
458 }
459 
Pop()460 void ViewStackProcessor::Pop()
461 {
462     if (componentsStack_.empty() || componentsStack_.size() == 1) {
463         return;
464     }
465 
466     auto component = WrapComponents().first;
467     if (AceType::DynamicCast<ComposedComponent>(component)) {
468         auto childComponent = AceType::DynamicCast<ComposedComponent>(component)->GetChild();
469         SetZIndex(childComponent);
470         SetIsPercentSize(childComponent);
471     } else {
472         SetZIndex(component);
473         SetIsPercentSize(component);
474     }
475 
476     UpdateTopComponentProps(component);
477 
478     componentsStack_.pop();
479     auto componentGroup = AceType::DynamicCast<ComponentGroup>(GetMainComponent());
480     auto multiComposedComponent = AceType::DynamicCast<MultiComposedComponent>(GetMainComponent());
481     if (componentGroup) {
482         componentGroup->AppendChild(component);
483     } else if (multiComposedComponent) {
484         multiComposedComponent->AddChild(component);
485     } else {
486         auto singleChild = AceType::DynamicCast<SingleChild>(GetMainComponent());
487         if (singleChild) {
488             singleChild->SetChild(component);
489         }
490     }
491 }
492 
GetNewComponent()493 RefPtr<Component> ViewStackProcessor::GetNewComponent()
494 {
495     if (componentsStack_.empty()) {
496         return nullptr;
497     }
498     auto component = WrapComponents().first;
499     if (AceType::DynamicCast<ComposedComponent>(component)) {
500         auto childComponent = AceType::DynamicCast<ComposedComponent>(component)->GetChild();
501         SetZIndex(childComponent);
502         SetIsPercentSize(childComponent);
503     } else {
504         SetZIndex(component);
505         SetIsPercentSize(component);
506     }
507     UpdateTopComponentProps(component);
508     componentsStack_.pop();
509     return component;
510 }
511 
PopContainer()512 void ViewStackProcessor::PopContainer()
513 {
514     auto type = AceType::TypeName(GetMainComponent());
515     auto componentGroup = AceType::DynamicCast<ComponentGroup>(GetMainComponent());
516     auto multiComposedComponent = AceType::DynamicCast<MultiComposedComponent>(GetMainComponent());
517     auto soleChildComponent = AceType::DynamicCast<SoleChildComponent>(GetMainComponent());
518     if ((componentGroup && strcmp(type, AceType::TypeName<TextSpanComponent>()) != 0) || multiComposedComponent ||
519         soleChildComponent) {
520         Pop();
521         return;
522     }
523 
524     while ((!componentGroup && !multiComposedComponent && !soleChildComponent) ||
525            strcmp(type, AceType::TypeName<TextSpanComponent>()) == 0) {
526         if (componentsStack_.size() <= 1) {
527             break;
528         }
529         Pop();
530         type = AceType::TypeName(GetMainComponent());
531         componentGroup = AceType::DynamicCast<ComponentGroup>(GetMainComponent());
532         multiComposedComponent = AceType::DynamicCast<MultiComposedComponent>(GetMainComponent());
533         soleChildComponent = AceType::DynamicCast<SoleChildComponent>(GetMainComponent());
534     }
535     Pop();
536 }
537 
538 #ifdef ACE_DEBUG_LOG
DumpStack()539 void ViewStackProcessor::DumpStack()
540 {
541     if (componentsStack_.empty()) {
542         return;
543     }
544     std::stack<std::unordered_map<std::string, RefPtr<Component>>> tmp;
545     while (!componentsStack_.empty()) {
546         tmp.push(componentsStack_.top());
547         componentsStack_.pop();
548     }
549     while (!tmp.empty()) {
550         componentsStack_.push(tmp.top());
551         tmp.pop();
552     }
553 }
554 #endif
555 
WrapComponents()556 std::pair<RefPtr<Component>, RefPtr<Component>> ViewStackProcessor::WrapComponents()
557 {
558     auto& wrappingComponentsMap = componentsStack_.top();
559     std::vector<RefPtr<Component>> components;
560 
561     auto mainComponent = wrappingComponentsMap["main"];
562 
563     auto videoComponentV2 = AceType::DynamicCast<VideoComponentV2>(mainComponent);
564     SaveComponentEvent saveComponentEvent;
565     if (videoComponentV2) {
566         saveComponentEvent = videoComponentV2->GetSaveComponentEvent();
567     }
568     std::unordered_map<std::string, RefPtr<Component>> videoMap;
569 
570     bool isItemComponent = AceType::InstanceOf<V2::ListItemComponent>(mainComponent) ||
571                            AceType::InstanceOf<GridLayoutItemComponent>(mainComponent) ||
572                            AceType::InstanceOf<V2::WaterFlowItemComponent>(mainComponent);
573 
574     RefPtr<Component> itemChildComponent;
575 
576     if (isItemComponent) {
577         itemChildComponent = AceType::DynamicCast<SingleChild>(mainComponent)->GetChild();
578         components.emplace_back(mainComponent);
579     }
580 
581     auto composedComponent = GetInspectorComposedComponent();
582     if (composedComponent) {
583         components.emplace_back(composedComponent);
584     }
585 
586     auto scoringComponent = GetScoringComponent();
587     if (scoringComponent) {
588         components.emplace_back(scoringComponent);
589     }
590 
591     std::string componentNames[] = { "stepperItem", "stepperDisplay", "flexItem", "display", "transform", "touch",
592         "pan_gesture", "click_gesture", "focusable", "coverage", "box", "shared_transition", "mouse",
593         "stepperScroll" };
594     // In RS extra case, use isFirstNode to determine the top node.
595     bool isFirstNode = true;
596     for (auto& name : componentNames) {
597         auto iter = wrappingComponentsMap.find(name);
598         if (iter != wrappingComponentsMap.end()) {
599             if (isFirstNode) {
600                 iter->second->SetIsFirst(isFirstNode);
601                 isFirstNode = false;
602             }
603             iter->second->OnWrap();
604             components.emplace_back(iter->second);
605             if (videoComponentV2 && saveComponentEvent) {
606                 videoMap.emplace(std::make_pair(name, iter->second));
607             }
608         }
609     }
610 
611     // Adjust layout param in TextComponent
612     auto isTextComponent = AceType::InstanceOf<TextComponent>(mainComponent);
613     if (isTextComponent) {
614         auto iter = wrappingComponentsMap.find("box");
615         if (iter != wrappingComponentsMap.end()) {
616             auto boxComponent = AceType::DynamicCast<BoxComponent>(wrappingComponentsMap["box"]);
617             if (boxComponent) {
618                 boxComponent->SetDeliverMinToChild(false);
619             }
620         }
621     }
622 
623     if (wrappingComponentsMap.find("shared_transition") != wrappingComponentsMap.end() &&
624         wrappingComponentsMap.find("display") != wrappingComponentsMap.end()) {
625         auto sharedTransitionComponent =
626             AceType::DynamicCast<SharedTransitionComponent>(wrappingComponentsMap["shared_transition"]);
627         auto displayComponent = AceType::DynamicCast<DisplayComponent>(wrappingComponentsMap["display"]);
628         if (sharedTransitionComponent && displayComponent) {
629             sharedTransitionComponent->SetOpacity(displayComponent->GetOpacity());
630         }
631     }
632 
633     if (videoComponentV2 && saveComponentEvent) {
634         saveComponentEvent(videoMap);
635         videoComponentV2->SetSaveComponentEvent(nullptr);
636     }
637 
638     if (isItemComponent) {
639         // itemComponent is placed before other components, they should share the same RSNode.
640         // we should not touch itemChildComponent as it's already marked.
641         //    (head)       (tail)      (unchanged)
642         // mainComponent - others - itemChildComponent
643         Component::MergeRSNode(mainComponent);
644         Component::MergeRSNode(components);
645         if (itemChildComponent) {
646             components.emplace_back(itemChildComponent);
647         }
648     } else if (!components.empty() && (
649         AceType::InstanceOf<BoxComponent>(mainComponent) ||
650         AceType::InstanceOf<FormComponent>(mainComponent) ||
651         AceType::InstanceOf<TextFieldComponent>(mainComponent) ||
652         AceType::InstanceOf<TextureComponent>(mainComponent) ||
653         AceType::InstanceOf<WebComponent>(mainComponent) ||
654         AceType::InstanceOf<XComponentComponent>(mainComponent))) {
655         // special types of mainComponent need be marked as standalone.
656         // (head)(tail)  (standalone)
657         //    others  -  mainComponent
658         Component::MergeRSNode(components);
659         Component::MergeRSNode(mainComponent);
660         components.emplace_back(mainComponent);
661     } else if (AceType::InstanceOf<RemoteWindowComponent>(mainComponent)) {
662         // mark head component, it should use external RSNode stored in tail component.
663         components.emplace_back(mainComponent);
664         Component::MergeRSNode(components);
665         components.front()->MarkUseExternalRSNode(true);
666     } else {
667         // by default, mainComponent is placed after other components, they should share the same RSNode.
668         //  (head)      (tail)
669         // (others) - mainComponent
670         components.emplace_back(mainComponent);
671         Component::MergeRSNode(components);
672     }
673 
674     // First, composite all components.
675     for (int32_t idx = static_cast<int32_t>(components.size()) - 1; idx - 1 >= 0; --idx) {
676         auto singleChild = AceType::DynamicCast<SingleChild>(components[idx - 1]);
677         if (singleChild) {
678             singleChild->SetChild(components[idx]);
679             continue;
680         }
681 
682         auto coverageComponent = AceType::DynamicCast<CoverageComponent>(components[idx - 1]);
683         if (coverageComponent) {
684             coverageComponent->InsertChild(0, components[idx]);
685             if (coverageComponent->IsOverLay()) {
686                 coverageComponent->Initialization();
687                 Component::MergeRSNode(components[idx], coverageComponent);
688             }
689 #ifndef WEARABLE_PRODUCT
690             auto popupComponent = GetPopupComponent(false);
691             if (popupComponent) {
692                 coverageComponent->AppendChild(popupComponent);
693             }
694 #endif
695             auto menuComponent = GetMenuComponent(false);
696             if (menuComponent) {
697                 coverageComponent->AppendChild(menuComponent);
698             }
699         }
700 
701         auto focusableComponent = AceType::DynamicCast<FocusableComponent>(components[idx - 1]);
702         if (focusableComponent) {
703             Component::MergeRSNode(components[idx], focusableComponent);
704         }
705     }
706 
707     auto component = components.front();
708     auto iter = wrappingComponentsMap.find("box");
709     if (iter != wrappingComponentsMap.end() && (iter->second->GetTextDirection() != component->GetTextDirection())) {
710         component->SetTextDirection(iter->second->GetTextDirection());
711     }
712 
713     for (auto&& component : components) {
714         component->SetTouchable(mainComponent->IsTouchable() &&
715         mainComponent->GetHitTestMode() != HitTestMode::HTMNONE);
716     }
717 
718     for (auto&& component : components) {
719         component->SetHitTestMode(mainComponent->GetHitTestMode());
720     }
721 
722     for (auto&& component : components) {
723         component->SetDisabledStatus(mainComponent->IsDisabledStatus());
724     }
725     return std::pair<RefPtr<Component>, RefPtr<Component>>(components[0], components[components.size() - 1]);
726 }
727 
UpdateTopComponentProps(const RefPtr<Component> & component)728 void ViewStackProcessor::UpdateTopComponentProps(const RefPtr<Component>& component)
729 {
730     auto& wrappingComponentsMap = componentsStack_.top();
731     if (wrappingComponentsMap.find("position") != wrappingComponentsMap.end()) {
732         auto renderComponent = AceType::DynamicCast<RenderComponent>(component);
733         if (renderComponent) {
734             auto positionedComponent = GetPositionedComponent();
735             if (positionedComponent->HasPositionStyle()) {
736                 renderComponent->SetMotionPathOption(positionedComponent->GetMotionPathOption());
737                 renderComponent->SetHasLeft(positionedComponent->HasLeft());
738                 renderComponent->SetLeft(positionedComponent->GetLeft());
739                 renderComponent->SetHasTop(positionedComponent->HasTop());
740                 renderComponent->SetTop(positionedComponent->GetTop());
741                 renderComponent->SetHasBottom(positionedComponent->HasBottom());
742                 renderComponent->SetBottom(positionedComponent->GetBottom());
743                 renderComponent->SetHasRight(positionedComponent->HasRight());
744                 renderComponent->SetRight(positionedComponent->GetRight());
745                 renderComponent->SetPositionType(positionedComponent->GetPositionType());
746             }
747         }
748     }
749 }
750 
FinishReturnMain()751 std::pair<RefPtr<Component>, RefPtr<Component>> ViewStackProcessor::FinishReturnMain()
752 {
753     if (componentsStack_.empty()) {
754         LOGE("ViewStackProcessor FinishInternal failed, input empty render or invalid root component");
755         return std::pair<RefPtr<Component>, RefPtr<Component>>(nullptr, nullptr);
756     }
757     const auto& componentsPair = WrapComponents();
758     auto component = componentsPair.first;
759     if (AceType::DynamicCast<ComposedComponent>(component)) {
760         auto childComponent = AceType::DynamicCast<ComposedComponent>(component)->GetChild();
761         SetZIndex(childComponent);
762     } else {
763         SetZIndex(component);
764     }
765     componentsStack_.pop();
766     return componentsPair;
767 }
768 
PushKey(const std::string & key)769 void ViewStackProcessor::PushKey(const std::string& key)
770 {
771     if (viewKey_.empty()) {
772         viewKey_ = key;
773         keyStack_.emplace(key.length());
774     } else {
775         viewKey_.append("_").append(key);
776         keyStack_.emplace(key.length() + 1);
777     }
778 }
779 
PopKey()780 void ViewStackProcessor::PopKey()
781 {
782     size_t length = keyStack_.top();
783     keyStack_.pop();
784 
785     if (length > 0) {
786         viewKey_.erase(viewKey_.length() - length);
787     }
788 }
789 
GetKey()790 std::string ViewStackProcessor::GetKey()
791 {
792     return viewKey_.empty() ? "" : viewKey_;
793 }
794 
ProcessViewId(const std::string & viewId)795 std::string ViewStackProcessor::ProcessViewId(const std::string& viewId)
796 {
797     return viewKey_.empty() ? viewId : viewKey_ + "_" + viewId;
798 }
799 
SetImplicitAnimationOption(const AnimationOption & option)800 void ViewStackProcessor::SetImplicitAnimationOption(const AnimationOption& option)
801 {
802     implicitAnimationOption_ = option;
803 }
804 
GetImplicitAnimationOption() const805 const AnimationOption& ViewStackProcessor::GetImplicitAnimationOption() const
806 {
807     return implicitAnimationOption_;
808 }
809 
SetZIndex(RefPtr<Component> & component)810 void ViewStackProcessor::SetZIndex(RefPtr<Component>& component)
811 {
812     int32_t zIndex = 0;
813     auto mainComponent = AceType::DynamicCast<RenderComponent>(GetMainComponent());
814     if (mainComponent) {
815         zIndex = mainComponent->GetZIndex();
816     }
817 
818     auto renderComponent = AceType::DynamicCast<RenderComponent>(component);
819     if (renderComponent) {
820         renderComponent->SetZIndex(zIndex);
821     }
822 }
823 
GetInspectorComposedComponent() const824 RefPtr<V2::InspectorComposedComponent> ViewStackProcessor::GetInspectorComposedComponent() const
825 {
826     if (componentsStack_.empty()) {
827         return nullptr;
828     }
829     auto& wrappingComponentsMap = componentsStack_.top();
830     auto iter = wrappingComponentsMap.find("inspector");
831     if (iter != wrappingComponentsMap.end()) {
832         return AceType::DynamicCast<V2::InspectorComposedComponent>(iter->second);
833     }
834     return nullptr;
835 }
836 
GetScoringComponent() const837 RefPtr<Component> ViewStackProcessor::GetScoringComponent() const
838 {
839     if (componentsStack_.empty()) {
840         return nullptr;
841     }
842     auto& wrappingComponentsMap = componentsStack_.top();
843     auto iter = wrappingComponentsMap.find("scoring");
844     if (iter != wrappingComponentsMap.end()) {
845         return iter->second;
846     }
847     return nullptr;
848 }
849 
CreateInspectorWrapper(const std::string & inspectorTag)850 RefPtr<ComposedComponent> ViewStackProcessor::CreateInspectorWrapper(const std::string& inspectorTag)
851 {
852     return AceType::MakeRefPtr<V2::InspectorComposedComponent>(
853         V2::InspectorComposedComponent::GenerateId(), inspectorTag);
854 }
855 
CreateInspectorComposedComponent(const std::string & inspectorTag)856 void ViewStackProcessor::CreateInspectorComposedComponent(const std::string& inspectorTag)
857 {
858     if (V2::InspectorComposedComponent::HasInspectorFinished(inspectorTag)) {
859         auto composedComponent = AceType::MakeRefPtr<V2::InspectorComposedComponent>(
860             V2::InspectorComposedComponent::GenerateId(), inspectorTag);
861         auto& wrappingComponentsMap = componentsStack_.top();
862 #if defined(PREVIEW)
863         composedComponent->SetViewId(viewKey_);
864 #endif
865         wrappingComponentsMap.emplace("inspector", composedComponent);
866     }
867 }
868 
CreateScoringComponent(const std::string & tag)869 void ViewStackProcessor::CreateScoringComponent(const std::string& tag)
870 {
871     static std::once_flag onceFlag;
872     std::call_once(onceFlag, [this]() {
873         auto name = AceApplicationInfo::GetInstance().GetProcessName().empty()
874                         ? AceApplicationInfo::GetInstance().GetPackageName()
875                         : AceApplicationInfo::GetInstance().GetProcessName();
876         isScoringEnable_ = SystemProperties::IsScoringEnabled(name);
877     });
878 
879     if (isScoringEnable_ && V2::InspectorComposedComponent::HasInspectorFinished(tag)) {
880         auto component =
881             AceType::MakeRefPtr<ScoringComponent>(V2::InspectorComposedComponent::GetEtsTag(tag), viewKey_);
882         auto& wrappingComponentsMap = componentsStack_.top();
883         wrappingComponentsMap.emplace("scoring", component);
884     }
885 }
886 
SetIsPercentSize(RefPtr<Component> & component)887 void ViewStackProcessor::SetIsPercentSize(RefPtr<Component>& component)
888 {
889     bool isPercentSize = false;
890     auto mainComponent = AceType::DynamicCast<RenderComponent>(GetMainComponent());
891     if (mainComponent) {
892         isPercentSize = mainComponent->GetIsPercentSize();
893     }
894 
895     auto renderComponent = AceType::DynamicCast<RenderComponent>(component);
896     if (renderComponent) {
897         renderComponent->SetIsPercentSize(isPercentSize);
898     }
899 }
900 
ClaimElementId(const RefPtr<Component> & component)901 void ViewStackProcessor::ClaimElementId(const RefPtr<Component>& component)
902 {
903     component->AssignUniqueElementId(reservedElementId_);
904     reservedElementId_ = ElementRegister::UndefinedElementId;
905 }
906 
ScopedViewStackProcessor()907 ScopedViewStackProcessor::ScopedViewStackProcessor()
908 {
909     std::swap(instance_, ViewStackProcessor::instance);
910 }
911 
~ScopedViewStackProcessor()912 ScopedViewStackProcessor::~ScopedViewStackProcessor()
913 {
914     std::swap(instance_, ViewStackProcessor::instance);
915 }
916 
917 } // namespace OHOS::Ace::Framework
918