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