• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_switch.h"
17 
18 #include "base/i18n/localization.h"
19 #include "base/utils/linear_map.h"
20 #include "base/utils/utils.h"
21 #include "frameworks/bridge/common/utils/utils.h"
22 
23 namespace OHOS::Ace::Framework {
24 namespace {
25 
26 constexpr Dimension BOX_HOVER_RADIUS = 8.0_vp;
27 
28 } // namespace
29 
DOMSwitch(NodeId nodeId,const std::string & nodeName)30 DOMSwitch::DOMSwitch(NodeId nodeId, const std::string& nodeName) : DOMNode(nodeId, nodeName)
31 {
32     switchChild_ = AceType::MakeRefPtr<SwitchComponent>(nullptr);
33     switchChild_->SetTextOn(Localization::GetInstance()->GetEntryLetters("switch.on"));
34     switchChild_->SetTextOff(Localization::GetInstance()->GetEntryLetters("switch.off"));
35 }
36 
InitializeStyle()37 void DOMSwitch::InitializeStyle()
38 {
39     ResetInitializedStyle();
40 }
41 
ResetInitializedStyle()42 void DOMSwitch::ResetInitializedStyle()
43 {
44     RefPtr<SwitchTheme> theme = GetTheme<SwitchTheme>();
45     if (theme) {
46         switchChild_->ApplyTheme(theme);
47     }
48     switchChild_->SetTextOn(Localization::GetInstance()->GetEntryLetters("switch.on"));
49     switchChild_->SetTextOff(Localization::GetInstance()->GetEntryLetters("switch.off"));
50 }
51 
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)52 bool DOMSwitch::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
53 {
54     static const LinearMapNode<void (*)(const std::string&, SwitchComponent&, std::string&, std::string&)>
55         switchAttrOperators[] = {
56             { DOM_CHECKED, [](const std::string& val, SwitchComponent& textSwitch, std::string& textOn,
57                                std::string& textOff) { textSwitch.SetValue(StringToBool(val)); } },
58             { DOM_DISABLED, [](const std::string& val, SwitchComponent& textSwitch, std::string& textOn,
59                                 std::string& textOff) { textSwitch.SetDisabled(StringToBool(val)); } },
60             { DOM_SHOW_TEXT, [](const std::string& val, SwitchComponent& textSwitch, std::string& textOn,
61                                  std::string& textOff) { textSwitch.SetShowText(StringToBool(val)); } },
62             { DOM_TEXT_OFF,
63                 [](const std::string& val, SwitchComponent& textSwitch, std::string& textOn, std::string& textOff) {
64                     textSwitch.SetTextOff(val);
65                     textOff = val;
66                 } },
67             { DOM_TEXT_ON,
68                 [](const std::string& val, SwitchComponent& textSwitch, std::string& textOn, std::string& textOff) {
69                     textSwitch.SetTextOn(val);
70                     textOn = val;
71                 } },
72         };
73     auto operatorIter = BinarySearchFindIndex(
74         switchAttrOperators, ArraySize(switchAttrOperators), attr.first.c_str());
75     if (operatorIter != -1) {
76         switchAttrOperators[operatorIter].value(attr.second, *switchChild_, textOn_, textOff_);
77         return true;
78     }
79     return false;
80 }
81 
SetSpecializedStyle(const std::pair<std::string,std::string> & style)82 bool DOMSwitch::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
83 {
84     static const LinearMapNode<void (*)(const std::string&, const DOMSwitch&, SwitchComponent&, TextStyle&)>
85         switchTextOperators[] = {
86             { DOM_TEXT_ALLOW_SCALE, [](const std::string& val, const DOMSwitch& node, SwitchComponent& textSwitch,
87                                     TextStyle& textStyle) { textStyle.SetAllowScale(StringToBool(val)); } },
88             { DOM_TEXT_FONT_FAMILY,
89                 [](const std::string& val, const DOMSwitch& node, SwitchComponent& textSwitch, TextStyle& textStyle) {
90                     textStyle.SetFontFamilies(node.ParseFontFamilies(val));
91                 } },
92             { DOM_TEXT_FONT_SIZE, [](const std::string& val, const DOMSwitch& node, SwitchComponent& textSwitch,
93                                   TextStyle& textStyle) { textStyle.SetFontSize(node.ParseDimension(val)); } },
94             { DOM_TEXT_FONT_STYLE, [](const std::string& val, const DOMSwitch& node, SwitchComponent& textSwitch,
95                                    TextStyle& textStyle) { textStyle.SetFontStyle(ConvertStrToFontStyle(val)); } },
96             { DOM_TEXT_FONT_WEIGHT, [](const std::string& val, const DOMSwitch& node, SwitchComponent& textSwitch,
97                                     TextStyle& textStyle) { textStyle.SetFontWeight(ConvertStrToFontWeight(val)); } },
98             { DOM_TEXT_LETTER_SPACING,
99                 [](const std::string& val, const DOMSwitch& node, SwitchComponent& textSwitch, TextStyle& textStyle) {
100                     textStyle.SetLetterSpacing(node.ParseDimension(val)); } },
101             { DOM_TEXT_DECORATION,
102                 [](const std::string& val, const DOMSwitch& node, SwitchComponent& textSwitch, TextStyle& textStyle) {
103                     textStyle.SetTextDecoration(ConvertStrToTextDecoration(val));
104                 } },
105             { DOM_TEXT_PADDING, [](const std::string& val, const DOMSwitch& node, SwitchComponent& textSwitch,
106                                 TextStyle& textStyle) { textSwitch.SetTextPadding(node.ParseDimension(val)); } },
107             { DOM_TEXT_OFF_COLOR, [](const std::string& val, const DOMSwitch& node, SwitchComponent& textSwitch,
108                                   TextStyle& textStyle) { textSwitch.SetTextColorOff(node.ParseColor(val)); } },
109             { DOM_TEXT_ON_COLOR, [](const std::string& val, const DOMSwitch& node, SwitchComponent& textSwitch,
110                                  TextStyle& textStyle) { textSwitch.SetTextColorOn(node.ParseColor(val)); } },
111         };
112     auto operatorIter = BinarySearchFindIndex(switchTextOperators, ArraySize(switchTextOperators), style.first.c_str());
113     if (operatorIter != -1) {
114         switchTextOperators[operatorIter].value(style.second, *this, *switchChild_, textStyle_);
115         return true;
116     }
117     return false;
118 }
119 
AddSpecializedEvent(int32_t pageId,const std::string & event)120 bool DOMSwitch::AddSpecializedEvent(int32_t pageId, const std::string& event)
121 {
122     if (event == DOM_CHANGE) {
123         changeEvent_ = EventMarker(GetNodeIdForEvent(), event, pageId);
124         switchChild_->SetChangeEvent(changeEvent_);
125         return true;
126     } else if (event == DOM_CLICK) {
127         EventMarker eventMarker(GetNodeIdForEvent(), event, pageId);
128         eventMarker.SetCatchMode(false);
129         switchChild_->SetClickEvent(eventMarker);
130     } else if (event == DOM_CATCH_BUBBLE_CLICK) {
131         EventMarker eventMarker(GetNodeIdForEvent(), event, pageId);
132         eventMarker.SetCatchMode(true);
133         switchChild_->SetClickEvent(eventMarker);
134     }
135     return false;
136 }
137 
PrepareCheckedListener()138 void DOMSwitch::PrepareCheckedListener()
139 {
140     auto weak = AceType::WeakClaim(this);
141     auto checkableChangeCallback = [weak](const std::string& checked) {
142         auto domNode = weak.Upgrade();
143         if (!domNode) {
144             LOGE("get dom node failed!");
145             return;
146         }
147         bool isChecked = checked.find("\"checked\":true") != std::string::npos;
148         std::string checkedString = isChecked ? "true" : "false";
149         domNode->SetSpecializedAttr(std::make_pair(DOM_CHECKED, checkedString));
150         domNode->OnChecked(isChecked);
151     };
152     auto checkableChangeMarker = BackEndEventManager<void(const std::string&)>::GetInstance().GetAvailableMarker();
153     BackEndEventManager<void(const std::string&)>::GetInstance().BindBackendEvent(
154         checkableChangeMarker, checkableChangeCallback);
155     switchChild_->SetDomChangeEvent(checkableChangeMarker);
156 }
157 
PrepareSpecializedComponent()158 void DOMSwitch::PrepareSpecializedComponent()
159 {
160     if (boxComponent_) {
161         boxComponent_->SetMouseAnimationType(HoverAnimationType::OPACITY);
162         if (!boxComponent_->GetBackDecoration()) {
163             RefPtr<Decoration> backDecoration = AceType::MakeRefPtr<Decoration>();
164             backDecoration->SetBorderRadius(Radius(BOX_HOVER_RADIUS));
165             boxComponent_->SetBackDecoration(backDecoration);
166         }
167     }
168     if (HasCheckedPseudo()) {
169         PrepareCheckedListener();
170     }
171     switchChild_->SetTextDirection(IsRightToLeft() ? TextDirection::RTL : TextDirection::LTR);
172     switchChild_->SetTextStyle(textStyle_);
173     if (!textOn_.empty()) {
174         switchChild_->SetTextOn(textOn_);
175     }
176     if (!textOff_.empty()) {
177         switchChild_->SetTextOff(textOff_);
178     }
179     RefPtr<SwitchTheme> theme = GetTheme<SwitchTheme>();
180     if (switchChild_->GetShowText()) {
181         return;
182     }
183     if (boxComponent_ && boxComponent_->GetHeightDimension().Value() < 0.0 && theme) {
184         boxComponent_->SetHeight(theme->GetHeight().Value(), theme->GetHeight().Unit());
185     }
186     if (boxComponent_ && boxComponent_->GetWidthDimension().Value() < 0.0 && theme) {
187         boxComponent_->SetWidth(theme->GetWidth().Value(), theme->GetWidth().Unit());
188     }
189 #ifndef WEARABLE_PRODUCT
190     if (declaration_) {
191         auto& multimodalAttr =
192             static_cast<CommonMultimodalAttribute&>(declaration_->GetAttribute(AttributeTag::COMMON_MULTIMODAL_ATTR));
193         if (multimodalAttr.IsValid() && !multimodalAttr.IsUnavailable() && multimodalAttr.scene == SceneLabel::SWITCH) {
194             switchChild_->SetMultimodalProperties(multimodalAttr);
195         }
196     }
197 #endif
198 }
199 
200 } // namespace OHOS::Ace::Framework
201