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