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