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