1 /*
2 * Copyright (c) 2021 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 "frameworks/bridge/common/dom/dom_stack.h"
17
18 #include "base/utils/linear_map.h"
19 #include "base/utils/utils.h"
20 #include "core/common/ace_application_info.h"
21 #include "core/components/common/layout/constants.h"
22 #include "core/components/common/properties/color.h"
23 #include "core/components/scroll/scroll_bar_theme.h"
24 #include "core/components/scroll/scroll_fade_effect.h"
25 #include "core/components/scroll/scroll_spring_effect.h"
26 #include "core/components/theme/theme_manager.h"
27
28 namespace OHOS::Ace::Framework {
29
DOMStack(NodeId nodeId,const std::string & nodeName)30 DOMStack::DOMStack(NodeId nodeId, const std::string& nodeName) : DOMNode(nodeId, nodeName)
31 {
32 stackChild_ = AceType::MakeRefPtr<StackComponent>(
33 alignment_, stackFit_, Overflow::OBSERVABLE, std::list<RefPtr<Component>>());
34 }
35
OnChildNodeAdded(const RefPtr<DOMNode> & child,int32_t slot)36 void DOMStack::OnChildNodeAdded(const RefPtr<DOMNode>& child, int32_t slot)
37 {
38 ACE_DCHECK(child);
39 LOGD("DOMStack Add Child");
40 // If child has absolute position, the stack should be as large as the box component, so that the position is
41 // correct in front-end.
42 auto childDeclaration = child->GetDeclaration();
43 if (childDeclaration && childDeclaration->HasPositionStyle() &&
44 stackChild_->GetMainStackSize() != MainStackSize::MAX) {
45 stackChild_->SetMainStackSize(MainStackSize::MATCH_CHILDREN);
46 }
47 stackChild_->InsertChild(slot, child->GetRootComponent());
48 }
49
OnChildNodeRemoved(const RefPtr<DOMNode> & child)50 void DOMStack::OnChildNodeRemoved(const RefPtr<DOMNode>& child)
51 {
52 ACE_DCHECK(child);
53 LOGD("DOMStack remove child");
54 stackChild_->RemoveChild(child->GetRootComponent());
55 }
56
GetAxisOffset(const std::pair<std::string,std::string> & style)57 bool DOMStack::GetAxisOffset(const std::pair<std::string, std::string>& style)
58 {
59 static const LinearMapNode<void (*)(const std::string&, DOMStack&)> stackStyleOperators[] = {
60 { DOM_ALIGN_ITEMS,
61 [](const std::string& val, DOMStack& stack) {
62 if (val == DOM_ALIGN_ITEMS_END) {
63 stack.crossAxisAlign_ = END;
64 } else if (val == DOM_ALIGN_ITEMS_CENTER) {
65 stack.crossAxisAlign_ = CENTER;
66 } else {
67 stack.crossAxisAlign_ = START;
68 }
69 } },
70 { DOM_FLEX_DIRECTION,
71 [](const std::string& val, DOMStack& stack) {
72 if (val == DOM_FLEX_COLUMN) {
73 stack.direction_ = FlexDirection::COLUMN;
74 } else if (val == DOM_FLEX_COLUMN_REVERSE) {
75 stack.direction_ = FlexDirection::COLUMN_REVERSE;
76 } else if (val == DOM_FLEX_ROW_REVERSE) {
77 stack.direction_ = FlexDirection::ROW_REVERSE;
78 } else {
79 stack.direction_ = FlexDirection::ROW;
80 }
81 } },
82 { DOM_JUSTIFY_CONTENT,
83 [](const std::string& val, DOMStack& stack) {
84 if (val == DOM_JUSTIFY_CONTENT_END) {
85 stack.mainAxisAlign_ = END;
86 } else if (val == DOM_JUSTIFY_CONTENT_CENTER || val == DOM_JUSTIFY_CONTENT_AROUND) {
87 stack.mainAxisAlign_ = CENTER;
88 } else {
89 stack.mainAxisAlign_ = START;
90 }
91 } },
92 };
93 auto operatorIter = BinarySearchFindIndex(stackStyleOperators, ArraySize(stackStyleOperators), style.first.c_str());
94 if (operatorIter != -1) {
95 stackStyleOperators[operatorIter].value(style.second, *this);
96 return true;
97 }
98 return false;
99 }
100
SetSpecializedStyle(const std::pair<std::string,std::string> & style)101 bool DOMStack::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
102 {
103 return GetAxisOffset(style);
104 }
105
PrepareSpecializedComponent()106 void DOMStack::PrepareSpecializedComponent()
107 {
108 if (FlexDirection::COLUMN == direction_) {
109 alignment_ = AlignArray[mainAxisAlign_][crossAxisAlign_];
110 } else {
111 alignment_ = AlignArray[crossAxisAlign_][mainAxisAlign_];
112 }
113 LOGD("DOMStack Vertical:%{private}lf ,Horizontal:%{private}lf", alignment_.GetVertical(),
114 alignment_.GetHorizontal());
115 if (boxComponent_->GetWidthDimension().IsValid() && boxComponent_->GetHeightDimension().IsValid()) {
116 stackChild_->SetMainStackSize(MainStackSize::MAX);
117 } else if (boxComponent_->GetWidthDimension().IsValid()) {
118 stackChild_->SetMainStackSize(MainStackSize::MAX_X);
119 } else if (boxComponent_->GetHeightDimension().IsValid()) {
120 stackChild_->SetMainStackSize(MainStackSize::MAX_Y);
121 }
122 stackChild_->SetAlignment(alignment_);
123 SetAlignment(alignment_);
124 auto& overflowStyle = static_cast<CommonOverflowStyle&>(declaration_->GetStyle(StyleTag::COMMON_OVERFLOW_STYLE));
125 if (!overflowStyle.IsValid()) {
126 return;
127 }
128 if (overflowStyle.overflow == Overflow::SCROLL) {
129 stackChild_->SetMainStackSize(MainStackSize::MATCH_CHILDREN);
130 }
131 }
132
CompositeComponents()133 void DOMStack::CompositeComponents()
134 {
135 DOMNode::CompositeComponents();
136
137 if (!declaration_) {
138 return;
139 }
140 scroll_.Reset();
141 auto& overflowStyle = static_cast<CommonOverflowStyle&>(declaration_->GetStyle(StyleTag::COMMON_OVERFLOW_STYLE));
142 if (!overflowStyle.IsValid()) {
143 return;
144 }
145
146 bool isRootScroll =
147 isRootNode_ && (!declaration_->HasOverflowStyle() || overflowStyle.overflow == Overflow::SCROLL);
148 bool isCard = AceApplicationInfo::GetInstance().GetIsCardType();
149 if (isRootScroll && !isCard) {
150 auto rootChild = rootComponent_->GetChild();
151 scroll_ = AceType::MakeRefPtr<ScrollComponent>(rootChild);
152 scroll_->InitScrollBar(GetTheme<ScrollBarTheme>(), overflowStyle.scrollBarColor, overflowStyle.scrollBarWidth,
153 overflowStyle.edgeEffect);
154 declaration_->SetPositionController(scroll_->GetScrollPositionController());
155 rootComponent_->SetChild(scroll_);
156 }
157 }
158
159 } // namespace OHOS::Ace::Framework
160