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_grid_column.h"
17 
18 namespace OHOS::Ace::Framework {
19 
DomGridColumn(NodeId nodeId,const std::string & nodeName)20 DomGridColumn::DomGridColumn(NodeId nodeId, const std::string& nodeName) : DOMDiv(nodeId, nodeName)
21 {
22     infoBuilder_.SetColumns(1); // default span 1 column
23 }
24 
GetSpecializedComponent()25 RefPtr<Component> DomGridColumn::GetSpecializedComponent()
26 {
27     if (!columnInfo_) {
28         columnInfo_ = infoBuilder_.Build();
29         boxComponent_->SetGridLayoutInfo(columnInfo_);
30         if (!flexItemComponent_) {
31             flexItemComponent_ = AceType::MakeRefPtr<FlexItemComponent>();
32         }
33         flexItemComponent_->SetGridColumnInfoBuilder(boxComponent_->GetGridColumnInfoBuilder());
34     }
35     return DOMDiv::GetSpecializedComponent();
36 }
37 
OnChildNodeAdded(const RefPtr<DOMNode> & child,int32_t slot)38 void DomGridColumn::OnChildNodeAdded(const RefPtr<DOMNode>& child, int32_t slot)
39 {
40     ACE_DCHECK(child);
41     DOMDiv::OnChildNodeAdded(child, slot);
42 }
43 
OnChildNodeRemoved(const RefPtr<DOMNode> & child)44 void DomGridColumn::OnChildNodeRemoved(const RefPtr<DOMNode>& child)
45 {
46     ACE_DCHECK(child);
47     DOMDiv::OnChildNodeRemoved(child);
48 }
49 
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)50 bool DomGridColumn::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
51 {
52     static const LinearMapNode<void (*)(const std::string&, DomGridColumn&)> attrOperators[] {
53         { DOM_GRID_SIZE_TYPE_LG,
54             [](const std::string& value, DomGridColumn& column) {
55                 uint32_t span = 0;
56                 Dimension offset = UNDEFINED_DIMENSION;
57                 column.ParseSpanAndOffset(value, span, offset);
58                 column.infoBuilder_.SetLgSizeColumn(span, offset);
59             } },
60         { DOM_GRID_SIZE_TYPE_MD,
61             [](const std::string& value, DomGridColumn& column) {
62                 uint32_t span = 0;
63                 Dimension offset = UNDEFINED_DIMENSION;
64                 column.ParseSpanAndOffset(value, span, offset);
65                 column.infoBuilder_.SetMdSizeColumn(span, offset);
66             } },
67         { DOM_GRID_COLUMN_OFFSET,
68             [](const std::string& value, DomGridColumn& column) {
69                 auto declaration = column.GetDeclaration();
70                 if (!declaration) {
71                     return;
72                 }
73                 auto& positionStyle =
74                     declaration->MaybeResetStyle<CommonPositionStyle>(StyleTag::COMMON_POSITION_STYLE);
75                 if (positionStyle.IsValid()) {
76                     positionStyle.position = PositionType::PTABSOLUTE;
77                     positionStyle.top = Dimension(0.0, DimensionUnit::PX);
78                     positionStyle.left = column.ParseDimension(value);
79                     declaration->SetHasLeft(true);
80                     declaration->SetHasTop(true);
81                     declaration->SetHasPositionStyle(true);
82                 }
83             } },
84         { DOM_GRID_SIZE_TYPE_SM,
85             [](const std::string& value, DomGridColumn& column) {
86                 uint32_t span = 0;
87                 Dimension offset = UNDEFINED_DIMENSION;
88                 column.ParseSpanAndOffset(value, span, offset);
89                 column.infoBuilder_.SetSmSizeColumn(span, offset);
90             } },
91         { DOM_GRID_COLUMN_SPAN,
92             [](const std::string& value, DomGridColumn& column) {
93                 column.infoBuilder_.SetColumns(StringUtils::StringToUint(value));
94             } },
95         { DOM_GRID_SIZE_TYPE_XS,
96             [](const std::string& value, DomGridColumn& column) {
97                 uint32_t span = 0;
98                 Dimension offset = UNDEFINED_DIMENSION;
99                 column.ParseSpanAndOffset(value, span, offset);
100                 column.infoBuilder_.SetXsSizeColumn(span, offset);
101             } },
102     };
103 
104     auto operatorIter = BinarySearchFindIndex(attrOperators, ArraySize(attrOperators), attr.first.c_str());
105     if (operatorIter != -1) {
106         attrOperators[operatorIter].value(attr.second, *this);
107         return true;
108     }
109     return false;
110 }
111 
ParseSpanAndOffset(const std::string & value,uint32_t & span,Dimension & offset)112 void DomGridColumn::DomGridColumn::ParseSpanAndOffset(const std::string& value, uint32_t& span, Dimension& offset)
113 {
114     span = StringUtils::StringToUint(value);
115     if (span > 0) {
116         return;
117     }
118 
119     std::unique_ptr<JsonValue> jsonValue = JsonUtil::ParseJsonString(value);
120     if (!jsonValue) {
121         return;
122     }
123 
124     std::unique_ptr<JsonValue> spanValue = jsonValue->GetValue(DOM_GRID_COLUMN_SPAN);
125     if (spanValue && spanValue->IsNumber()) {
126         span = spanValue->GetUInt();
127     }
128 
129     std::unique_ptr<JsonValue> offsetValue = jsonValue->GetValue(DOM_GRID_COLUMN_OFFSET);
130     if (!offsetValue) {
131         return;
132     }
133     if (offsetValue->IsNumber()) {
134         offset.SetValue(offsetValue->GetDouble());
135     } else if (offsetValue->IsString()) {
136         offset = ParseDimension(offsetValue->GetString());
137     }
138 }
139 
140 } // namespace OHOS::Ace::Framework
141