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_span.h"
17 
18 namespace OHOS::Ace::Framework {
19 
DOMSpan(NodeId nodeId,const std::string & nodeName)20 DOMSpan::DOMSpan(NodeId nodeId, const std::string& nodeName) : DOMNode(nodeId, nodeName)
21 {
22     textSpanChild_ = AceType::MakeRefPtr<TextSpanComponent>("");
23     // span has no box component.
24     boxComponent_.Reset();
25 }
26 
ResetInitializedStyle()27 void DOMSpan::ResetInitializedStyle()
28 {
29     for (const auto& child : GetChildList()) {
30         auto domSpan = AceType::DynamicCast<DOMSpan>(child);
31         if (!domSpan) {
32             continue;
33         }
34         auto spanComponent = AceType::DynamicCast<TextSpanComponent>(domSpan->GetSpecializedComponent());
35         if (!spanComponent) {
36             continue;
37         }
38 
39         // If span component has no developer-set styles, then set text styles to span
40         TextStyle spanStyle = spanComponent->GetTextStyle();
41         CheckAndSetCurrentSpanStyle(domSpan, spanStyle, textSpanChild_->GetTextStyle());
42         domSpan->SetTextStyle(spanStyle);
43         spanComponent->SetTextStyle(spanStyle);
44     }
45 }
46 
CheckAndSetCurrentSpanStyle(const RefPtr<DOMSpan> & domSpan,TextStyle & currentStyle,const TextStyle & parentStyle)47 void DOMSpan::CheckAndSetCurrentSpanStyle(
48     const RefPtr<DOMSpan>& domSpan, TextStyle& currentStyle, const TextStyle& parentStyle)
49 {
50     if (!domSpan->HasSetFontColor()) {
51         currentStyle.SetTextColor(parentStyle.GetTextColor());
52     }
53     if (!domSpan->HasSetFontSize()) {
54         currentStyle.SetFontSize(parentStyle.GetFontSize());
55     }
56     if (!domSpan->HasSetFontStyle()) {
57         currentStyle.SetFontStyle(parentStyle.GetFontStyle());
58     }
59     if (!domSpan->HasSetFontWeight()) {
60         currentStyle.SetFontWeight(parentStyle.GetFontWeight());
61     }
62     if (!domSpan->HasSetTextDecoration()) {
63         currentStyle.SetTextDecoration(parentStyle.GetTextDecoration());
64     }
65     if (!domSpan->HasSetTextDecorationColor()) {
66         currentStyle.SetTextDecorationColor(parentStyle.GetTextDecorationColor());
67     }
68     if (!domSpan->HasSetTextDecorationStyle()) {
69         currentStyle.SetTextDecorationStyle(parentStyle.GetTextDecorationStyle());
70     }
71     if (!domSpan->HasSetFontFamily()) {
72         currentStyle.SetFontFamilies(parentStyle.GetFontFamilies());
73     }
74     if (!domSpan->HasSetAllowScale()) {
75         currentStyle.SetAllowScale(parentStyle.IsAllowScale());
76     }
77     if (!domSpan->HasSetFontFeatures()) {
78         currentStyle.SetFontFeatures(parentStyle.GetFontFeatures());
79     }
80     currentStyle.SetLetterSpacing(parentStyle.GetLetterSpacing());
81     currentStyle.SetLineHeight(parentStyle.GetLineHeight(), parentStyle.HasHeightOverride());
82 }
83 
OnChildNodeAdded(const RefPtr<DOMNode> & child,int32_t slot)84 void DOMSpan::OnChildNodeAdded(const RefPtr<DOMNode>& child, int32_t slot)
85 {
86     if (!child) {
87         return;
88     }
89 
90     if (child->GetTag() == DOM_NODE_TAG_SPAN) {
91         // Get current span's parent (also span) styles, if no user setting styles
92         // on this span, use its parent styles.
93         TextStyle parentSpanStyle = textSpanChild_->GetTextStyle();
94         auto spanComponent = AceType::DynamicCast<TextSpanComponent>(child->GetSpecializedComponent());
95         if (!spanComponent) {
96             return;
97         }
98 
99         // Get current span's styles to compare with its parent span.
100         TextStyle currentSpanStyle = spanComponent->GetTextStyle();
101         auto domSpan = AceType::DynamicCast<DOMSpan>(child);
102         CheckAndSetCurrentSpanStyle(domSpan, currentSpanStyle, parentSpanStyle);
103         domSpan->SetTextStyle(currentSpanStyle);
104         spanComponent->SetTextStyle(currentSpanStyle);
105         textSpanChild_->InsertChild(slot, child->GetRootComponent());
106     }
107 }
108 
OnChildNodeRemoved(const RefPtr<DOMNode> & child)109 void DOMSpan::OnChildNodeRemoved(const RefPtr<DOMNode>& child)
110 {
111     if (!child) {
112         return;
113     }
114 
115     textSpanChild_->RemoveChild(child->GetRootComponent());
116 }
117 
PrepareSpecializedComponent()118 void DOMSpan::PrepareSpecializedComponent()
119 {
120     auto spanDeclaration = AceType::DynamicCast<SpanDeclaration>(declaration_);
121     if (!spanDeclaration) {
122         return;
123     }
124     auto& specializedStyle = declaration_->MaybeResetStyle<SpanStyle>(StyleTag::SPECIALIZED_STYLE);
125     if (specializedStyle.IsValid()) {
126         bool isCard = AceApplicationInfo::GetInstance().GetIsCardType();
127         if (isCard) {
128             specializedStyle.spanStyle.SetAllowScale(false);
129             if (specializedStyle.spanStyle.GetFontSize().Unit() == DimensionUnit::FP) {
130                 specializedStyle.spanStyle.SetAllowScale(true);
131             }
132         }
133     }
134 
135     textSpanChild_->SetDeclaration(spanDeclaration);
136 }
137 
138 } // namespace OHOS::Ace::Framework
139