• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 "bridge/declarative_frontend/jsview/js_search.h"
17 
18 #include <optional>
19 #include <string>
20 
21 #include "base/log/ace_scoring_log.h"
22 #include "bridge/declarative_frontend/engine/functions/js_function.h"
23 #include "bridge/declarative_frontend/jsview/js_text_editable_controller.h"
24 #include "bridge/declarative_frontend/jsview/js_textfield.h"
25 #include "bridge/declarative_frontend/jsview/js_textinput.h"
26 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
27 #include "bridge/declarative_frontend/jsview/models/search_model_impl.h"
28 #include "core/components/common/layout/constants.h"
29 #include "core/components/search/search_theme.h"
30 #include "core/components_ng/pattern/search/search_model_ng.h"
31 #include "core/components_ng/pattern/text_field/text_field_model_ng.h"
32 
33 namespace OHOS::Ace {
34 
35 std::unique_ptr<SearchModel> SearchModel::instance_ = nullptr;
36 std::mutex SearchModel::mutex_;
37 
GetInstance()38 SearchModel* SearchModel::GetInstance()
39 {
40     if (!instance_) {
41         std::lock_guard<std::mutex> lock(mutex_);
42         if (!instance_) {
43 #ifdef NG_BUILD
44             instance_.reset(new NG::SearchModelNG());
45 #else
46             if (Container::IsCurrentUseNewPipeline()) {
47                 instance_.reset(new NG::SearchModelNG());
48             } else {
49                 instance_.reset(new Framework::SearchModelImpl());
50             }
51 #endif
52         }
53     }
54     return instance_.get();
55 }
56 
57 } // namespace OHOS::Ace
58 
59 namespace OHOS::Ace::Framework {
60 namespace {
61 const std::vector<TextAlign> TEXT_ALIGNS = { TextAlign::START, TextAlign::CENTER, TextAlign::END };
62 } // namespace
63 
JSBind(BindingTarget globalObj)64 void JSSearch::JSBind(BindingTarget globalObj)
65 {
66     JSClass<JSSearch>::Declare("Search");
67     MethodOptions opt = MethodOptions::NONE;
68 
69     JSClass<JSSearch>::StaticMethod("create", &JSSearch::Create, opt);
70     JSClass<JSSearch>::StaticMethod("searchButton", &JSSearch::SetSearchButton, opt);
71     JSClass<JSSearch>::StaticMethod("searchIcon", &JSSearch::SetSearchIcon, opt);
72     JSClass<JSSearch>::StaticMethod("cancelButton", &JSSearch::SetCancelButton, opt);
73     JSClass<JSSearch>::StaticMethod("fontColor", &JSSearch::SetTextColor, opt);
74     JSClass<JSSearch>::StaticMethod("caretStyle", &JSSearch::SetCaret, opt);
75     JSClass<JSSearch>::StaticMethod("placeholderColor", &JSSearch::SetPlaceholderColor, opt);
76     JSClass<JSSearch>::StaticMethod("placeholderFont", &JSSearch::SetPlaceholderFont, opt);
77     JSClass<JSSearch>::StaticMethod("textFont", &JSSearch::SetTextFont, opt);
78     JSClass<JSSearch>::StaticMethod("textAlign", &JSSearch::SetTextAlign, opt);
79     JSClass<JSSearch>::StaticMethod("onSubmit", &JSSearch::OnSubmit, opt);
80     JSClass<JSSearch>::StaticMethod("onChange", &JSSearch::OnChange, opt);
81     JSClass<JSSearch>::StaticMethod("onTextSelectionChange", &JSSearch::SetOnTextSelectionChange);
82     JSClass<JSSearch>::StaticMethod("onContentScroll", &JSSearch::SetOnScroll);
83     JSClass<JSSearch>::StaticMethod("border", &JSSearch::JsBorder);
84     JSClass<JSSearch>::StaticMethod("borderWidth", &JSSearch::JsBorderWidth);
85     JSClass<JSSearch>::StaticMethod("borderColor", &JSSearch::JsBorderColor);
86     JSClass<JSSearch>::StaticMethod("borderStyle", &JSSearch::JsBorderStyle);
87     JSClass<JSSearch>::StaticMethod("borderRadius", &JSSearch::JsBorderRadius);
88     JSClass<JSSearch>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
89     JSClass<JSSearch>::StaticMethod("height", &JSSearch::SetHeight);
90     JSClass<JSSearch>::StaticMethod("width", &JSViewAbstract::JsWidth);
91     JSClass<JSSearch>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
92     JSClass<JSSearch>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
93     JSClass<JSSearch>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
94     JSClass<JSSearch>::StaticMethod("requestKeyboardOnFocus", &JSSearch::SetEnableKeyboardOnFocus);
95     JSClass<JSSearch>::StaticMethod("enableKeyboardOnFocus", &JSSearch::SetEnableKeyboardOnFocus);
96     JSClass<JSSearch>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
97     JSClass<JSSearch>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
98     JSClass<JSSearch>::StaticMethod("onCopy", &JSSearch::SetOnCopy);
99     JSClass<JSSearch>::StaticMethod("onCut", &JSSearch::SetOnCut);
100     JSClass<JSSearch>::StaticMethod("onPaste", &JSSearch::SetOnPaste);
101     JSClass<JSSearch>::StaticMethod("copyOption", &JSSearch::SetCopyOption);
102     JSClass<JSSearch>::StaticMethod("textMenuOptions", &JSSearch::JsMenuOptionsExtension);
103     JSClass<JSSearch>::StaticMethod("selectionMenuHidden", &JSSearch::SetSelectionMenuHidden);
104     JSClass<JSSearch>::StaticMethod("customKeyboard", &JSSearch::SetCustomKeyboard);
105     JSClass<JSSearch>::StaticMethod("maxLength", &JSSearch::SetMaxLength);
106     JSClass<JSSearch>::StaticMethod("type", &JSSearch::SetType);
107     JSClass<JSSearch>::InheritAndBind<JSViewAbstract>(globalObj);
108 }
109 
ParseSearchValueObject(const JSCallbackInfo & info,const JSRef<JSVal> & changeEventVal)110 void ParseSearchValueObject(const JSCallbackInfo& info, const JSRef<JSVal>& changeEventVal)
111 {
112     CHECK_NULL_VOID(changeEventVal->IsFunction());
113 
114     JsEventCallback<void(const std::string&)> onChangeEvent(
115         info.GetExecutionContext(), JSRef<JSFunc>::Cast(changeEventVal));
116     SearchModel::GetInstance()->SetOnChangeEvent(std::move(onChangeEvent));
117 }
118 
Create(const JSCallbackInfo & info)119 void JSSearch::Create(const JSCallbackInfo& info)
120 {
121     std::optional<std::string> key;
122     std::optional<std::string> tip;
123     std::optional<std::string> src;
124     JSTextEditableController* jsController = nullptr;
125     JSRef<JSVal> changeEventVal;
126     if (info[0]->IsObject()) {
127         auto param = JSRef<JSObject>::Cast(info[0]);
128         std::string placeholder;
129         if (param->GetProperty("placeholder")->IsUndefined()) {
130             tip = "";
131         }
132         if (ParseJsString(param->GetProperty("placeholder"), placeholder)) {
133             tip = placeholder;
134         }
135         std::string text;
136         JSRef<JSVal> textValue = param->GetProperty("value");
137         if (textValue->IsObject()) {
138             JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(textValue);
139             changeEventVal = valueObj->GetProperty("changeEvent");
140             if (changeEventVal->IsFunction()) {
141                 textValue = valueObj->GetProperty("value");
142             }
143             if (ParseJsString(textValue, text)) {
144                 key = text;
145             }
146         } else if (param->HasProperty("value") && textValue->IsUndefined()) {
147             key = "";
148         } else {
149             if (ParseJsString(textValue, text)) {
150                 key = text;
151             }
152         }
153         std::string icon;
154         if (ParseJsString(param->GetProperty("icon"), icon)) {
155             src = icon;
156         }
157         auto controllerObj = param->GetProperty("controller");
158         if (!controllerObj->IsUndefined() && !controllerObj->IsNull()) {
159             jsController = JSRef<JSObject>::Cast(controllerObj)->Unwrap<JSTextEditableController>();
160         }
161     }
162     auto controller = SearchModel::GetInstance()->Create(key, tip, src);
163     if (jsController) {
164         jsController->SetController(controller);
165     }
166     SearchModel::GetInstance()->SetFocusable(true);
167     SearchModel::GetInstance()->SetFocusNode(true);
168     if (!changeEventVal->IsUndefined() && changeEventVal->IsFunction()) {
169         ParseSearchValueObject(info, changeEventVal);
170     }
171 }
172 
SetEnableKeyboardOnFocus(const JSCallbackInfo & info)173 void JSSearch::SetEnableKeyboardOnFocus(const JSCallbackInfo& info)
174 {
175     if (info[0]->IsUndefined() || !info[0]->IsBoolean()) {
176         SearchModel::GetInstance()->RequestKeyboardOnFocus(true);
177         return;
178     }
179     SearchModel::GetInstance()->RequestKeyboardOnFocus(info[0]->ToBoolean());
180 }
181 
SetSearchButton(const JSCallbackInfo & info)182 void JSSearch::SetSearchButton(const JSCallbackInfo& info)
183 {
184     auto theme = GetTheme<SearchTheme>();
185     CHECK_NULL_VOID(theme);
186     std::string buttonValue;
187     if (!ParseJsString(info[0], buttonValue)) {
188         return;
189     }
190     SearchModel::GetInstance()->SetSearchButton(buttonValue);
191     SearchModel::GetInstance()->SetSearchButtonFontSize(theme->GetFontSize());
192     SearchModel::GetInstance()->SetSearchButtonFontColor(theme->GetSearchButtonTextColor());
193 
194     if (info[1]->IsObject()) {
195         auto param = JSRef<JSObject>::Cast(info[1]);
196 
197         // set button font size, unit FP
198         auto fontSize = param->GetProperty("fontSize");
199         CalcDimension size = theme->GetFontSize();
200         if (ParseJsDimensionVpNG(fontSize, size) && size.Unit() != DimensionUnit::PERCENT &&
201             GreatOrEqual(size.Value(), 0.0)) {
202             ParseJsDimensionFp(fontSize, size);
203         } else {
204             size = theme->GetFontSize();
205         }
206         SearchModel::GetInstance()->SetSearchButtonFontSize(size);
207 
208         // set font color
209         Color fontColor;
210         auto fontColorProp = param->GetProperty("fontColor");
211         if (fontColorProp->IsUndefined() || fontColorProp->IsNull() || !ParseJsColor(fontColorProp, fontColor)) {
212             fontColor = theme->GetSearchButtonTextColor();
213         }
214         SearchModel::GetInstance()->SetSearchButtonFontColor(fontColor);
215     }
216 }
217 
SetSearchIcon(const JSCallbackInfo & info)218 void JSSearch::SetSearchIcon(const JSCallbackInfo& info)
219 {
220     if (info[0]->IsObject()) {
221         auto param = JSRef<JSObject>::Cast(info[0]);
222         auto theme = GetTheme<SearchTheme>();
223         CHECK_NULL_VOID(theme);
224 
225         // set icon size
226         CalcDimension size;
227         auto sizeProp = param->GetProperty("size");
228         if (!sizeProp->IsUndefined() && !sizeProp->IsNull() && ParseJsDimensionVpNG(sizeProp, size)) {
229             if (LessNotEqual(size.Value(), 0.0) || size.Unit() == DimensionUnit::PERCENT) {
230                 size = theme->GetIconHeight();
231             }
232         } else {
233             size = theme->GetIconHeight();
234         }
235         SearchModel::GetInstance()->SetSearchIconSize(size);
236 
237         // set icon src
238         std::string src;
239         auto srcPathProp = param->GetProperty("src");
240         if (srcPathProp->IsUndefined() || srcPathProp->IsNull() || !ParseJsMedia(srcPathProp, src)) {
241             src = "";
242         }
243         std::string bundleName;
244         std::string moduleName;
245         GetJsMediaBundleInfo(srcPathProp, bundleName, moduleName);
246         SearchModel::GetInstance()->SetSearchSrcPath(src, bundleName, moduleName);
247 
248         // set icon color
249         Color colorVal;
250         auto colorProp = param->GetProperty("color");
251         if (!colorProp->IsUndefined() && !colorProp->IsNull() && ParseJsColor(colorProp, colorVal)) {
252             SearchModel::GetInstance()->SetSearchIconColor(colorVal);
253         }
254     }
255 }
256 
ConvertStrToCancelButtonStyle(const std::string & value)257 static CancelButtonStyle ConvertStrToCancelButtonStyle(const std::string& value)
258 {
259     if (value == "CONSTANT") {
260         return CancelButtonStyle::CONSTANT;
261     } else if (value == "INVISIBLE") {
262         return CancelButtonStyle::INVISIBLE;
263     } else {
264         return CancelButtonStyle::INPUT;
265     }
266 }
267 
SetCancelButton(const JSCallbackInfo & info)268 void JSSearch::SetCancelButton(const JSCallbackInfo& info)
269 {
270     if (!info[0]->IsObject()) {
271         return;
272     }
273     auto param = JSRef<JSObject>::Cast(info[0]);
274     auto theme = GetTheme<SearchTheme>();
275     CHECK_NULL_VOID(theme);
276 
277     // set style
278     std::string styleStr;
279     CancelButtonStyle cancelButtonStyle;
280     auto styleProp = param->GetProperty("style");
281     if (!styleProp->IsUndefined() && !styleProp->IsNull() && ParseJsString(styleProp, styleStr)) {
282         cancelButtonStyle = ConvertStrToCancelButtonStyle(styleStr);
283     } else {
284         cancelButtonStyle = theme->GetCancelButtonStyle();
285     }
286     SearchModel::GetInstance()->SetCancelButtonStyle(cancelButtonStyle);
287 
288     auto iconProp = param->GetProperty("icon");
289     if (iconProp->IsUndefined() || iconProp->IsNull()) {
290         SearchModel::GetInstance()->SetCancelIconSize(theme->GetIconHeight());
291         SearchModel::GetInstance()->SetCancelIconColor(theme->GetSearchIconColor());
292         SearchModel::GetInstance()->SetRightIconSrcPath("");
293     } else {
294         SetIconStyle(info);
295     }
296 }
297 
SetIconStyle(const JSCallbackInfo & info)298 void JSSearch::SetIconStyle(const JSCallbackInfo& info)
299 {
300     if (!info[0]->IsObject()) {
301         return;
302     }
303     auto param = JSRef<JSObject>::Cast(info[0]);
304     auto iconJsVal = param->GetProperty("icon");
305     if (!iconJsVal->IsObject()) {
306         return;
307     }
308     auto iconParam = JSRef<JSObject>::Cast(iconJsVal);
309     // set icon size
310     CalcDimension iconSize;
311     auto iconSizeProp = iconParam->GetProperty("size");
312     auto theme = GetTheme<SearchTheme>();
313     if (!iconSizeProp->IsUndefined() && !iconSizeProp->IsNull() && ParseJsDimensionVpNG(iconSizeProp, iconSize)) {
314         if (LessNotEqual(iconSize.Value(), 0.0) || iconSize.Unit() == DimensionUnit::PERCENT) {
315             iconSize = theme->GetIconHeight();
316         }
317     } else {
318         iconSize = theme->GetIconHeight();
319     }
320     SearchModel::GetInstance()->SetCancelIconSize(iconSize);
321 
322     // set icon src
323     std::string iconSrc;
324     auto iconSrcProp = iconParam->GetProperty("src");
325     if (iconSrcProp->IsUndefined() || iconSrcProp->IsNull() || !ParseJsMedia(iconSrcProp, iconSrc)) {
326         iconSrc = "";
327     }
328     SearchModel::GetInstance()->SetRightIconSrcPath(iconSrc);
329 
330     // set icon color
331     Color iconColor;
332     auto iconColorProp = iconParam->GetProperty("color");
333     if (!iconColorProp->IsUndefined() && !iconColorProp->IsNull() && ParseJsColor(iconColorProp, iconColor)) {
334         SearchModel::GetInstance()->SetCancelIconColor(iconColor);
335     }
336 }
337 
SetTextColor(const JSCallbackInfo & info)338 void JSSearch::SetTextColor(const JSCallbackInfo& info)
339 {
340     auto theme = GetTheme<SearchTheme>();
341     CHECK_NULL_VOID(theme);
342 
343     auto value = JSRef<JSVal>::Cast(info[0]);
344     Color colorVal;
345     if (!ParseJsColor(value, colorVal)) {
346         colorVal = theme->GetTextColor();
347     }
348     SearchModel::GetInstance()->SetTextColor(colorVal);
349 }
350 
SetCaret(const JSCallbackInfo & info)351 void JSSearch::SetCaret(const JSCallbackInfo& info)
352 {
353     if (info[0]->IsObject()) {
354         auto param = JSRef<JSObject>::Cast(info[0]);
355         auto textFieldTheme = GetTheme<TextFieldTheme>();
356         CHECK_NULL_VOID(textFieldTheme);
357 
358         // set caret width
359         CalcDimension caretWidth = textFieldTheme->GetCursorWidth();
360         auto caretWidthProp = param->GetProperty("width");
361         if (!ParseJsDimensionVpNG(caretWidthProp, caretWidth, false) || LessNotEqual(caretWidth.Value(), 0.0)) {
362             caretWidth = textFieldTheme->GetCursorWidth();
363         }
364         SearchModel::GetInstance()->SetCaretWidth(caretWidth);
365 
366         // set caret color
367         Color caretColor;
368         auto caretColorProp = param->GetProperty("color");
369         if (caretColorProp->IsUndefined() || caretColorProp->IsNull() || !ParseJsColor(caretColorProp, caretColor)) {
370             caretColor = textFieldTheme->GetCursorColor();
371         }
372         SearchModel::GetInstance()->SetCaretColor(caretColor);
373     }
374 }
375 
SetPlaceholderColor(const JSCallbackInfo & info)376 void JSSearch::SetPlaceholderColor(const JSCallbackInfo& info)
377 {
378     auto value = JSRef<JSVal>::Cast(info[0]);
379     Color colorVal;
380     if (!ParseJsColor(value, colorVal)) {
381         auto theme = GetTheme<SearchTheme>();
382         CHECK_NULL_VOID(theme);
383         colorVal = theme->GetPlaceholderColor();
384     }
385     SearchModel::GetInstance()->SetPlaceholderColor(colorVal);
386 }
387 
SetPlaceholderFont(const JSCallbackInfo & info)388 void JSSearch::SetPlaceholderFont(const JSCallbackInfo& info)
389 {
390     if (!info[0]->IsObject()) {
391         return;
392     }
393     auto param = JSRef<JSObject>::Cast(info[0]);
394     auto theme = GetTheme<SearchTheme>();
395     CHECK_NULL_VOID(theme);
396     auto themeFontSize = theme->GetFontSize();
397     Font font;
398     auto fontSize = param->GetProperty("size");
399     if (fontSize->IsNull() || fontSize->IsUndefined()) {
400         font.fontSize = themeFontSize;
401     } else {
402         auto versionTenOrLarger = Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN);
403         CalcDimension size;
404         if ((versionTenOrLarger ? ParseJsDimensionVpNG(fontSize, size) : ParseJsDimensionVp(fontSize, size)) &&
405             size.Unit() != DimensionUnit::PERCENT) {
406             ParseJsDimensionFp(fontSize, size);
407             font.fontSize = size;
408         } else {
409             font.fontSize = themeFontSize;
410         }
411     }
412 
413     auto weight = param->GetProperty("weight");
414     if (!weight->IsNull()) {
415         std::string weightVal;
416         if (weight->IsNumber()) {
417             weightVal = std::to_string(weight->ToNumber<int32_t>());
418         } else {
419             ParseJsString(weight, weightVal);
420         }
421         font.fontWeight = ConvertStrToFontWeight(weightVal);
422     }
423 
424     auto family = param->GetProperty("family");
425     if (!family->IsNull() && family->IsString()) {
426         auto familyVal = family->ToString();
427         font.fontFamilies = ConvertStrToFontFamilies(familyVal);
428     }
429 
430     auto style = param->GetProperty("style");
431     if (!style->IsNull() && style->IsNumber()) {
432         FontStyle styleVal = static_cast<FontStyle>(style->ToNumber<int32_t>());
433         font.fontStyle = styleVal;
434     }
435     SearchModel::GetInstance()->SetPlaceholderFont(font);
436 }
437 
SetTextFont(const JSCallbackInfo & info)438 void JSSearch::SetTextFont(const JSCallbackInfo& info)
439 {
440     if (info.Length() < 1 || !info[0]->IsObject()) {
441         return;
442     }
443     auto param = JSRef<JSObject>::Cast(info[0]);
444     auto theme = GetTheme<SearchTheme>();
445     CHECK_NULL_VOID(theme);
446     auto themeFontSize = theme->GetFontSize();
447     Font font;
448     auto fontSize = param->GetProperty("size");
449     CalcDimension size = themeFontSize;
450     if (ParseJsDimensionVpNG(fontSize, size) && size.Unit() != DimensionUnit::PERCENT &&
451         GreatOrEqual(size.Value(), 0.0)) {
452         ParseJsDimensionFp(fontSize, size);
453     } else {
454         size = themeFontSize;
455     }
456     font.fontSize = size;
457 
458     auto weight = param->GetProperty("weight");
459     if (!weight->IsNull()) {
460         std::string weightVal;
461         if (weight->IsNumber()) {
462             weightVal = std::to_string(weight->ToNumber<int32_t>());
463         } else {
464             ParseJsString(weight, weightVal);
465         }
466         font.fontWeight = ConvertStrToFontWeight(weightVal);
467     }
468 
469     auto family = param->GetProperty("family");
470     if (!family->IsNull() && family->IsString()) {
471         auto familyVal = family->ToString();
472         font.fontFamilies = ConvertStrToFontFamilies(familyVal);
473     }
474 
475     auto style = param->GetProperty("style");
476     if (!style->IsNull() && style->IsNumber()) {
477         FontStyle styleVal = static_cast<FontStyle>(style->ToNumber<int32_t>());
478         font.fontStyle = styleVal;
479     }
480     SearchModel::GetInstance()->SetTextFont(font);
481 }
482 
SetTextAlign(int32_t value)483 void JSSearch::SetTextAlign(int32_t value)
484 {
485     if (value >= 0 && value < static_cast<int32_t>(TEXT_ALIGNS.size())) {
486         SearchModel::GetInstance()->SetTextAlign(TEXT_ALIGNS[value]);
487     }
488 }
489 
JsBorder(const JSCallbackInfo & info)490 void JSSearch::JsBorder(const JSCallbackInfo& info)
491 {
492     JSViewAbstract::JsBorder(info);
493     if (!info[0]->IsObject()) {
494         return;
495     }
496     RefPtr<Decoration> decoration = nullptr;
497     JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
498     auto valueWidth = object->GetProperty("width");
499     if (!valueWidth->IsUndefined()) {
500         ParseBorderWidth(valueWidth);
501     }
502     auto valueColor = object->GetProperty("color");
503     if (!valueColor->IsUndefined()) {
504         ParseBorderColor(valueColor);
505     }
506     auto valueRadius = object->GetProperty("radius");
507     if (!valueRadius->IsUndefined()) {
508         ParseBorderRadius(valueRadius);
509     }
510     auto valueStyle = object->GetProperty("style");
511     if (!valueStyle->IsUndefined()) {
512         ParseBorderStyle(valueStyle);
513     }
514     SearchModel::GetInstance()->SetBackBorder();
515     info.ReturnSelf();
516 }
517 
JsBorderWidth(const JSCallbackInfo & info)518 void JSSearch::JsBorderWidth(const JSCallbackInfo& info)
519 {
520     JSViewAbstract::JsBorderWidth(info);
521     if (!info[0]->IsObject() && !info[0]->IsString() && !info[0]->IsNumber()) {
522         return;
523     }
524     SearchModel::GetInstance()->SetBackBorder();
525 }
526 
JsBorderColor(const JSCallbackInfo & info)527 void JSSearch::JsBorderColor(const JSCallbackInfo& info)
528 {
529     JSViewAbstract::JsBorderColor(info);
530     if (!info[0]->IsObject() && !info[0]->IsString() && !info[0]->IsNumber()) {
531         return;
532     }
533     SearchModel::GetInstance()->SetBackBorder();
534 }
535 
JsBorderStyle(const JSCallbackInfo & info)536 void JSSearch::JsBorderStyle(const JSCallbackInfo& info)
537 {
538     JSViewAbstract::JsBorderStyle(info);
539     if (!info[0]->IsObject() && !info[0]->IsNumber()) {
540         return;
541     }
542     SearchModel::GetInstance()->SetBackBorder();
543 }
544 
JsBorderRadius(const JSCallbackInfo & info)545 void JSSearch::JsBorderRadius(const JSCallbackInfo& info)
546 {
547     JSViewAbstract::JsBorderRadius(info);
548     if (!info[0]->IsObject() && !info[0]->IsString() && !info[0]->IsNumber()) {
549         return;
550     }
551     SearchModel::GetInstance()->SetBackBorder();
552 }
553 
OnSubmit(const JSCallbackInfo & info)554 void JSSearch::OnSubmit(const JSCallbackInfo& info)
555 {
556     CHECK_NULL_VOID(info[0]->IsFunction());
557     JsEventCallback<void(const std::string&)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(info[0]));
558     SearchModel::GetInstance()->SetOnSubmit(std::move(callback));
559 }
560 
OnChange(const JSCallbackInfo & info)561 void JSSearch::OnChange(const JSCallbackInfo& info)
562 {
563     CHECK_NULL_VOID(info[0]->IsFunction());
564     JsEventCallback<void(const std::string&)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(info[0]));
565     SearchModel::GetInstance()->SetOnChange(std::move(callback));
566 }
567 
SetOnTextSelectionChange(const JSCallbackInfo & info)568 void JSSearch::SetOnTextSelectionChange(const JSCallbackInfo& info)
569 {
570     CHECK_NULL_VOID(info[0]->IsFunction());
571     JsEventCallback<void(int32_t, int32_t)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(info[0]));
572     SearchModel::GetInstance()->SetOnTextSelectionChange(std::move(callback));
573 }
574 
SetOnScroll(const JSCallbackInfo & info)575 void JSSearch::SetOnScroll(const JSCallbackInfo& info)
576 {
577     CHECK_NULL_VOID(info[0]->IsFunction());
578     JsEventCallback<void(float, float)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(info[0]));
579     SearchModel::GetInstance()->SetOnScroll(std::move(callback));
580 }
581 
SetHeight(const JSCallbackInfo & info)582 void JSSearch::SetHeight(const JSCallbackInfo& info)
583 {
584     JSViewAbstract::JsHeight(info);
585     CalcDimension value;
586     auto versionTenOrLarger = Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN);
587     if (versionTenOrLarger ? !ParseJsDimensionVpNG(info[0], value) : !ParseJsDimensionVp(info[0], value)) {
588         return;
589     }
590     if (LessNotEqual(value.Value(), 0.0)) {
591         value.SetValue(0.0);
592     }
593     SearchModel::GetInstance()->SetHeight(value);
594 }
595 
SetOnCopy(const JSCallbackInfo & info)596 void JSSearch::SetOnCopy(const JSCallbackInfo& info)
597 {
598     CHECK_NULL_VOID(info[0]->IsFunction());
599     JsEventCallback<void(const std::string&)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(info[0]));
600     SearchModel::GetInstance()->SetOnCopy(std::move(callback));
601 }
602 
SetOnCut(const JSCallbackInfo & info)603 void JSSearch::SetOnCut(const JSCallbackInfo& info)
604 {
605     CHECK_NULL_VOID(info[0]->IsFunction());
606     JsEventCallback<void(const std::string&)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(info[0]));
607     SearchModel::GetInstance()->SetOnCut(std::move(callback));
608 }
609 
CreateJSTextCommonEvent(NG::TextCommonEvent & event)610 JSRef<JSVal> JSSearch::CreateJSTextCommonEvent(NG::TextCommonEvent& event)
611 {
612     JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
613     objectTemplate->SetInternalFieldCount(1);
614     JSRef<JSObject> object = objectTemplate->NewInstance();
615     object->SetPropertyObject("preventDefault", JSRef<JSFunc>::New<FunctionCallback>(JsPreventDefault));
616     object->Wrap<NG::TextCommonEvent>(&event);
617     return JSRef<JSVal>::Cast(object);
618 }
619 
SetOnPaste(const JSCallbackInfo & info)620 void JSSearch::SetOnPaste(const JSCallbackInfo& info)
621 {
622     CHECK_NULL_VOID(info[0]->IsFunction());
623     auto jsTextFunc = AceType::MakeRefPtr<JsCitedEventFunction<NG::TextCommonEvent, 2>>(
624         JSRef<JSFunc>::Cast(info[0]), CreateJSTextCommonEvent);
625 
626     auto onPaste = [execCtx = info.GetExecutionContext(), func = std::move(jsTextFunc)](
627                        const std::string& val, NG::TextCommonEvent& info) {
628         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
629         ACE_SCORING_EVENT("onPaste");
630         func->Execute(val, info);
631     };
632     SearchModel::GetInstance()->SetOnPasteWithEvent(std::move(onPaste));
633 }
634 
SetCopyOption(const JSCallbackInfo & info)635 void JSSearch::SetCopyOption(const JSCallbackInfo& info)
636 {
637     if (info.Length() == 0) {
638         return;
639     }
640     if (info[0]->IsUndefined()) {
641         SearchModel::GetInstance()->SetCopyOption(CopyOptions::Local);
642         return;
643     }
644     auto copyOptions = CopyOptions::None;
645     if (info[0]->IsNumber()) {
646         auto emunNumber = info[0]->ToNumber<int>();
647         copyOptions = static_cast<CopyOptions>(emunNumber);
648     }
649     SearchModel::GetInstance()->SetCopyOption(copyOptions);
650 }
651 
JsMenuOptionsExtension(const JSCallbackInfo & info)652 void JSSearch::JsMenuOptionsExtension(const JSCallbackInfo& info)
653 {
654     if (info[0]->IsArray()) {
655         std::vector<NG::MenuOptionsParam> menuOptionsItems;
656         JSViewAbstract::ParseMenuOptions(info, JSRef<JSArray>::Cast(info[0]), menuOptionsItems);
657         SearchModel::GetInstance()->SetMenuOptionItems(std::move(menuOptionsItems));
658     }
659 }
660 
SetSelectionMenuHidden(const JSCallbackInfo & info)661 void JSSearch::SetSelectionMenuHidden(const JSCallbackInfo& info)
662 {
663     if (info[0]->IsUndefined() || !info[0]->IsBoolean()) {
664         SearchModel::GetInstance()->SetSelectionMenuHidden(false);
665         return;
666     }
667     SearchModel::GetInstance()->SetSelectionMenuHidden(info[0]->ToBoolean());
668 }
669 
SetCustomKeyboard(const JSCallbackInfo & info)670 void JSSearch::SetCustomKeyboard(const JSCallbackInfo& info)
671 {
672     if (info.Length() > 0 && (info[0]->IsUndefined() || info[0]->IsNull())) {
673         SearchModel::GetInstance()->SetCustomKeyboard(nullptr);
674         return;
675     }
676     if (info.Length() < 1 || !info[0]->IsObject()) {
677         return;
678     }
679     std::function<void()> buildFunc;
680     if (JSTextField::ParseJsCustomKeyboardBuilder(info, 0, buildFunc)) {
681         SearchModel::GetInstance()->SetCustomKeyboard(std::move(buildFunc));
682     }
683 }
684 
SetType(const JSCallbackInfo & info)685 void JSSearch::SetType(const JSCallbackInfo& info)
686 {
687     if (info.Length() < 1) {
688         return;
689     }
690     if (info[0]->IsUndefined()) {
691         SearchModel::GetInstance()->SetType(TextInputType::UNSPECIFIED);
692         return;
693     }
694     if (!info[0]->IsNumber()) {
695         return;
696     }
697     TextInputType textInputType = static_cast<TextInputType>(info[0]->ToNumber<int32_t>());
698     SearchModel::GetInstance()->SetType(textInputType);
699 }
700 
JSBind(BindingTarget globalObj)701 void JSSearchController::JSBind(BindingTarget globalObj)
702 {
703     JSClass<JSTextEditableController>::Declare("SearchController");
704     JSTextEditableController::JSBind(globalObj);
705 }
706 
SetMaxLength(const JSCallbackInfo & info)707 void JSSearch::SetMaxLength(const JSCallbackInfo& info)
708 {
709     int32_t maxLength = 0;
710     if (info[0]->IsUndefined()) {
711         SearchModel::GetInstance()->ResetMaxLength();
712         return;
713     } else if (!info[0]->IsNumber()) {
714         SearchModel::GetInstance()->ResetMaxLength();
715         return;
716     }
717     maxLength = info[0]->ToNumber<int32_t>();
718     if (GreatOrEqual(maxLength, 0)) {
719         SearchModel::GetInstance()->SetMaxLength(maxLength);
720     } else {
721         SearchModel::GetInstance()->ResetMaxLength();
722     }
723 }
724 } // namespace OHOS::Ace::Framework
725