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