• 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/jsview/js_textfield.h"
23 #include "bridge/declarative_frontend/jsview/js_textinput.h"
24 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
25 #include "bridge/declarative_frontend/jsview/models/search_model_impl.h"
26 #include "core/components/common/layout/constants.h"
27 #include "core/components/search/search_theme.h"
28 #include "core/components_ng/pattern/search/search_model_ng.h"
29 #include "core/components_ng/pattern/text_field/text_field_model_ng.h"
30 
31 namespace OHOS::Ace {
32 
33 std::unique_ptr<SearchModel> SearchModel::instance_ = nullptr;
34 std::mutex SearchModel::mutex_;
35 
GetInstance()36 SearchModel* SearchModel::GetInstance()
37 {
38     if (!instance_) {
39         std::lock_guard<std::mutex> lock(mutex_);
40         if (!instance_) {
41 #ifdef NG_BUILD
42             instance_.reset(new NG::SearchModelNG());
43 #else
44             if (Container::IsCurrentUseNewPipeline()) {
45                 instance_.reset(new NG::SearchModelNG());
46             } else {
47                 instance_.reset(new Framework::SearchModelImpl());
48             }
49 #endif
50         }
51     }
52     return instance_.get();
53 }
54 
55 } // namespace OHOS::Ace
56 
57 namespace OHOS::Ace::Framework {
58 const static int32_t PLATFORM_VERSION_TEN = 10;
59 namespace {
60 const std::vector<TextAlign> TEXT_ALIGNS = { TextAlign::START, TextAlign::CENTER, TextAlign::END };
61 } // namespace
62 
JSBind(BindingTarget globalObj)63 void JSSearch::JSBind(BindingTarget globalObj)
64 {
65     JSClass<JSSearch>::Declare("Search");
66     MethodOptions opt = MethodOptions::NONE;
67 
68     JSClass<JSSearch>::StaticMethod("create", &JSSearch::Create, opt);
69     JSClass<JSSearch>::StaticMethod("searchButton", &JSSearch::SetSearchButton, opt);
70     JSClass<JSSearch>::StaticMethod("searchIcon", &JSSearch::SetSearchIcon, opt);
71     JSClass<JSSearch>::StaticMethod("cancelButton", &JSSearch::SetCancelButton, opt);
72     JSClass<JSSearch>::StaticMethod("fontColor", &JSSearch::SetTextColor, opt);
73     JSClass<JSSearch>::StaticMethod("caretStyle", &JSSearch::SetCaret, opt);
74     JSClass<JSSearch>::StaticMethod("placeholderColor", &JSSearch::SetPlaceholderColor, opt);
75     JSClass<JSSearch>::StaticMethod("placeholderFont", &JSSearch::SetPlaceholderFont, opt);
76     JSClass<JSSearch>::StaticMethod("textFont", &JSSearch::SetTextFont, opt);
77     JSClass<JSSearch>::StaticMethod("textAlign", &JSSearch::SetTextAlign, opt);
78     JSClass<JSSearch>::StaticMethod("onSubmit", &JSSearch::OnSubmit, opt);
79     JSClass<JSSearch>::StaticMethod("onChange", &JSSearch::OnChange, opt);
80     JSClass<JSSearch>::StaticMethod("onTextSelectionChange", &JSSearch::SetOnTextSelectionChange);
81     JSClass<JSSearch>::StaticMethod("onContentScroll", &JSSearch::SetOnScroll);
82     JSClass<JSSearch>::StaticMethod("border", &JSSearch::JsBorder);
83     JSClass<JSSearch>::StaticMethod("borderWidth", &JSSearch::JsBorderWidth);
84     JSClass<JSSearch>::StaticMethod("borderColor", &JSSearch::JsBorderColor);
85     JSClass<JSSearch>::StaticMethod("borderStyle", &JSSearch::JsBorderStyle);
86     JSClass<JSSearch>::StaticMethod("borderRadius", &JSSearch::JsBorderRadius);
87     JSClass<JSSearch>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
88     JSClass<JSSearch>::StaticMethod("height", &JSSearch::SetHeight);
89     JSClass<JSSearch>::StaticMethod("width", &JSViewAbstract::JsWidth);
90     JSClass<JSSearch>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
91     JSClass<JSSearch>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
92     JSClass<JSSearch>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
93     JSClass<JSSearch>::StaticMethod("requestKeyboardOnFocus", &JSSearch::SetEnableKeyboardOnFocus);
94     JSClass<JSSearch>::StaticMethod("enableKeyboardOnFocus", &JSSearch::SetEnableKeyboardOnFocus);
95     JSClass<JSSearch>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
96     JSClass<JSSearch>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
97     JSClass<JSSearch>::StaticMethod("onCopy", &JSSearch::SetOnCopy);
98     JSClass<JSSearch>::StaticMethod("onCut", &JSSearch::SetOnCut);
99     JSClass<JSSearch>::StaticMethod("onPaste", &JSSearch::SetOnPaste);
100     JSClass<JSSearch>::StaticMethod("copyOption", &JSSearch::SetCopyOption);
101     JSClass<JSSearch>::StaticMethod("textMenuOptions", &JSSearch::JsMenuOptionsExtension);
102     JSClass<JSSearch>::StaticMethod("selectionMenuHidden", &JSSearch::SetSelectionMenuHidden);
103     JSClass<JSSearch>::StaticMethod("customKeyboard", &JSSearch::SetCustomKeyboard);
104     JSClass<JSSearch>::InheritAndBind<JSViewAbstract>(globalObj);
105 }
106 
ParseSearchValueObject(const JSCallbackInfo & info,const JSRef<JSVal> & changeEventVal)107 void ParseSearchValueObject(const JSCallbackInfo& info, const JSRef<JSVal>& changeEventVal)
108 {
109     CHECK_NULL_VOID(changeEventVal->IsFunction());
110 
111     JsEventCallback<void(const std::string&)> onChangeEvent(
112         info.GetExecutionContext(), JSRef<JSFunc>::Cast(changeEventVal));
113     SearchModel::GetInstance()->SetOnChangeEvent(std::move(onChangeEvent));
114 }
115 
Create(const JSCallbackInfo & info)116 void JSSearch::Create(const JSCallbackInfo& info)
117 {
118     std::optional<std::string> key;
119     std::optional<std::string> tip;
120     std::optional<std::string> src;
121     JSSearchController* jsController = nullptr;
122     JSRef<JSVal> changeEventVal;
123     if (info[0]->IsObject()) {
124         auto param = JSRef<JSObject>::Cast(info[0]);
125         std::string placeholder;
126         if (param->GetProperty("placeholder")->IsUndefined()) {
127             tip = "";
128         }
129         if (ParseJsString(param->GetProperty("placeholder"), placeholder)) {
130             tip = placeholder;
131         }
132         std::string text;
133         JSRef<JSVal> textValue = param->GetProperty("value");
134         if (textValue->IsObject()) {
135             JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(textValue);
136             changeEventVal = valueObj->GetProperty("changeEvent");
137             if (changeEventVal->IsFunction()) {
138                 textValue = valueObj->GetProperty("value");
139             }
140             if (ParseJsString(textValue, text)) {
141                 key = text;
142             }
143         } else {
144             if (ParseJsString(textValue, text)) {
145                 key = text;
146             }
147         }
148         std::string icon;
149         if (ParseJsString(param->GetProperty("icon"), icon)) {
150             src = icon;
151         }
152         auto controllerObj = param->GetProperty("controller");
153         if (!controllerObj->IsUndefined() && !controllerObj->IsNull()) {
154             jsController = JSRef<JSObject>::Cast(controllerObj)->Unwrap<JSSearchController>();
155         }
156     }
157     auto controller = SearchModel::GetInstance()->Create(key, tip, src);
158     if (jsController) {
159         jsController->SetController(controller);
160     }
161     SearchModel::GetInstance()->SetFocusable(true);
162     SearchModel::GetInstance()->SetFocusNode(true);
163     if (!changeEventVal->IsUndefined() && changeEventVal->IsFunction()) {
164         ParseSearchValueObject(info, changeEventVal);
165     }
166 }
167 
SetEnableKeyboardOnFocus(const JSCallbackInfo & info)168 void JSSearch::SetEnableKeyboardOnFocus(const JSCallbackInfo& info)
169 {
170     if (info.Length() < 1) {
171         LOGW("EnableKeyboardOnFocus should have at least 1 param");
172         return;
173     }
174     if (info[0]->IsUndefined() || !info[0]->IsBoolean()) {
175         LOGI("The info of SetEnableKeyboardOnFocus is not correct, using default");
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_NOLOG(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_NOLOG(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         SearchModel::GetInstance()->SetSearchSrcPath(src);
244 
245         // set icon color
246         Color colorVal;
247         auto colorProp = param->GetProperty("color");
248         if (!colorProp->IsUndefined() && !colorProp->IsNull() && ParseJsColor(colorProp, colorVal)) {
249             SearchModel::GetInstance()->SetSearchIconColor(colorVal);
250         }
251     }
252 }
253 
ConvertStrToCancelButtonStyle(const std::string & value)254 static CancelButtonStyle ConvertStrToCancelButtonStyle(const std::string& value)
255 {
256     if (value == "CONSTANT") {
257         return CancelButtonStyle::CONSTANT;
258     } else if (value == "INVISIBLE") {
259         return CancelButtonStyle::INVISIBLE;
260     } else {
261         return CancelButtonStyle::INPUT;
262     }
263 }
264 
SetCancelButton(const JSCallbackInfo & info)265 void JSSearch::SetCancelButton(const JSCallbackInfo& info)
266 {
267     if (!info[0]->IsObject()) {
268         LOGI("ivalid argvs");
269         return;
270     }
271     auto param = JSRef<JSObject>::Cast(info[0]);
272     auto theme = GetTheme<SearchTheme>();
273     CHECK_NULL_VOID_NOLOG(theme);
274 
275     // set style
276     std::string styleStr;
277     CancelButtonStyle cancelButtonStyle;
278     auto styleProp = param->GetProperty("style");
279     if (!styleProp->IsUndefined() && !styleProp->IsNull() && ParseJsString(styleProp, styleStr)) {
280         cancelButtonStyle = ConvertStrToCancelButtonStyle(styleStr);
281     } else {
282         cancelButtonStyle = theme->GetCancelButtonStyle();
283     }
284     SearchModel::GetInstance()->SetCancelButtonStyle(cancelButtonStyle);
285 
286     auto iconProp = param->GetProperty("icon");
287     if (iconProp->IsUndefined() || iconProp->IsNull()) {
288         LOGI("icon is null");
289         SearchModel::GetInstance()->SetCancelIconSize(theme->GetIconHeight());
290         SearchModel::GetInstance()->SetCancelIconColor(theme->GetSearchIconColor());
291         SearchModel::GetInstance()->SetRightIconSrcPath("");
292     } else {
293         SetIconStyle(info);
294     }
295 }
296 
SetIconStyle(const JSCallbackInfo & info)297 void JSSearch::SetIconStyle(const JSCallbackInfo& info)
298 {
299     if (!info[0]->IsObject()) {
300         return;
301     }
302     auto param = JSRef<JSObject>::Cast(info[0]);
303     auto iconJsVal = param->GetProperty("icon");
304     if (!iconJsVal->IsObject()) {
305         return;
306     }
307     auto iconParam = JSRef<JSObject>::Cast(iconJsVal);
308     // set icon size
309     CalcDimension iconSize;
310     auto iconSizeProp = iconParam->GetProperty("size");
311     auto theme = GetTheme<SearchTheme>();
312     if (!iconSizeProp->IsUndefined() && !iconSizeProp->IsNull() && ParseJsDimensionVpNG(iconSizeProp, iconSize)) {
313         if (LessOrEqual(iconSize.Value(), 0.0) || iconSize.Unit() == DimensionUnit::PERCENT) {
314             iconSize = theme->GetIconHeight();
315         }
316     } else {
317         iconSize = theme->GetIconHeight();
318     }
319     SearchModel::GetInstance()->SetCancelIconSize(iconSize);
320 
321     // set icon src
322     std::string iconSrc;
323     auto iconSrcProp = iconParam->GetProperty("src");
324     if (iconSrcProp->IsUndefined() || iconSrcProp->IsNull() || !ParseJsMedia(iconSrcProp, iconSrc)) {
325         iconSrc = "";
326     }
327     SearchModel::GetInstance()->SetRightIconSrcPath(iconSrc);
328 
329     // set icon color
330     Color iconColor;
331     auto iconColorProp = iconParam->GetProperty("color");
332     if (!iconColorProp->IsUndefined() && !iconColorProp->IsNull() && ParseJsColor(iconColorProp, iconColor)) {
333         SearchModel::GetInstance()->SetCancelIconColor(iconColor);
334     }
335 }
336 
SetTextColor(const JSCallbackInfo & info)337 void JSSearch::SetTextColor(const JSCallbackInfo& info)
338 {
339     auto theme = GetTheme<SearchTheme>();
340     CHECK_NULL_VOID_NOLOG(theme);
341 
342     auto value = JSRef<JSVal>::Cast(info[0]);
343     Color colorVal;
344     if (!ParseJsColor(value, colorVal)) {
345         colorVal = theme->GetTextColor();
346     }
347     SearchModel::GetInstance()->SetTextColor(colorVal);
348 }
349 
SetCaret(const JSCallbackInfo & info)350 void JSSearch::SetCaret(const JSCallbackInfo& info)
351 {
352     if (info[0]->IsObject()) {
353         auto param = JSRef<JSObject>::Cast(info[0]);
354         auto textFieldTheme = GetTheme<TextFieldTheme>();
355         CHECK_NULL_VOID_NOLOG(textFieldTheme);
356 
357         // set caret width
358         CalcDimension caretWidth = textFieldTheme->GetCursorWidth();
359         auto caretWidthProp = param->GetProperty("width");
360         if (!ParseJsDimensionVpNG(caretWidthProp, caretWidth, false) || LessNotEqual(caretWidth.Value(), 0.0)) {
361             caretWidth = textFieldTheme->GetCursorWidth();
362         }
363         SearchModel::GetInstance()->SetCaretWidth(caretWidth);
364 
365         // set caret color
366         Color caretColor;
367         auto caretColorProp = param->GetProperty("color");
368         if (caretColorProp->IsUndefined() || caretColorProp->IsNull() || !ParseJsColor(caretColorProp, caretColor)) {
369             caretColor = textFieldTheme->GetCursorColor();
370         }
371         SearchModel::GetInstance()->SetCaretColor(caretColor);
372     }
373 }
374 
SetPlaceholderColor(const JSCallbackInfo & info)375 void JSSearch::SetPlaceholderColor(const JSCallbackInfo& info)
376 {
377     auto value = JSRef<JSVal>::Cast(info[0]);
378     Color colorVal;
379     if (ParseJsColor(value, colorVal)) {
380         SearchModel::GetInstance()->SetPlaceholderColor(colorVal);
381     }
382 }
383 
SetPlaceholderFont(const JSCallbackInfo & info)384 void JSSearch::SetPlaceholderFont(const JSCallbackInfo& info)
385 {
386     if (!info[0]->IsObject()) {
387         return;
388     }
389     auto param = JSRef<JSObject>::Cast(info[0]);
390     auto theme = GetTheme<SearchTheme>();
391     CHECK_NULL_VOID_NOLOG(theme);
392     auto themeFontSize = theme->GetFontSize();
393     Font font;
394     auto fontSize = param->GetProperty("size");
395     if (fontSize->IsNull() || fontSize->IsUndefined()) {
396         font.fontSize = themeFontSize;
397     } else {
398         auto versionTenOrLarger = PipelineBase::GetCurrentContext() &&
399                                   PipelineBase::GetCurrentContext()->GetMinPlatformVersion() >= PLATFORM_VERSION_TEN;
400         CalcDimension size;
401         if ((versionTenOrLarger ? ParseJsDimensionVpNG(fontSize, size) : ParseJsDimensionVp(fontSize, size)) &&
402             size.Unit() != DimensionUnit::PERCENT) {
403             ParseJsDimensionFp(fontSize, size);
404             font.fontSize = size;
405         } else {
406             font.fontSize = themeFontSize;
407         }
408     }
409 
410     auto weight = param->GetProperty("weight");
411     if (!weight->IsNull()) {
412         std::string weightVal;
413         if (weight->IsNumber()) {
414             weightVal = std::to_string(weight->ToNumber<int32_t>());
415         } else {
416             ParseJsString(weight, weightVal);
417         }
418         font.fontWeight = ConvertStrToFontWeight(weightVal);
419     }
420 
421     auto family = param->GetProperty("family");
422     if (!family->IsNull() && family->IsString()) {
423         auto familyVal = family->ToString();
424         font.fontFamilies = ConvertStrToFontFamilies(familyVal);
425     }
426 
427     auto style = param->GetProperty("style");
428     if (!style->IsNull() && style->IsNumber()) {
429         FontStyle styleVal = static_cast<FontStyle>(style->ToNumber<int32_t>());
430         font.fontStyle = styleVal;
431     }
432     SearchModel::GetInstance()->SetPlaceholderFont(font);
433 }
434 
SetTextFont(const JSCallbackInfo & info)435 void JSSearch::SetTextFont(const JSCallbackInfo& info)
436 {
437     if (info.Length() < 1 || !info[0]->IsObject()) {
438         return;
439     }
440     auto param = JSRef<JSObject>::Cast(info[0]);
441     auto theme = GetTheme<SearchTheme>();
442     CHECK_NULL_VOID_NOLOG(theme);
443     auto themeFontSize = theme->GetFontSize();
444     Font font;
445     auto fontSize = param->GetProperty("size");
446     CalcDimension size = themeFontSize;
447     if (ParseJsDimensionVpNG(fontSize, size) && size.Unit() != DimensionUnit::PERCENT &&
448         GreatOrEqual(size.Value(), 0.0)) {
449         ParseJsDimensionFp(fontSize, size);
450     } else {
451         size = themeFontSize;
452     }
453     font.fontSize = size;
454 
455     auto weight = param->GetProperty("weight");
456     if (!weight->IsNull()) {
457         std::string weightVal;
458         if (weight->IsNumber()) {
459             weightVal = std::to_string(weight->ToNumber<int32_t>());
460         } else {
461             ParseJsString(weight, weightVal);
462         }
463         font.fontWeight = ConvertStrToFontWeight(weightVal);
464     }
465 
466     auto family = param->GetProperty("family");
467     if (!family->IsNull() && family->IsString()) {
468         auto familyVal = family->ToString();
469         font.fontFamilies = ConvertStrToFontFamilies(familyVal);
470     }
471 
472     auto style = param->GetProperty("style");
473     if (!style->IsNull() && style->IsNumber()) {
474         FontStyle styleVal = static_cast<FontStyle>(style->ToNumber<int32_t>());
475         font.fontStyle = styleVal;
476     }
477     SearchModel::GetInstance()->SetTextFont(font);
478 }
479 
SetTextAlign(int32_t value)480 void JSSearch::SetTextAlign(int32_t value)
481 {
482     if (value >= 0 && value < static_cast<int32_t>(TEXT_ALIGNS.size())) {
483         SearchModel::GetInstance()->SetTextAlign(TEXT_ALIGNS[value]);
484     } else {
485         LOGE("the value is error");
486     }
487 }
488 
JsBorder(const JSCallbackInfo & info)489 void JSSearch::JsBorder(const JSCallbackInfo& info)
490 {
491     JSViewAbstract::JsBorder(info);
492     if (!info[0]->IsObject()) {
493         LOGE("args is not a object. %s", info[0]->ToString().c_str());
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         LOGE("args need a string or number or object");
523         return;
524     }
525     SearchModel::GetInstance()->SetBackBorder();
526 }
527 
JsBorderColor(const JSCallbackInfo & info)528 void JSSearch::JsBorderColor(const JSCallbackInfo& info)
529 {
530     JSViewAbstract::JsBorderColor(info);
531     if (!info[0]->IsObject() && !info[0]->IsString() && !info[0]->IsNumber()) {
532         LOGE("args need a string or number or object");
533         return;
534     }
535     SearchModel::GetInstance()->SetBackBorder();
536 }
537 
JsBorderStyle(const JSCallbackInfo & info)538 void JSSearch::JsBorderStyle(const JSCallbackInfo& info)
539 {
540     JSViewAbstract::JsBorderStyle(info);
541     if (!info[0]->IsObject() && !info[0]->IsNumber()) {
542         LOGE("args need a string or number or object");
543         return;
544     }
545     SearchModel::GetInstance()->SetBackBorder();
546 }
547 
JsBorderRadius(const JSCallbackInfo & info)548 void JSSearch::JsBorderRadius(const JSCallbackInfo& info)
549 {
550     JSViewAbstract::JsBorderRadius(info);
551     if (!info[0]->IsObject() && !info[0]->IsString() && !info[0]->IsNumber()) {
552         LOGE("args need a string or number or object");
553         return;
554     }
555     SearchModel::GetInstance()->SetBackBorder();
556 }
557 
OnSubmit(const JSCallbackInfo & info)558 void JSSearch::OnSubmit(const JSCallbackInfo& info)
559 {
560     CHECK_NULL_VOID(info[0]->IsFunction());
561     JsEventCallback<void(const std::string&)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(info[0]));
562     SearchModel::GetInstance()->SetOnSubmit(std::move(callback));
563 }
564 
OnChange(const JSCallbackInfo & info)565 void JSSearch::OnChange(const JSCallbackInfo& info)
566 {
567     CHECK_NULL_VOID(info[0]->IsFunction());
568     JsEventCallback<void(const std::string&)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(info[0]));
569     SearchModel::GetInstance()->SetOnChange(std::move(callback));
570 }
571 
SetOnTextSelectionChange(const JSCallbackInfo & info)572 void JSSearch::SetOnTextSelectionChange(const JSCallbackInfo& info)
573 {
574     CHECK_NULL_VOID(info[0]->IsFunction());
575     JsEventCallback<void(int32_t, int32_t)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(info[0]));
576     SearchModel::GetInstance()->SetOnTextSelectionChange(std::move(callback));
577 }
578 
SetOnScroll(const JSCallbackInfo & info)579 void JSSearch::SetOnScroll(const JSCallbackInfo& info)
580 {
581     CHECK_NULL_VOID(info[0]->IsFunction());
582     JsEventCallback<void(float, float)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(info[0]));
583     SearchModel::GetInstance()->SetOnScroll(std::move(callback));
584 }
585 
SetHeight(const JSCallbackInfo & info)586 void JSSearch::SetHeight(const JSCallbackInfo& info)
587 {
588     JSViewAbstract::JsHeight(info);
589     CalcDimension value;
590     auto versionTenOrLarger = PipelineBase::GetCurrentContext() &&
591                               PipelineBase::GetCurrentContext()->GetMinPlatformVersion() >= PLATFORM_VERSION_TEN;
592     if (versionTenOrLarger ? !ParseJsDimensionVpNG(info[0], value) : !ParseJsDimensionVp(info[0], value)) {
593         LOGE("The arg is wrong, it is supposed to be a number arguments");
594         return;
595     }
596     if (LessNotEqual(value.Value(), 0.0)) {
597         value.SetValue(0.0);
598     }
599     SearchModel::GetInstance()->SetHeight(value);
600 }
601 
SetOnCopy(const JSCallbackInfo & info)602 void JSSearch::SetOnCopy(const JSCallbackInfo& info)
603 {
604     CHECK_NULL_VOID(info[0]->IsFunction());
605     JsEventCallback<void(const std::string&)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(info[0]));
606     SearchModel::GetInstance()->SetOnCopy(std::move(callback));
607 }
608 
SetOnCut(const JSCallbackInfo & info)609 void JSSearch::SetOnCut(const JSCallbackInfo& info)
610 {
611     CHECK_NULL_VOID(info[0]->IsFunction());
612     JsEventCallback<void(const std::string&)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(info[0]));
613     SearchModel::GetInstance()->SetOnCut(std::move(callback));
614 }
615 
SetOnPaste(const JSCallbackInfo & info)616 void JSSearch::SetOnPaste(const JSCallbackInfo& info)
617 {
618     CHECK_NULL_VOID(info[0]->IsFunction());
619     JsEventCallback<void(const std::string&)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(info[0]));
620     SearchModel::GetInstance()->SetOnPaste(std::move(callback));
621 }
622 
SetCopyOption(const JSCallbackInfo & info)623 void JSSearch::SetCopyOption(const JSCallbackInfo& info)
624 {
625     if (info.Length() == 0) {
626         return;
627     }
628     if (info[0]->IsUndefined()) {
629         SearchModel::GetInstance()->SetCopyOption(CopyOptions::Local);
630         return;
631     }
632     auto copyOptions = CopyOptions::None;
633     if (info[0]->IsNumber()) {
634         auto emunNumber = info[0]->ToNumber<int>();
635         copyOptions = static_cast<CopyOptions>(emunNumber);
636     }
637     SearchModel::GetInstance()->SetCopyOption(copyOptions);
638 }
639 
JsMenuOptionsExtension(const JSCallbackInfo & info)640 void JSSearch::JsMenuOptionsExtension(const JSCallbackInfo& info)
641 {
642     if (info[0]->IsArray()) {
643         std::vector<NG::MenuOptionsParam> menuOptionsItems;
644         JSViewAbstract::ParseMenuOptions(info, JSRef<JSArray>::Cast(info[0]), menuOptionsItems);
645         SearchModel::GetInstance()->SetMenuOptionItems(std::move(menuOptionsItems));
646     }
647 }
648 
SetSelectionMenuHidden(const JSCallbackInfo & info)649 void JSSearch::SetSelectionMenuHidden(const JSCallbackInfo& info)
650 {
651     if (info.Length() < 1) {
652         LOGW("SelectionMenuHidden should have at least 1 param");
653         return;
654     }
655     if (info[0]->IsUndefined() || !info[0]->IsBoolean()) {
656         LOGI("The info of SetSelectionMenuHidden is not correct, using default");
657         SearchModel::GetInstance()->SetSelectionMenuHidden(false);
658         return;
659     }
660     SearchModel::GetInstance()->SetSelectionMenuHidden(info[0]->ToBoolean());
661 }
662 
SetCustomKeyboard(const JSCallbackInfo & info)663 void JSSearch::SetCustomKeyboard(const JSCallbackInfo& info)
664 {
665     if (info.Length() > 0 && (info[0]->IsUndefined() || info[0]->IsNull())) {
666         SearchModel::GetInstance()->SetCustomKeyboard(nullptr);
667         return;
668     }
669     if (info.Length() < 1 || !info[0]->IsObject()) {
670         return;
671     }
672     std::function<void()> buildFunc;
673     if (JSTextField::ParseJsCustomKeyboardBuilder(info, 0, buildFunc)) {
674         SearchModel::GetInstance()->SetCustomKeyboard(std::move(buildFunc));
675     }
676 }
677 
JSBind(BindingTarget globalObj)678 void JSSearchController::JSBind(BindingTarget globalObj)
679 {
680     JSClass<JSSearchController>::Declare("SearchController");
681     JSClass<JSSearchController>::Method("caretPosition", &JSSearchController::CaretPosition);
682     JSClass<JSSearchController>::CustomMethod("getTextContentRect", &JSSearchController::GetTextContentRect);
683     JSClass<JSSearchController>::CustomMethod("getTextContentLineCount", &JSSearchController::GetTextContentLinesNum);
684     JSClass<JSSearchController>::Method("stopEditing", &JSSearchController::StopEditing);
685     JSClass<JSSearchController>::Bind(globalObj, JSSearchController::Constructor, JSSearchController::Destructor);
686 }
687 
Constructor(const JSCallbackInfo & args)688 void JSSearchController::Constructor(const JSCallbackInfo& args)
689 {
690     auto scroller = Referenced::MakeRefPtr<JSSearchController>();
691     scroller->IncRefCount();
692     args.SetReturnValue(Referenced::RawPtr(scroller));
693 }
694 
Destructor(JSSearchController * scroller)695 void JSSearchController::Destructor(JSSearchController* scroller)
696 {
697     if (scroller != nullptr) {
698         scroller->DecRefCount();
699     }
700 }
701 
CaretPosition(int32_t caretPosition)702 void JSSearchController::CaretPosition(int32_t caretPosition)
703 {
704     auto controller = controller_.Upgrade();
705     if (controller) {
706         controller->CaretPosition(caretPosition);
707     }
708 }
709 
CreateRectangle(const Rect & info)710 JSRef<JSObject> JSSearchController::CreateRectangle(const Rect& info)
711 {
712     JSRef<JSObject> rectObj = JSRef<JSObject>::New();
713     rectObj->SetProperty<double>("x", info.Left());
714     rectObj->SetProperty<double>("y", info.Top());
715     rectObj->SetProperty<double>("width", info.Width());
716     rectObj->SetProperty<double>("height", info.Height());
717     return rectObj;
718 }
719 
GetTextContentRect(const JSCallbackInfo & info)720 void JSSearchController::GetTextContentRect(const JSCallbackInfo& info)
721 {
722     auto controller = controller_.Upgrade();
723     if (controller) {
724         auto rectObj = CreateRectangle(controller->GetTextContentRect());
725         JSRef<JSVal> rect = JSRef<JSObject>::Cast(rectObj);
726         info.SetReturnValue(rect);
727     } else {
728         LOGE("GetTextContentRect: The JSSearchController is NULL");
729     }
730 }
731 
GetTextContentLinesNum(const JSCallbackInfo & info)732 void JSSearchController::GetTextContentLinesNum(const JSCallbackInfo& info)
733 {
734     auto controller = controller_.Upgrade();
735     if (controller) {
736         auto lines = controller->GetTextContentLinesNum();
737         auto linesNum = JSVal(ToJSValue(lines));
738         auto textLines = JSRef<JSVal>::Make(linesNum);
739         info.SetReturnValue(textLines);
740     } else {
741         LOGE("GetTextContentRect: The JSSearchController is NULL");
742     }
743 }
744 
StopEditing()745 void JSSearchController::StopEditing()
746 {
747     auto controller = controller_.Upgrade();
748     if (controller) {
749         controller->StopEditing();
750     }
751 }
752 } // namespace OHOS::Ace::Framework
753