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 "core/components/declaration/search/search_declaration.h"
17
18 #include "base/utils/string_utils.h"
19 #include "base/utils/system_properties.h"
20 #include "core/components/declaration/common/declaration_constants.h"
21 #include "frameworks/bridge/common/utils/utils.h"
22 #include "frameworks/core/components/search/search_theme.h"
23 #include "frameworks/core/components/text_field/textfield_theme.h"
24
25 namespace OHOS::Ace {
26
27 using namespace Framework;
28
SearchDeclaration()29 SearchDeclaration::SearchDeclaration()
30 {
31 textFieldDeclaration_ = AceType::MakeRefPtr<TextFieldDeclaration>();
32 textFieldDeclaration_->BindPipelineContext(pipelineContext_);
33 textFieldDeclaration_->Init();
34 }
35
InitSpecialized()36 void SearchDeclaration::InitSpecialized()
37 {
38 AddSpecializedAttribute(DeclarationConstants::DEFAULT_SEARCH_ATTR);
39 AddSpecializedStyle(DeclarationConstants::DEFAULT_SEARCH_STYLE);
40 AddSpecializedEvent(DeclarationConstants::DEFAULT_SEARCH_EVENT);
41 AddSpecializedMethod(DeclarationConstants::DEFAULT_SEARCH_METHOD);
42 }
43
InitializeStyle()44 void SearchDeclaration::InitializeStyle()
45 {
46 textFieldDeclaration_->InitializeStyle();
47
48 auto textFieldTheme = GetTheme<TextFieldTheme>();
49 auto searchTheme = GetTheme<SearchTheme>();
50 if (!textFieldTheme || !searchTheme) {
51 // theme is null, set default decoration to text field component
52 RefPtr<Decoration> decoration = AceType::MakeRefPtr<Decoration>();
53 textFieldDeclaration_->SetDecoration(decoration);
54 LOGE("textFieldTheme or searchTheme is null");
55 return;
56 }
57
58 auto& paddingStyle = static_cast<CommonPaddingStyle&>(GetStyle(StyleTag::COMMON_PADDING_STYLE));
59 if (paddingStyle.IsValid()) {
60 paddingStyle.padding = Edge();
61 }
62
63 auto& sizeStyle = static_cast<CommonSizeStyle&>(GetStyle(StyleTag::COMMON_SIZE_STYLE));
64 if (sizeStyle.IsValid()) {
65 sizeStyle.height = searchTheme->GetHeight();
66 }
67
68 SetBackDecoration(nullptr);
69
70 textFieldDeclaration_->SetIconSize(searchTheme->GetIconSize());
71 textFieldDeclaration_->SetIconHotZoneSize(searchTheme->GetCloseIconHotZoneSize());
72 Edge decorationPadding;
73 Dimension leftPadding = searchTheme->GetLeftPadding();
74 Dimension rightPadding = searchTheme->GetRightPadding();
75 if (IsRightToLeft()) {
76 decorationPadding = Edge(rightPadding.Value(), 0.0, leftPadding.Value(), 0.0, leftPadding.Unit());
77 } else {
78 decorationPadding = Edge(leftPadding.Value(), 0.0, rightPadding.Value(), 0.0, leftPadding.Unit());
79 }
80 auto textFieldDecoration = textFieldDeclaration_->GetDecoration();
81 if (textFieldDecoration) {
82 textFieldDecoration->SetPadding(decorationPadding);
83 textFieldDecoration->SetBorderRadius(searchTheme->GetBorderRadius());
84 textFieldDeclaration_->SetOriginBorder(textFieldDecoration->GetBorder());
85 }
86 textFieldDeclaration_->SetAction(TextInputAction::SEARCH);
87 textFieldDeclaration_->SetWidthReserved(searchTheme->GetTextFieldWidthReserved());
88 textFieldDeclaration_->SetTextColor(searchTheme->GetTextColor());
89 textFieldDeclaration_->SetFocusTextColor(searchTheme->GetFocusTextColor());
90 textFieldDeclaration_->SetPlaceholderColor(searchTheme->GetPlaceholderColor());
91 textFieldDeclaration_->SetFocusPlaceholderColor(searchTheme->GetFocusPlaceholderColor());
92 textFieldDeclaration_->SetBlockRightShade(searchTheme->GetBlockRightShade());
93
94 std::function<void(const std::string&)> submitEvent;
95 SetSubmitEvent(submitEvent);
96 SetTextEditController(textFieldDeclaration_->GetTextEditController());
97 SetCloseIconSize(searchTheme->GetCloseIconSize());
98 SetCloseIconHotZoneHorizontal(searchTheme->GetCloseIconHotZoneSize());
99 SetHoverColor(textFieldTheme->GetHoverColor());
100 SetPressColor(textFieldTheme->GetPressColor());
101 isPaddingChanged_ = true;
102 }
103
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)104 bool SearchDeclaration::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
105 {
106 static const LinearMapNode<void (*)(const std::string&, SearchDeclaration&, TextFieldDeclaration&)>
107 searchAttrOperators[] = {
108 { DOM_AUTO_FOCUS,
109 [](const std::string& val, SearchDeclaration& searchDeclaration,
110 TextFieldDeclaration& textFieldDeclaration) {
111 textFieldDeclaration.SetAutoFocus(StringToBool(val));
112 } },
113 { DOM_SEARCH_HINT,
114 [](const std::string& val, SearchDeclaration& searchDeclaration,
115 TextFieldDeclaration& textFieldDeclaration) { textFieldDeclaration.SetPlaceholder(val); } },
116 { DOM_SEARCH_ICON,
117 [](const std::string& val, SearchDeclaration& searchDeclaration,
118 TextFieldDeclaration& textFieldDeclaration) {
119 if (SystemProperties::GetDeviceType() == DeviceType::TV) {
120 return;
121 }
122 textFieldDeclaration.SetIconImage(val);
123 } },
124 { DOM_SEARCH_BUTTON,
125 [](const std::string& val, SearchDeclaration& searchDeclaration,
126 TextFieldDeclaration& textFieldDeclaration) { searchDeclaration.SetSearchText(val); } },
127 { DOM_INPUT_SELECTED_END,
128 [](const std::string& val, SearchDeclaration& searchDeclaration,
129 TextFieldDeclaration& textFieldDeclaration) {
130 textFieldDeclaration.SetSelectedEnd(StringToInt(val));
131 } },
132 { DOM_INPUT_SELECTED_START,
133 [](const std::string& val, SearchDeclaration& searchDeclaration,
134 TextFieldDeclaration& textFieldDeclaration) {
135 textFieldDeclaration.SetSelectedStart(StringToInt(val));
136 } },
137 { DOM_INPUT_SOFT_KEYBOARD_ENABLED,
138 [](const std::string& val, SearchDeclaration& searchDeclaration,
139 TextFieldDeclaration& textFieldDeclaration) {
140 textFieldDeclaration.SetSoftKeyboardEnabled(StringToBool(val));
141 } },
142 { DOM_SEARCH_VALUE,
143 [](const std::string& val, SearchDeclaration& searchDeclaration,
144 TextFieldDeclaration& textFieldDeclaration) {
145 textFieldDeclaration.SetValue(val);
146 textFieldDeclaration.SetResetToStart(false);
147 } },
148 };
149 auto operatorIter = BinarySearchFindIndex(searchAttrOperators, ArraySize(searchAttrOperators), attr.first.c_str());
150 if (operatorIter != -1) {
151 searchAttrOperators[operatorIter].value(attr.second, *this, *textFieldDeclaration_);
152 return true;
153 }
154 return false;
155 }
156
SetSpecializedStyle(const std::pair<std::string,std::string> & style)157 bool SearchDeclaration::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
158 {
159 // static linear map must be sorted by key.
160 static const LinearMapNode<void (*)(const std::string&, SearchDeclaration&, TextFieldDeclaration&)>
161 searchStyleSize[] = {
162 { DOM_TEXT_ALLOW_SCALE,
163 [](const std::string& val, SearchDeclaration& searchDeclaration,
164 TextFieldDeclaration& textFieldDeclaration) {
165 textFieldDeclaration.GetTextStyle().SetAllowScale(StringToBool(val));
166 } },
167 { DOM_BACKGROUND_COLOR,
168 [](const std::string& val, SearchDeclaration& searchDeclaration,
169 TextFieldDeclaration& textFieldDeclaration) {
170 textFieldDeclaration.SetBgColor(searchDeclaration.ParseColor(val));
171 textFieldDeclaration.SetFocusBgColor(searchDeclaration.ParseColor(val));
172 } },
173 { DOM_CARET_COLOR,
174 [](const std::string& val, SearchDeclaration& searchDeclaration,
175 TextFieldDeclaration& textFieldDeclaration) {
176 textFieldDeclaration.SetCursorColor(searchDeclaration.ParseColor(val));
177 } },
178 { DOM_COLOR,
179 [](const std::string& val, SearchDeclaration& searchDeclaration,
180 TextFieldDeclaration& textFieldDeclaration) {
181 textFieldDeclaration.SetFocusTextColor(searchDeclaration.ParseColor(val));
182 } },
183 { DOM_TEXT_FONT_FAMILY,
184 [](const std::string& val, SearchDeclaration& searchDeclaration,
185 TextFieldDeclaration& textFieldDeclaration) {
186 textFieldDeclaration.GetTextStyle().SetFontFamilies(searchDeclaration.ParseFontFamilies(val));
187 } },
188 { DOM_TEXT_FONT_SIZE,
189 [](const std::string& val, SearchDeclaration& searchDeclaration,
190 TextFieldDeclaration& textFieldDeclaration) {
191 textFieldDeclaration.GetTextStyle().SetFontSize(searchDeclaration.ParseDimension(val));
192 } },
193 { DOM_TEXT_FONT_WEIGHT,
194 [](const std::string& val, SearchDeclaration& searchDeclaration,
195 TextFieldDeclaration& textFieldDeclaration) {
196 textFieldDeclaration.GetTextStyle().SetFontWeight(ConvertStrToFontWeight(val));
197 } },
198 { DOM_PADDING,
199 [](const std::string& val, SearchDeclaration& searchDeclaration,
200 TextFieldDeclaration& textFieldDeclaration) {
201 Edge padding;
202 if (Edge::FromString(val, padding)) {
203 textFieldDeclaration.GetDecoration()->SetPadding(padding);
204 searchDeclaration.isPaddingChanged_ = true;
205 }
206 } },
207 { DOM_PADDING_BOTTOM,
208 [](const std::string& val, SearchDeclaration& searchDeclaration,
209 TextFieldDeclaration& textFieldDeclaration) {
210 auto padding = textFieldDeclaration.GetDecoration()->GetPadding();
211 padding.SetBottom(searchDeclaration.ParseDimension(val));
212 textFieldDeclaration.GetDecoration()->SetPadding(padding);
213 searchDeclaration.isPaddingChanged_ = true;
214 } },
215 { DOM_PADDING_END,
216 [](const std::string& val, SearchDeclaration& searchDeclaration,
217 TextFieldDeclaration& textFieldDeclaration) {
218 auto padding = textFieldDeclaration.GetDecoration()->GetPadding();
219 searchDeclaration.IsRightToLeft() ? padding.SetLeft(searchDeclaration.ParseDimension(val))
220 : padding.SetRight(searchDeclaration.ParseDimension(val));
221 textFieldDeclaration.GetDecoration()->SetPadding(padding);
222 searchDeclaration.isPaddingChanged_ = true;
223 } },
224 { DOM_PADDING_LEFT,
225 [](const std::string& val, SearchDeclaration& searchDeclaration,
226 TextFieldDeclaration& textFieldDeclaration) {
227 auto padding = textFieldDeclaration.GetDecoration()->GetPadding();
228 padding.SetLeft(searchDeclaration.ParseDimension(val));
229 textFieldDeclaration.GetDecoration()->SetPadding(padding);
230 searchDeclaration.isPaddingChanged_ = true;
231 } },
232 { DOM_PADDING_RIGHT,
233 [](const std::string& val, SearchDeclaration& searchDeclaration,
234 TextFieldDeclaration& textFieldDeclaration) {
235 auto padding = textFieldDeclaration.GetDecoration()->GetPadding();
236 padding.SetRight(searchDeclaration.ParseDimension(val));
237 textFieldDeclaration.GetDecoration()->SetPadding(padding);
238 searchDeclaration.isPaddingChanged_ = true;
239 } },
240 { DOM_PADDING_START,
241 [](const std::string& val, SearchDeclaration& searchDeclaration,
242 TextFieldDeclaration& textFieldDeclaration) {
243 auto padding = textFieldDeclaration.GetDecoration()->GetPadding();
244 searchDeclaration.IsRightToLeft() ? padding.SetRight(searchDeclaration.ParseDimension(val))
245 : padding.SetLeft(searchDeclaration.ParseDimension(val));
246 textFieldDeclaration.GetDecoration()->SetPadding(padding);
247 searchDeclaration.isPaddingChanged_ = true;
248 } },
249 { DOM_PADDING_TOP,
250 [](const std::string& val, SearchDeclaration& searchDeclaration,
251 TextFieldDeclaration& textFieldDeclaration) {
252 auto padding = textFieldDeclaration.GetDecoration()->GetPadding();
253 padding.SetTop(searchDeclaration.ParseDimension(val));
254 textFieldDeclaration.GetDecoration()->SetPadding(padding);
255 searchDeclaration.isPaddingChanged_ = true;
256 } },
257 { DOM_INPUT_PLACEHOLDER_COLOR,
258 [](const std::string& val, SearchDeclaration& searchDeclaration,
259 TextFieldDeclaration& textFieldDeclaration) {
260 textFieldDeclaration.SetPlaceholderColor(searchDeclaration.ParseColor(val));
261 } },
262 };
263 auto operatorIter = BinarySearchFindIndex(searchStyleSize, ArraySize(searchStyleSize), style.first.c_str());
264 if (operatorIter != -1) {
265 searchStyleSize[operatorIter].value(style.second, *this, *textFieldDeclaration_);
266 return true;
267 }
268 if (style.first == DOM_BORDER_TOP_LEFT_RADIUS || style.first == DOM_BORDER_TOP_RIGHT_RADIUS ||
269 style.first == DOM_BORDER_BOTTOM_LEFT_RADIUS || style.first == DOM_BORDER_BOTTOM_RIGHT_RADIUS ||
270 style.first == DOM_BORDER_RADIUS) {
271 hasBoxRadius_ = true;
272 }
273 return false;
274 }
275
SetSpecializedEvent(int32_t pageId,const std::string & eventId,const std::string & event)276 bool SearchDeclaration::SetSpecializedEvent(int32_t pageId, const std::string& eventId, const std::string& event)
277 {
278 static const LinearMapNode<void (*)(SearchDeclaration&, TextFieldDeclaration&, const EventMarker&)>
279 eventOperators[] = {
280 { DOM_CHANGE, [](SearchDeclaration& searchDeclaration, TextFieldDeclaration& textFieldDeclaration,
281 const EventMarker& event) { searchDeclaration.SetChangeEventId(event); } },
282 { DOM_INPUT_EVENT_OPTION_SELECT,
283 [](SearchDeclaration& searchDeclaration, TextFieldDeclaration& textFieldDeclaration,
284 const EventMarker& event) { textFieldDeclaration.SetOnOptionsClick(event); } },
285 { DOM_INPUT_EVENT_SEARCH,
286 [](SearchDeclaration& searchDeclaration, TextFieldDeclaration& textFieldDeclaration,
287 const EventMarker& event) { textFieldDeclaration.SetOnSearch(event); } },
288 { DOM_INPUT_EVENT_SELECT_CHANGE,
289 [](SearchDeclaration& searchDeclaration, TextFieldDeclaration& textFieldDeclaration,
290 const EventMarker& event) { textFieldDeclaration.SetOnSelectChange(event); } },
291 { DOM_INPUT_EVENT_SHARE,
292 [](SearchDeclaration& searchDeclaration, TextFieldDeclaration& textFieldDeclaration,
293 const EventMarker& event) { textFieldDeclaration.SetOnShare(event); } },
294 { DOM_SUBMIT, [](SearchDeclaration& searchDeclaration, TextFieldDeclaration& textFieldDeclaration,
295 const EventMarker& event) { searchDeclaration.SetSubmitEventId(event); } },
296 { DOM_INPUT_EVENT_TRANSLATE,
297 [](SearchDeclaration& searchDeclaration, TextFieldDeclaration& textFieldDeclaration,
298 const EventMarker& event) { textFieldDeclaration.SetOnTranslate(event); } },
299 };
300 auto operatorIter = BinarySearchFindIndex(eventOperators, ArraySize(eventOperators), event.c_str());
301 if (operatorIter != -1) {
302 eventOperators[operatorIter].value(*this, *textFieldDeclaration_, EventMarker(eventId, event, pageId));
303 return true;
304 }
305 return false;
306 }
307
CallSpecializedMethod(const std::string & method,const std::string & args)308 void SearchDeclaration::CallSpecializedMethod(const std::string& method, const std::string& args)
309 {
310 textFieldDeclaration_->CallSpecializedMethod(method, args);
311 }
312
OnRequestFocus(bool shouldFocus)313 void SearchDeclaration::OnRequestFocus(bool shouldFocus)
314 {
315 textFieldDeclaration_->OnRequestFocus(shouldFocus);
316 }
317
318 } // namespace OHOS::Ace
319