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 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
21 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
22 #endif
23
24 #include "base/log/ace_scoring_log.h"
25 #include "bridge/declarative_frontend/engine/functions/js_clipboard_function.h"
26 #include "bridge/declarative_frontend/engine/functions/js_function.h"
27 #include "bridge/declarative_frontend/jsview/js_text_editable_controller.h"
28 #include "bridge/declarative_frontend/jsview/js_textfield.h"
29 #include "bridge/declarative_frontend/jsview/js_textinput.h"
30 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
31 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
32 #include "bridge/declarative_frontend/jsview/models/search_model_impl.h"
33 #include "core/components/common/layout/constants.h"
34 #include "core/components/search/search_theme.h"
35 #include "core/components_ng/gestures/gesture_info.h"
36 #include "core/components_ng/pattern/search/search_model_ng.h"
37 #include "core/components_ng/pattern/text_field/text_field_model_ng.h"
38 #include "core/components/common/properties/text_style_parser.h"
39 #include "bridge/declarative_frontend/ark_theme/theme_apply/js_search_theme.h"
40
41 namespace OHOS::Ace {
42
43 std::unique_ptr<SearchModel> SearchModel::instance_ = nullptr;
44 std::mutex SearchModel::mutex_;
45
GetInstance()46 SearchModel* SearchModel::GetInstance()
47 {
48 #ifdef NG_BUILD
49 static NG::SearchModelNG instance;
50 return &instance;
51 #else
52 if (Container::IsCurrentUseNewPipeline()) {
53 static NG::SearchModelNG instance;
54 return &instance;
55 } else {
56 static Framework::SearchModelImpl instance;
57 return &instance;
58 }
59 #endif
60 }
61
62 } // namespace OHOS::Ace
63
64 namespace OHOS::Ace::Framework {
65 namespace {
66 const std::vector<TextAlign> TEXT_ALIGNS = { TextAlign::START, TextAlign::CENTER, TextAlign::END };
67 constexpr double DEFAULT_OPACITY = 0.2;
68 const int32_t DEFAULT_ALPHA = 255;
69 constexpr TextDecorationStyle DEFAULT_TEXT_DECORATION_STYLE = TextDecorationStyle::SOLID;
70 } // namespace
71
JSBind(BindingTarget globalObj)72 void JSSearch::JSBind(BindingTarget globalObj)
73 {
74 JSClass<JSSearch>::Declare("Search");
75 MethodOptions opt = MethodOptions::NONE;
76
77 JSClass<JSSearch>::StaticMethod("create", &JSSearch::Create, opt);
78 JSClass<JSSearch>::StaticMethod("searchButton", &JSSearch::SetSearchButton, opt);
79 JSClass<JSSearch>::StaticMethod("searchIcon", &JSSearch::SetSearchIcon, opt);
80 JSClass<JSSearch>::StaticMethod("cancelButton", &JSSearch::SetCancelButton, opt);
81 JSClass<JSSearch>::StaticMethod("fontColor", &JSSearch::SetTextColor, opt);
82 JSClass<JSSearch>::StaticMethod("caretStyle", &JSSearch::SetCaret, opt);
83 JSClass<JSSearch>::StaticMethod("placeholderColor", &JSSearch::SetPlaceholderColor, opt);
84 JSClass<JSSearch>::StaticMethod("placeholderFont", &JSSearch::SetPlaceholderFont, opt);
85 JSClass<JSSearch>::StaticMethod("textFont", &JSSearch::SetTextFont, opt);
86 JSClass<JSSearch>::StaticMethod("textAlign", &JSSearch::SetTextAlign, opt);
87 JSClass<JSSearch>::StaticMethod("onSubmit", &JSSearch::OnSubmit, opt);
88 JSClass<JSSearch>::StaticMethod("onChange", &JSSearch::OnChange, opt);
89 JSClass<JSSearch>::StaticMethod("onTextSelectionChange", &JSSearch::SetOnTextSelectionChange);
90 JSClass<JSSearch>::StaticMethod("onContentScroll", &JSSearch::SetOnScroll);
91 JSClass<JSSearch>::StaticMethod("border", &JSSearch::JsBorder);
92 JSClass<JSSearch>::StaticMethod("borderWidth", &JSSearch::JsBorderWidth);
93 JSClass<JSSearch>::StaticMethod("borderColor", &JSSearch::JsBorderColor);
94 JSClass<JSSearch>::StaticMethod("borderStyle", &JSSearch::JsBorderStyle);
95 JSClass<JSSearch>::StaticMethod("borderRadius", &JSSearch::JsBorderRadius);
96 JSClass<JSSearch>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
97 JSClass<JSSearch>::StaticMethod("height", &JSSearch::SetHeight);
98 JSClass<JSSearch>::StaticMethod("width", &JSViewAbstract::JsWidth);
99 JSClass<JSSearch>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
100 JSClass<JSSearch>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
101 JSClass<JSSearch>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
102 JSClass<JSSearch>::StaticMethod("requestKeyboardOnFocus", &JSSearch::SetEnableKeyboardOnFocus);
103 JSClass<JSSearch>::StaticMethod("enableKeyboardOnFocus", &JSSearch::SetEnableKeyboardOnFocus);
104 JSClass<JSSearch>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
105 JSClass<JSSearch>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
106 JSClass<JSSearch>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
107 JSClass<JSSearch>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
108 JSClass<JSSearch>::StaticMethod("onCopy", &JSSearch::SetOnCopy);
109 JSClass<JSSearch>::StaticMethod("onCut", &JSSearch::SetOnCut);
110 JSClass<JSSearch>::StaticMethod("onPaste", &JSSearch::SetOnPaste);
111 JSClass<JSSearch>::StaticMethod("copyOption", &JSSearch::SetCopyOption);
112 JSClass<JSSearch>::StaticMethod("selectionMenuHidden", &JSSearch::SetSelectionMenuHidden);
113 JSClass<JSSearch>::StaticMethod("customKeyboard", &JSSearch::SetCustomKeyboard);
114 JSClass<JSSearch>::StaticMethod("enterKeyType", &JSSearch::SetEnterKeyType);
115 JSClass<JSSearch>::StaticMethod("maxLength", &JSSearch::SetMaxLength);
116 JSClass<JSSearch>::StaticMethod("fontFeature", &JSSearch::SetFontFeature);
117 JSClass<JSSearch>::StaticMethod("type", &JSSearch::SetType);
118 JSClass<JSSearch>::StaticMethod("decoration", &JSSearch::SetDecoration);
119 JSClass<JSSearch>::StaticMethod("minFontSize", &JSSearch::SetMinFontSize);
120 JSClass<JSSearch>::StaticMethod("maxFontSize", &JSSearch::SetMaxFontSize);
121 JSClass<JSSearch>::StaticMethod("letterSpacing", &JSSearch::SetLetterSpacing);
122 JSClass<JSSearch>::StaticMethod("lineHeight", &JSSearch::SetLineHeight);
123 JSClass<JSSearch>::StaticMethod("dragPreviewOptions", &JSSearch::SetDragPreviewOptions);
124 JSClass<JSSearch>::StaticMethod("editMenuOptions", &JSSearch::EditMenuOptions);
125 JSBindMore();
126 JSClass<JSSearch>::InheritAndBind<JSViewAbstract>(globalObj);
127 }
128
JSBindMore()129 void JSSearch::JSBindMore()
130 {
131 JSClass<JSSearch>::StaticMethod("selectedBackgroundColor", &JSSearch::SetSelectedBackgroundColor);
132 JSClass<JSSearch>::StaticMethod("inputFilter", &JSSearch::SetInputFilter);
133 JSClass<JSSearch>::StaticMethod("onEditChange", &JSSearch::SetOnEditChange);
134 JSClass<JSSearch>::StaticMethod("textIndent", &JSSearch::SetTextIndent);
135 JSClass<JSSearch>::StaticMethod("onWillInsert", &JSSearch::OnWillInsertValue);
136 JSClass<JSSearch>::StaticMethod("onDidInsert", &JSSearch::OnDidInsertValue);
137 JSClass<JSSearch>::StaticMethod("onWillDelete", &JSSearch::OnWillDelete);
138 JSClass<JSSearch>::StaticMethod("onDidDelete", &JSSearch::OnDidDelete);
139 JSClass<JSSearch>::StaticMethod("enablePreviewText", &JSSearch::SetEnablePreviewText);
140 JSClass<JSSearch>::StaticMethod("id", &JSSearch::SetId);
141 JSClass<JSSearch>::StaticMethod("key", &JSSearch::SetKey);
142 JSClass<JSSearch>::StaticMethod("enableHapticFeedback", &JSSearch::SetEnableHapticFeedback);
143 }
144
ParseSearchValueObject(const JSCallbackInfo & info,const JSRef<JSVal> & changeEventVal)145 void ParseSearchValueObject(const JSCallbackInfo& info, const JSRef<JSVal>& changeEventVal)
146 {
147 CHECK_NULL_VOID(changeEventVal->IsFunction());
148
149 JsEventCallback<void(const std::string&)> onChangeEvent(
150 info.GetExecutionContext(), JSRef<JSFunc>::Cast(changeEventVal));
151 SearchModel::GetInstance()->SetOnChangeEvent(std::move(onChangeEvent));
152 }
153
SetDragPreviewOptions(const JSCallbackInfo & info)154 void JSSearch::SetDragPreviewOptions(const JSCallbackInfo& info)
155 {
156 NG::DragPreviewOption option = JSViewAbstract::ParseDragPreviewOptions(info);
157 SearchModel::GetInstance()->SetDragPreviewOptions(option);
158 }
159
SetFontFeature(const JSCallbackInfo & info)160 void JSSearch::SetFontFeature(const JSCallbackInfo& info)
161 {
162 if (info.Length() < 1) {
163 return;
164 }
165
166 if (!info[0]->IsString() && !info[0]->IsObject()) {
167 return;
168 }
169 std::string fontFeatureSettings = info[0]->ToString();
170 SearchModel::GetInstance()->SetFontFeature(ParseFontFeatureSettings(fontFeatureSettings));
171 }
172
Create(const JSCallbackInfo & info)173 void JSSearch::Create(const JSCallbackInfo& info)
174 {
175 std::optional<std::string> key;
176 std::optional<std::string> tip;
177 std::optional<std::string> src;
178 JSTextEditableController* jsController = nullptr;
179 JSRef<JSVal> changeEventVal;
180 if (info[0]->IsObject()) {
181 auto param = JSRef<JSObject>::Cast(info[0]);
182 std::string placeholder;
183 if (param->GetProperty("placeholder")->IsUndefined()) {
184 tip = "";
185 }
186 if (ParseJsString(param->GetProperty("placeholder"), placeholder)) {
187 tip = placeholder;
188 }
189 std::string text;
190 JSRef<JSVal> textValue = param->GetProperty("value");
191 if (textValue->IsObject()) {
192 JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(textValue);
193 changeEventVal = valueObj->GetProperty("changeEvent");
194 if (changeEventVal->IsFunction()) {
195 textValue = valueObj->GetProperty("value");
196 }
197 if (ParseJsString(textValue, text)) {
198 key = text;
199 }
200 } else if (param->HasProperty("value") && textValue->IsUndefined()) {
201 key = "";
202 } else {
203 if (ParseJsString(textValue, text)) {
204 key = text;
205 }
206 }
207 std::string icon;
208 if (ParseJsString(param->GetProperty("icon"), icon)) {
209 src = icon;
210 }
211 auto controllerObj = param->GetProperty("controller");
212 if (!controllerObj->IsUndefined() && !controllerObj->IsNull() && controllerObj->IsObject()) {
213 jsController = JSRef<JSObject>::Cast(controllerObj)->Unwrap<JSTextEditableController>();
214 }
215 }
216 auto controller = SearchModel::GetInstance()->Create(key, tip, src);
217 if (jsController) {
218 jsController->SetController(controller);
219 }
220 SearchModel::GetInstance()->SetFocusable(true);
221 SearchModel::GetInstance()->SetFocusNode(true);
222 if (!changeEventVal->IsUndefined() && changeEventVal->IsFunction()) {
223 ParseSearchValueObject(info, changeEventVal);
224 }
225 JSSeacrhTheme::ApplyTheme();
226 }
227
SetSelectedBackgroundColor(const JSCallbackInfo & info)228 void JSSearch::SetSelectedBackgroundColor(const JSCallbackInfo& info)
229 {
230 if (info.Length() < 1) {
231 return;
232 }
233 Color selectedColor;
234 if (!ParseJsColor(info[0], selectedColor)) {
235 auto pipeline = PipelineBase::GetCurrentContext();
236 CHECK_NULL_VOID(pipeline);
237 auto theme = pipeline->GetThemeManager()->GetTheme<TextFieldTheme>();
238 CHECK_NULL_VOID(theme);
239 selectedColor = theme->GetSelectedColor();
240 }
241 // Alpha = 255 means opaque
242 if (selectedColor.GetAlpha() == DEFAULT_ALPHA) {
243 // Default setting of 20% opacity
244 selectedColor = selectedColor.ChangeOpacity(DEFAULT_OPACITY);
245 }
246 SearchModel::GetInstance()->SetSelectedBackgroundColor(selectedColor);
247 }
248
SetEnableKeyboardOnFocus(const JSCallbackInfo & info)249 void JSSearch::SetEnableKeyboardOnFocus(const JSCallbackInfo& info)
250 {
251 if (info[0]->IsUndefined() || !info[0]->IsBoolean()) {
252 SearchModel::GetInstance()->RequestKeyboardOnFocus(true);
253 return;
254 }
255 SearchModel::GetInstance()->RequestKeyboardOnFocus(info[0]->ToBoolean());
256 }
257
SetId(const JSCallbackInfo & info)258 void JSSearch::SetId(const JSCallbackInfo& info)
259 {
260 JSViewAbstract::JsId(info);
261 JSRef<JSVal> arg = info[0];
262 std::string id;
263 if (arg->IsString()) {
264 id = arg->ToString();
265 }
266 SearchModel::GetInstance()->UpdateInspectorId(id);
267 }
268
SetKey(const std::string & key)269 void JSSearch::SetKey(const std::string& key)
270 {
271 JSViewAbstract::JsKey(key);
272 SearchModel::GetInstance()->UpdateInspectorId(key);
273 }
274
SetSearchButton(const JSCallbackInfo & info)275 void JSSearch::SetSearchButton(const JSCallbackInfo& info)
276 {
277 auto theme = GetTheme<SearchTheme>();
278 CHECK_NULL_VOID(theme);
279 std::string buttonValue = "";
280 if (info[0]->IsString()) {
281 buttonValue = info[0]->ToString();
282 }
283 SearchModel::GetInstance()->SetSearchButton(buttonValue);
284 // set font color
285 Color fontColor = theme->GetSearchButtonTextColor();
286 if (info[1]->IsObject()) {
287 auto param = JSRef<JSObject>::Cast(info[1]);
288
289 // set button font size, unit FP
290 auto fontSize = param->GetProperty("fontSize");
291 CalcDimension size = theme->GetFontSize();
292 if (ParseJsDimensionVpNG(fontSize, size) && size.Unit() != DimensionUnit::PERCENT &&
293 GreatOrEqual(size.Value(), 0.0)) {
294 ParseJsDimensionFp(fontSize, size);
295 } else {
296 size = theme->GetFontSize();
297 }
298 SearchModel::GetInstance()->SetSearchButtonFontSize(size);
299 auto fontColorProp = param->GetProperty("fontColor");
300 if (fontColorProp->IsUndefined() || fontColorProp->IsNull() || !ParseJsColor(fontColorProp, fontColor)) {
301 if (!JSSeacrhTheme::ObtainSearchButtonFontColor(fontColor)) {
302 SearchModel::GetInstance()->SetSearchButtonFontColor(fontColor);
303 }
304 } else {
305 SearchModel::GetInstance()->SetSearchButtonFontColor(fontColor);
306 }
307 } else {
308 SearchModel::GetInstance()->SetSearchButtonFontSize(theme->GetFontSize());
309 if (!JSSeacrhTheme::ObtainSearchButtonFontColor(fontColor)) {
310 SearchModel::GetInstance()->SetSearchButtonFontColor(fontColor);
311 }
312 }
313 }
314
SetSearchIcon(const JSCallbackInfo & info)315 void JSSearch::SetSearchIcon(const JSCallbackInfo& info)
316 {
317 if (info[0]->IsUndefined() || info[0]->IsNull()) {
318 SetSearchDefaultIcon();
319 return;
320 }
321 if (info[0]->IsObject()) {
322 auto param = JSRef<JSObject>::Cast(info[0]);
323 bool isSymbolIcon = param->HasProperty("fontColor"); // only SymbolGlyph has fontColor property
324 if (isSymbolIcon) {
325 SetSearchSymbolIcon(info);
326 } else {
327 SetSearchImageIcon(info);
328 }
329 }
330 }
331
SetCancelDefaultIcon()332 void JSSearch::SetCancelDefaultIcon()
333 {
334 SearchModel::GetInstance()->SetCancelDefaultIcon();
335 }
336
SetCancelSymbolIcon(const JSCallbackInfo & info)337 void JSSearch::SetCancelSymbolIcon(const JSCallbackInfo& info)
338 {
339 if (info[0]->IsObject()) {
340 std::function<void(WeakPtr<NG::FrameNode>)> iconSymbol = nullptr;
341 auto param = JSRef<JSObject>::Cast(info[0]);
342 auto iconProp = param->GetProperty("icon");
343 SetSymbolOptionApply(info, iconSymbol, iconProp);
344 SearchModel::GetInstance()->SetCancelSymbolIcon(iconSymbol);
345 }
346 }
347
SetCancelImageIcon(const JSCallbackInfo & info)348 void JSSearch::SetCancelImageIcon(const JSCallbackInfo& info)
349 {
350 if (!info[0]->IsObject()) {
351 return;
352 }
353
354 auto param = JSRef<JSObject>::Cast(info[0]);
355 auto theme = GetTheme<SearchTheme>();
356 CHECK_NULL_VOID(theme);
357 auto iconJsVal = param->GetProperty("icon");
358 if (!iconJsVal->IsObject()) {
359 return;
360 }
361 auto iconParam = JSRef<JSObject>::Cast(iconJsVal);
362
363 // set icon size
364 CalcDimension iconSize;
365 auto iconSizeProp = iconParam->GetProperty("size");
366 if (!iconSizeProp->IsUndefined() && !iconSizeProp->IsNull() && ParseJsDimensionVpNG(iconSizeProp, iconSize)) {
367 if (LessNotEqual(iconSize.Value(), 0.0) || iconSize.Unit() == DimensionUnit::PERCENT) {
368 iconSize = theme->GetIconHeight();
369 }
370 } else {
371 iconSize = theme->GetIconHeight();
372 }
373
374 // set icon src
375 std::string iconSrc;
376 auto iconSrcProp = iconParam->GetProperty("src");
377 if (iconSrcProp->IsUndefined() || iconSrcProp->IsNull() || !ParseJsMedia(iconSrcProp, iconSrc)) {
378 iconSrc = "";
379 }
380
381 // set icon color
382 Color iconColor = theme->GetSearchIconColor();
383 auto iconColorProp = iconParam->GetProperty("color");
384 if (!iconColorProp->IsUndefined() && !iconColorProp->IsNull() && ParseJsColor(iconColorProp, iconColor)) {
385 NG::IconOptions cancelIconOptions = NG::IconOptions(iconColor, iconSize, iconSrc, "", "");
386 SearchModel::GetInstance()->SetCancelImageIcon(cancelIconOptions);
387 } else {
388 NG::IconOptions cancelIconOptions = NG::IconOptions(iconSize, iconSrc, "", "");
389 SearchModel::GetInstance()->SetCancelImageIcon(cancelIconOptions);
390 }
391 }
392
SetSearchDefaultIcon()393 void JSSearch::SetSearchDefaultIcon()
394 {
395 SearchModel::GetInstance()->SetSearchDefaultIcon();
396 }
397
SetSearchSymbolIcon(const JSCallbackInfo & info)398 void JSSearch::SetSearchSymbolIcon(const JSCallbackInfo& info)
399 {
400 if (!info[0]->IsObject()) {
401 return;
402 }
403
404 std::function<void(WeakPtr<NG::FrameNode>)> iconSymbol = nullptr;
405 SetSymbolOptionApply(info, iconSymbol, info[0]);
406 SearchModel::GetInstance()->SetSearchSymbolIcon(iconSymbol);
407 }
408
SetSearchImageIcon(const JSCallbackInfo & info)409 void JSSearch::SetSearchImageIcon(const JSCallbackInfo& info)
410 {
411 if (!info[0]->IsObject()) {
412 return;
413 }
414
415 auto param = JSRef<JSObject>::Cast(info[0]);
416 auto theme = GetTheme<SearchTheme>();
417 CHECK_NULL_VOID(theme);
418
419 // set icon size
420 CalcDimension size;
421 auto sizeProp = param->GetProperty("size");
422 if (!sizeProp->IsUndefined() && !sizeProp->IsNull() && ParseJsDimensionVpNG(sizeProp, size)) {
423 if (LessNotEqual(size.Value(), 0.0) || size.Unit() == DimensionUnit::PERCENT) {
424 size = theme->GetIconHeight();
425 }
426 } else {
427 size = theme->GetIconHeight();
428 }
429
430 // set icon src
431 std::string src;
432 auto srcPathProp = param->GetProperty("src");
433 if (srcPathProp->IsUndefined() || srcPathProp->IsNull() || !ParseJsMedia(srcPathProp, src)) {
434 src = "";
435 }
436 // set icon color
437 Color colorVal = theme->GetSearchIconColor();
438 auto colorProp = param->GetProperty("color");
439 if (!colorProp->IsUndefined() && !colorProp->IsNull() && ParseJsColor(colorProp, colorVal)) {
440 ParseJsColor(colorProp, colorVal);
441 }
442
443 std::string bundleName;
444 std::string moduleName;
445 GetJsMediaBundleInfo(srcPathProp, bundleName, moduleName);
446 NG::IconOptions searchIconOptions = NG::IconOptions(colorVal, size, src, bundleName, moduleName);
447 SearchModel::GetInstance()->SetSearchImageIcon(searchIconOptions);
448 }
449
ConvertStrToCancelButtonStyle(const std::string & value)450 static CancelButtonStyle ConvertStrToCancelButtonStyle(const std::string& value)
451 {
452 if (value == "CONSTANT") {
453 return CancelButtonStyle::CONSTANT;
454 } else if (value == "INVISIBLE") {
455 return CancelButtonStyle::INVISIBLE;
456 } else {
457 return CancelButtonStyle::INPUT;
458 }
459 }
460
SetCancelButton(const JSCallbackInfo & info)461 void JSSearch::SetCancelButton(const JSCallbackInfo& info)
462 {
463 if (!info[0]->IsObject()) {
464 return;
465 }
466 auto param = JSRef<JSObject>::Cast(info[0]);
467 auto theme = GetTheme<SearchTheme>();
468 CHECK_NULL_VOID(theme);
469
470 // set style
471 std::string styleStr;
472 CancelButtonStyle cancelButtonStyle;
473 auto styleProp = param->GetProperty("style");
474 if (!styleProp->IsUndefined() && !styleProp->IsNull() && ParseJsString(styleProp, styleStr)) {
475 cancelButtonStyle = ConvertStrToCancelButtonStyle(styleStr);
476 } else {
477 cancelButtonStyle = theme->GetCancelButtonStyle();
478 }
479 SearchModel::GetInstance()->SetCancelButtonStyle(cancelButtonStyle);
480
481 auto iconProp = param->GetProperty("icon");
482 if (iconProp->IsUndefined() || iconProp->IsNull()) {
483 SetCancelDefaultIcon();
484 } else {
485 SetIconStyle(info);
486 }
487 }
488
SetIconStyle(const JSCallbackInfo & info)489 void JSSearch::SetIconStyle(const JSCallbackInfo& info)
490 {
491 if (!info[0]->IsObject()) {
492 return;
493 }
494
495 auto param = JSRef<JSObject>::Cast(info[0]);
496 auto iconJsVal = param->GetProperty("icon");
497 if (!iconJsVal->IsObject()) {
498 return;
499 }
500
501 auto iconParam = JSRef<JSObject>::Cast(iconJsVal);
502 bool isSymbolIcon = iconParam->HasProperty("fontColor"); // only SymbolGlyph has fontColor property
503 if (isSymbolIcon) {
504 SetCancelSymbolIcon(info);
505 } else {
506 SetCancelImageIcon(info);
507 }
508 }
509
SetTextColor(const JSCallbackInfo & info)510 void JSSearch::SetTextColor(const JSCallbackInfo& info)
511 {
512 auto theme = GetTheme<SearchTheme>();
513 CHECK_NULL_VOID(theme);
514
515 auto value = JSRef<JSVal>::Cast(info[0]);
516 Color colorVal;
517 if (!ParseJsColor(value, colorVal)) {
518 colorVal = theme->GetTextColor();
519 }
520 SearchModel::GetInstance()->SetTextColor(colorVal);
521 }
522
SetCaret(const JSCallbackInfo & info)523 void JSSearch::SetCaret(const JSCallbackInfo& info)
524 {
525 if (info[0]->IsObject()) {
526 auto param = JSRef<JSObject>::Cast(info[0]);
527 auto textFieldTheme = GetTheme<TextFieldTheme>();
528 CHECK_NULL_VOID(textFieldTheme);
529
530 // set caret width
531 CalcDimension caretWidth = textFieldTheme->GetCursorWidth();
532 auto caretWidthProp = param->GetProperty("width");
533 if (!ParseJsDimensionVpNG(caretWidthProp, caretWidth, false) || LessNotEqual(caretWidth.Value(), 0.0)) {
534 caretWidth = textFieldTheme->GetCursorWidth();
535 }
536 SearchModel::GetInstance()->SetCaretWidth(caretWidth);
537
538 // set caret color
539 Color caretColor;
540 auto caretColorProp = param->GetProperty("color");
541 if (caretColorProp->IsUndefined() || caretColorProp->IsNull() || !ParseJsColor(caretColorProp, caretColor)) {
542 caretColor = textFieldTheme->GetCursorColor();
543 }
544 SearchModel::GetInstance()->SetCaretColor(caretColor);
545 }
546 }
547
SetInputFilter(const JSCallbackInfo & info)548 void JSSearch::SetInputFilter(const JSCallbackInfo& info)
549 {
550 if (info.Length() < 1) {
551 return;
552 }
553 auto tmpInfo = info[0];
554 auto errInfo = info[1];
555 std::string inputFilter;
556 if (tmpInfo->IsUndefined()) {
557 SearchModel::GetInstance()->SetInputFilter(inputFilter, nullptr);
558 return;
559 }
560 if (!ParseJsString(tmpInfo, inputFilter)) {
561 return;
562 }
563 if (!CheckRegexValid(inputFilter)) {
564 inputFilter = "";
565 }
566 if (info.Length() > 1 && errInfo->IsFunction()) {
567 auto jsFunc = AceType::MakeRefPtr<JsClipboardFunction>(JSRef<JSFunc>::Cast(errInfo));
568 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
569 auto resultId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
570 const std::string& info) {
571 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
572 PipelineContext::SetCallBackNode(node);
573 func->Execute(info);
574 };
575 SearchModel::GetInstance()->SetInputFilter(inputFilter, resultId);
576 return;
577 }
578 SearchModel::GetInstance()->SetInputFilter(inputFilter, nullptr);
579 }
580
SetOnEditChange(const JSCallbackInfo & info)581 void JSSearch::SetOnEditChange(const JSCallbackInfo& info)
582 {
583 auto tmpInfo = info[0];
584 CHECK_NULL_VOID(tmpInfo->IsFunction());
585 JsEventCallback<void(bool)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(tmpInfo));
586 SearchModel::GetInstance()->SetOnEditChanged(std::move(callback));
587 }
588
SetTextIndent(const JSCallbackInfo & info)589 void JSSearch::SetTextIndent(const JSCallbackInfo& info)
590 {
591 CalcDimension value;
592 if (!ParseJsDimensionVpNG(info[0], value, true)) {
593 value.Reset();
594 }
595 SearchModel::GetInstance()->SetTextIndent(value);
596 }
597
SetPlaceholderColor(const JSCallbackInfo & info)598 void JSSearch::SetPlaceholderColor(const JSCallbackInfo& info)
599 {
600 auto value = JSRef<JSVal>::Cast(info[0]);
601 Color colorVal;
602 if (!ParseJsColor(value, colorVal)) {
603 auto theme = GetTheme<SearchTheme>();
604 CHECK_NULL_VOID(theme);
605 colorVal = theme->GetPlaceholderColor();
606 }
607 SearchModel::GetInstance()->SetPlaceholderColor(colorVal);
608 }
609
SetPlaceholderFont(const JSCallbackInfo & info)610 void JSSearch::SetPlaceholderFont(const JSCallbackInfo& info)
611 {
612 if (!info[0]->IsObject()) {
613 return;
614 }
615 auto param = JSRef<JSObject>::Cast(info[0]);
616 auto theme = GetTheme<SearchTheme>();
617 CHECK_NULL_VOID(theme);
618 auto themeFontSize = theme->GetFontSize();
619 Font font;
620 auto fontSize = param->GetProperty("size");
621 if (fontSize->IsNull() || fontSize->IsUndefined()) {
622 font.fontSize = themeFontSize;
623 } else {
624 auto versionTenOrLarger = Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN);
625 CalcDimension size;
626 if ((versionTenOrLarger ? ParseJsDimensionVpNG(fontSize, size) : ParseJsDimensionVp(fontSize, size)) &&
627 size.Unit() != DimensionUnit::PERCENT) {
628 ParseJsDimensionFp(fontSize, size);
629 font.fontSize = size;
630 } else {
631 font.fontSize = themeFontSize;
632 }
633 }
634
635 auto weight = param->GetProperty("weight");
636 if (!weight->IsNull()) {
637 std::string weightVal;
638 if (weight->IsNumber()) {
639 weightVal = std::to_string(weight->ToNumber<int32_t>());
640 } else {
641 ParseJsString(weight, weightVal);
642 }
643 font.fontWeight = ConvertStrToFontWeight(weightVal);
644 }
645
646 auto family = param->GetProperty("family");
647 if (!family->IsNull() && family->IsString()) {
648 auto familyVal = family->ToString();
649 font.fontFamilies = ConvertStrToFontFamilies(familyVal);
650 }
651
652 auto style = param->GetProperty("style");
653 if (!style->IsNull() && style->IsNumber()) {
654 FontStyle styleVal = static_cast<FontStyle>(style->ToNumber<int32_t>());
655 font.fontStyle = styleVal;
656 }
657 SearchModel::GetInstance()->SetPlaceholderFont(font);
658 }
659
SetTextFont(const JSCallbackInfo & info)660 void JSSearch::SetTextFont(const JSCallbackInfo& info)
661 {
662 auto theme = GetTheme<SearchTheme>();
663 CHECK_NULL_VOID(theme);
664 auto themeFontSize = theme->GetFontSize();
665 auto themeFontWeight = theme->GetFontWeight();
666 Font font {.fontWeight = themeFontWeight, .fontSize = themeFontSize, .fontStyle = Ace::FontStyle::NORMAL};
667 if (info.Length() < 1 || !info[0]->IsObject()) {
668 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
669 SearchModel::GetInstance()->SetTextFont(font);
670 }
671 return;
672 }
673 auto param = JSRef<JSObject>::Cast(info[0]);
674 auto fontSize = param->GetProperty("size");
675 CalcDimension size = themeFontSize;
676 if (ParseJsDimensionVpNG(fontSize, size) && size.Unit() != DimensionUnit::PERCENT &&
677 GreatOrEqual(size.Value(), 0.0)) {
678 ParseJsDimensionFp(fontSize, size);
679 } else {
680 size = themeFontSize;
681 }
682 font.fontSize = size;
683
684 auto weight = param->GetProperty("weight");
685 if (!weight->IsNull()) {
686 std::string weightVal;
687 if (weight->IsNumber()) {
688 weightVal = std::to_string(weight->ToNumber<int32_t>());
689 } else {
690 ParseJsString(weight, weightVal);
691 }
692 font.fontWeight = ConvertStrToFontWeight(weightVal);
693 }
694
695 auto family = param->GetProperty("family");
696 if (!family->IsNull() && family->IsString()) {
697 auto familyVal = family->ToString();
698 font.fontFamilies = ConvertStrToFontFamilies(familyVal);
699 }
700
701 auto style = param->GetProperty("style");
702 if (!style->IsNull() && style->IsNumber()) {
703 FontStyle styleVal = static_cast<FontStyle>(style->ToNumber<int32_t>());
704 font.fontStyle = styleVal;
705 }
706 SearchModel::GetInstance()->SetTextFont(font);
707 }
708
SetTextAlign(int32_t value)709 void JSSearch::SetTextAlign(int32_t value)
710 {
711 if (value >= 0 && value < static_cast<int32_t>(TEXT_ALIGNS.size())) {
712 SearchModel::GetInstance()->SetTextAlign(TEXT_ALIGNS[value]);
713 }
714 }
715
JsBorder(const JSCallbackInfo & info)716 void JSSearch::JsBorder(const JSCallbackInfo& info)
717 {
718 JSViewAbstract::JsBorder(info);
719 SearchModel::GetInstance()->SetBackBorder();
720 }
721
JsBorderWidth(const JSCallbackInfo & info)722 void JSSearch::JsBorderWidth(const JSCallbackInfo& info)
723 {
724 JSViewAbstract::JsBorderWidth(info);
725 if (!info[0]->IsObject() && !info[0]->IsString() && !info[0]->IsNumber()) {
726 return;
727 }
728 SearchModel::GetInstance()->SetBackBorder();
729 }
730
JsBorderColor(const JSCallbackInfo & info)731 void JSSearch::JsBorderColor(const JSCallbackInfo& info)
732 {
733 JSViewAbstract::JsBorderColor(info);
734 if (!info[0]->IsObject() && !info[0]->IsString() && !info[0]->IsNumber()) {
735 return;
736 }
737 SearchModel::GetInstance()->SetBackBorder();
738 }
739
JsBorderStyle(const JSCallbackInfo & info)740 void JSSearch::JsBorderStyle(const JSCallbackInfo& info)
741 {
742 JSViewAbstract::JsBorderStyle(info);
743 if (!info[0]->IsObject() && !info[0]->IsNumber()) {
744 return;
745 }
746 SearchModel::GetInstance()->SetBackBorder();
747 }
748
JsBorderRadius(const JSCallbackInfo & info)749 void JSSearch::JsBorderRadius(const JSCallbackInfo& info)
750 {
751 JSViewAbstract::JsBorderRadius(info);
752 if (!info[0]->IsObject() && !info[0]->IsString() && !info[0]->IsNumber()) {
753 return;
754 }
755 SearchModel::GetInstance()->SetBackBorder();
756 }
757
CreateJsSearchCommonEvent(const JSCallbackInfo & info)758 void JSSearch::CreateJsSearchCommonEvent(const JSCallbackInfo &info)
759 {
760 if (info.Length() < 1 || !info[0]->IsFunction()) {
761 return;
762 }
763 auto jsTextFunc = AceType::MakeRefPtr<JsCommonEventFunction<NG::TextFieldCommonEvent, 2>>(
764 JSRef<JSFunc>::Cast(info[0]));
765 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
766 auto callback = [execCtx = info.GetExecutionContext(), func = std::move(jsTextFunc), node = targetNode](
767 const std::string& value, NG::TextFieldCommonEvent& event) {
768 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
769 ACE_SCORING_EVENT("onSubmit");
770 PipelineContext::SetCallBackNode(node);
771 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
772 objectTemplate->SetInternalFieldCount(2);
773 JSRef<JSObject> object = objectTemplate->NewInstance();
774 object->SetProperty<std::string>("text", event.GetText());
775 object->SetPropertyObject(
776 "keepEditableState", JSRef<JSFunc>::New<FunctionCallback>(JSTextField::JsKeepEditableState));
777 object->Wrap<NG::TextFieldCommonEvent>(&event);
778 JSRef<JSVal> stringValue = JSRef<JSVal>::Make(ToJSValue(value));
779 JSRef<JSVal> dataObject = JSRef<JSVal>::Cast(object);
780 JSRef<JSVal> param[2] = {stringValue, dataObject};
781 func->Execute(param);
782 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
783 UiSessionManager::GetInstance().ReportComponentChangeEvent("event", "onSubmit");
784 #endif
785 };
786 SearchModel::GetInstance()->SetOnSubmit(std::move(callback));
787 }
788
OnSubmit(const JSCallbackInfo & info)789 void JSSearch::OnSubmit(const JSCallbackInfo& info)
790 {
791 auto jsValue = info[0];
792 CHECK_NULL_VOID(jsValue->IsFunction());
793 #ifdef NG_BUILD
794 CreateJsSearchCommonEvent(info);
795 #else
796 if (Container::IsCurrentUseNewPipeline()) {
797 CreateJsSearchCommonEvent(info);
798 } else {
799 JsEventCallback<void(const std::string&)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(jsValue));
800 SearchModel::GetInstance()->SetOnSubmit(std::move(callback));
801 }
802 #endif
803 }
804
CreateJsOnChangeObj(const PreviewText & previewText)805 JSRef<JSVal> JSSearch::CreateJsOnChangeObj(const PreviewText& previewText)
806 {
807 JSRef<JSObject> previewTextObj = JSRef<JSObject>::New();
808 previewTextObj->SetProperty<int32_t>("offset", previewText.offset);
809 previewTextObj->SetProperty<std::string>("value", previewText.value);
810 return JSRef<JSVal>::Cast(previewTextObj);
811 }
812
OnChange(const JSCallbackInfo & info)813 void JSSearch::OnChange(const JSCallbackInfo& info)
814 {
815 auto jsValue = info[0];
816 CHECK_NULL_VOID(jsValue->IsFunction());
817 auto jsChangeFunc = AceType::MakeRefPtr<JsCitedEventFunction<PreviewText, 2>>(
818 JSRef<JSFunc>::Cast(jsValue), CreateJsOnChangeObj);
819 auto onChange = [execCtx = info.GetExecutionContext(), func = std::move(jsChangeFunc)](
820 const std::string& val, PreviewText& previewText) {
821 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
822 ACE_SCORING_EVENT("onChange");
823 func->Execute(val, previewText);
824 };
825 SearchModel::GetInstance()->SetOnChange(std::move(onChange));
826 }
827
SetOnTextSelectionChange(const JSCallbackInfo & info)828 void JSSearch::SetOnTextSelectionChange(const JSCallbackInfo& info)
829 {
830 CHECK_NULL_VOID(info[0]->IsFunction());
831 JsEventCallback<void(int32_t, int32_t)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(info[0]));
832 SearchModel::GetInstance()->SetOnTextSelectionChange(std::move(callback));
833 }
834
SetOnScroll(const JSCallbackInfo & info)835 void JSSearch::SetOnScroll(const JSCallbackInfo& info)
836 {
837 CHECK_NULL_VOID(info[0]->IsFunction());
838 JsEventCallback<void(float, float)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(info[0]));
839 SearchModel::GetInstance()->SetOnScroll(std::move(callback));
840 }
841
SetHeight(const JSCallbackInfo & info)842 void JSSearch::SetHeight(const JSCallbackInfo& info)
843 {
844 JSViewAbstract::JsHeight(info);
845 CalcDimension value;
846 auto versionTenOrLarger = Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN);
847 if (versionTenOrLarger ? !ParseJsDimensionVpNG(info[0], value) : !ParseJsDimensionVp(info[0], value)) {
848 return;
849 }
850 if (LessNotEqual(value.Value(), 0.0)) {
851 value.SetValue(0.0);
852 }
853 SearchModel::GetInstance()->SetHeight(value);
854 }
855
SetOnCopy(const JSCallbackInfo & info)856 void JSSearch::SetOnCopy(const JSCallbackInfo& info)
857 {
858 CHECK_NULL_VOID(info[0]->IsFunction());
859 JsEventCallback<void(const std::string&)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(info[0]));
860 SearchModel::GetInstance()->SetOnCopy(std::move(callback));
861 }
862
SetOnCut(const JSCallbackInfo & info)863 void JSSearch::SetOnCut(const JSCallbackInfo& info)
864 {
865 CHECK_NULL_VOID(info[0]->IsFunction());
866 JsEventCallback<void(const std::string&)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(info[0]));
867 SearchModel::GetInstance()->SetOnCut(std::move(callback));
868 }
869
CreateJSTextCommonEvent(NG::TextCommonEvent & event)870 JSRef<JSVal> JSSearch::CreateJSTextCommonEvent(NG::TextCommonEvent& event)
871 {
872 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
873 objectTemplate->SetInternalFieldCount(1);
874 JSRef<JSObject> object = objectTemplate->NewInstance();
875 object->SetPropertyObject("preventDefault", JSRef<JSFunc>::New<FunctionCallback>(JsPreventDefault));
876 object->Wrap<NG::TextCommonEvent>(&event);
877 return JSRef<JSVal>::Cast(object);
878 }
879
SetOnPaste(const JSCallbackInfo & info)880 void JSSearch::SetOnPaste(const JSCallbackInfo& info)
881 {
882 CHECK_NULL_VOID(info[0]->IsFunction());
883 auto jsTextFunc = AceType::MakeRefPtr<JsCitedEventFunction<NG::TextCommonEvent, 2>>(
884 JSRef<JSFunc>::Cast(info[0]), CreateJSTextCommonEvent);
885
886 auto onPaste = [execCtx = info.GetExecutionContext(), func = std::move(jsTextFunc)](
887 const std::string& val, NG::TextCommonEvent& info) {
888 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
889 ACE_SCORING_EVENT("onPaste");
890 func->Execute(val, info);
891 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
892 UiSessionManager::GetInstance().ReportComponentChangeEvent("event", "onPaste");
893 #endif
894 };
895 SearchModel::GetInstance()->SetOnPasteWithEvent(std::move(onPaste));
896 }
897
SetCopyOption(const JSCallbackInfo & info)898 void JSSearch::SetCopyOption(const JSCallbackInfo& info)
899 {
900 if (info.Length() == 0) {
901 return;
902 }
903 if (info[0]->IsUndefined()) {
904 SearchModel::GetInstance()->SetCopyOption(CopyOptions::Local);
905 return;
906 }
907 auto copyOptions = CopyOptions::None;
908 if (info[0]->IsNumber()) {
909 auto emunNumber = info[0]->ToNumber<int>();
910 copyOptions = static_cast<CopyOptions>(emunNumber);
911 }
912 SearchModel::GetInstance()->SetCopyOption(copyOptions);
913 }
914
CreateJsAboutToIMEInputObj(const InsertValueInfo & insertValue)915 JSRef<JSVal> JSSearch::CreateJsAboutToIMEInputObj(const InsertValueInfo& insertValue)
916 {
917 JSRef<JSObject> aboutToIMEInputObj = JSRef<JSObject>::New();
918 aboutToIMEInputObj->SetProperty<int32_t>("insertOffset", insertValue.insertOffset);
919 aboutToIMEInputObj->SetProperty<std::string>("insertValue", insertValue.insertValue);
920 return JSRef<JSVal>::Cast(aboutToIMEInputObj);
921 }
922
OnWillInsertValue(const JSCallbackInfo & info)923 void JSSearch::OnWillInsertValue(const JSCallbackInfo& info)
924 {
925 auto jsValue = info[0];
926 CHECK_NULL_VOID(jsValue->IsFunction());
927 auto jsAboutToIMEInputFunc = AceType::MakeRefPtr<JsEventFunction<InsertValueInfo, 1>>(
928 JSRef<JSFunc>::Cast(jsValue), CreateJsAboutToIMEInputObj);
929 auto callback = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToIMEInputFunc)](
930 const InsertValueInfo& insertValue) -> bool {
931 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, true);
932 auto ret = func->ExecuteWithValue(insertValue);
933 if (ret->IsBoolean()) {
934 return ret->ToBoolean();
935 }
936 return true;
937 };
938 SearchModel::GetInstance()->SetOnWillInsertValueEvent(std::move(callback));
939 }
940
CreateJsDeleteToIMEObj(const DeleteValueInfo & deleteValueInfo)941 JSRef<JSVal> JSSearch::CreateJsDeleteToIMEObj(const DeleteValueInfo& deleteValueInfo)
942 {
943 JSRef<JSObject> aboutToIMEInputObj = JSRef<JSObject>::New();
944 aboutToIMEInputObj->SetProperty<int32_t>("deleteOffset", deleteValueInfo.deleteOffset);
945 aboutToIMEInputObj->SetProperty<int32_t>("direction", static_cast<int32_t>(deleteValueInfo.direction));
946 aboutToIMEInputObj->SetProperty<std::string>("deleteValue", deleteValueInfo.deleteValue);
947 return JSRef<JSVal>::Cast(aboutToIMEInputObj);
948 }
949
OnDidInsertValue(const JSCallbackInfo & info)950 void JSSearch::OnDidInsertValue(const JSCallbackInfo& info)
951 {
952 auto jsValue = info[0];
953 CHECK_NULL_VOID(jsValue->IsFunction());
954 auto jsAboutToIMEInputFunc = AceType::MakeRefPtr<JsEventFunction<InsertValueInfo, 1>>(
955 JSRef<JSFunc>::Cast(jsValue), CreateJsAboutToIMEInputObj);
956 auto callback = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToIMEInputFunc)](
957 const InsertValueInfo& insertValue) {
958 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
959 func->ExecuteWithValue(insertValue);
960 };
961 SearchModel::GetInstance()->SetOnDidInsertValueEvent(std::move(callback));
962 }
963
OnWillDelete(const JSCallbackInfo & info)964 void JSSearch::OnWillDelete(const JSCallbackInfo& info)
965 {
966 auto jsValue = info[0];
967 CHECK_NULL_VOID(jsValue->IsFunction());
968 auto jsAboutToIMEInputFunc =
969 AceType::MakeRefPtr<JsEventFunction<DeleteValueInfo, 1>>(JSRef<JSFunc>::Cast(jsValue), CreateJsDeleteToIMEObj);
970 auto callback = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToIMEInputFunc)](
971 const DeleteValueInfo& deleteValue) {
972 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, true);
973 auto ret = func->ExecuteWithValue(deleteValue);
974 if (ret->IsBoolean()) {
975 return ret->ToBoolean();
976 }
977 return true;
978 };
979 SearchModel::GetInstance()->SetOnWillDeleteEvent(std::move(callback));
980 }
981
OnDidDelete(const JSCallbackInfo & info)982 void JSSearch::OnDidDelete(const JSCallbackInfo& info)
983 {
984 auto jsValue = info[0];
985 CHECK_NULL_VOID(jsValue->IsFunction());
986 auto jsAboutToIMEInputFunc =
987 AceType::MakeRefPtr<JsEventFunction<DeleteValueInfo, 1>>(JSRef<JSFunc>::Cast(jsValue), CreateJsDeleteToIMEObj);
988 auto callback = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToIMEInputFunc)](
989 const DeleteValueInfo& deleteValue) {
990 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
991 func->ExecuteWithValue(deleteValue);
992 };
993 SearchModel::GetInstance()->SetOnDidDeleteEvent(std::move(callback));
994 }
995
SetSelectionMenuHidden(const JSCallbackInfo & info)996 void JSSearch::SetSelectionMenuHidden(const JSCallbackInfo& info)
997 {
998 if (info[0]->IsUndefined() || !info[0]->IsBoolean()) {
999 SearchModel::GetInstance()->SetSelectionMenuHidden(false);
1000 return;
1001 }
1002 SearchModel::GetInstance()->SetSelectionMenuHidden(info[0]->ToBoolean());
1003 }
1004
SetCustomKeyboard(const JSCallbackInfo & info)1005 void JSSearch::SetCustomKeyboard(const JSCallbackInfo& info)
1006 {
1007 if (info.Length() > 0 && (info[0]->IsUndefined() || info[0]->IsNull())) {
1008 SearchModel::GetInstance()->SetCustomKeyboard(nullptr);
1009 return;
1010 }
1011 if (info.Length() < 1 || !info[0]->IsObject()) {
1012 return;
1013 }
1014 bool supportAvoidance = false;
1015 if (info.Length() == 2 && info[1]->IsObject()) { // 2 here refers to the number of parameters
1016 auto paramObject = JSRef<JSObject>::Cast(info[1]);
1017 auto isSupportAvoidance = paramObject->GetProperty("supportAvoidance");
1018 if (!isSupportAvoidance->IsNull() && isSupportAvoidance->IsBoolean()) {
1019 supportAvoidance = isSupportAvoidance->ToBoolean();
1020 }
1021 }
1022 std::function<void()> buildFunc;
1023 if (JSTextField::ParseJsCustomKeyboardBuilder(info, 0, buildFunc)) {
1024 SearchModel::GetInstance()->SetCustomKeyboard(std::move(buildFunc), supportAvoidance);
1025 }
1026 }
1027
SetType(const JSCallbackInfo & info)1028 void JSSearch::SetType(const JSCallbackInfo& info)
1029 {
1030 if (info.Length() < 1) {
1031 return;
1032 }
1033 if (info[0]->IsUndefined()) {
1034 SearchModel::GetInstance()->SetType(TextInputType::UNSPECIFIED);
1035 return;
1036 }
1037 if (!info[0]->IsNumber()) {
1038 return;
1039 }
1040 TextInputType textInputType = CastToTextInputType(info[0]->ToNumber<int32_t>());
1041 SearchModel::GetInstance()->SetType(textInputType);
1042 }
1043
JSBind(BindingTarget globalObj)1044 void JSSearchController::JSBind(BindingTarget globalObj)
1045 {
1046 JSClass<JSTextEditableController>::Declare("SearchController");
1047 JSTextEditableController::JSBind(globalObj);
1048 }
1049
SetEnterKeyType(const JSCallbackInfo & info)1050 void JSSearch::SetEnterKeyType(const JSCallbackInfo& info)
1051 {
1052 if (info.Length() < 1) {
1053 return;
1054 }
1055 if (info[0]->IsUndefined()) {
1056 SearchModel::GetInstance()->SetSearchEnterKeyType(TextInputAction::SEARCH);
1057 return;
1058 }
1059 if (!info[0]->IsNumber()) {
1060 return;
1061 }
1062 TextInputAction textInputAction = CastToTextInputAction(info[0]->ToNumber<int32_t>());
1063 SearchModel::GetInstance()->SetSearchEnterKeyType(textInputAction);
1064 }
1065
SetMaxLength(const JSCallbackInfo & info)1066 void JSSearch::SetMaxLength(const JSCallbackInfo& info)
1067 {
1068 if (info.Length() < 1) {
1069 LOGI("The arg(SetMaxLength) is wrong, it is supposed to have atleast 1 argument");
1070 return;
1071 }
1072 int32_t maxLength = 0;
1073 if (info[0]->IsUndefined()) {
1074 SearchModel::GetInstance()->ResetMaxLength();
1075 return;
1076 } else if (!info[0]->IsNumber()) {
1077 SearchModel::GetInstance()->ResetMaxLength();
1078 return;
1079 }
1080 maxLength = info[0]->ToNumber<int32_t>();
1081 if (std::isinf(info[0]->ToNumber<float>())) {
1082 maxLength = INT32_MAX; // Infinity
1083 }
1084 if (GreatOrEqual(maxLength, 0)) {
1085 SearchModel::GetInstance()->SetMaxLength(maxLength);
1086 } else {
1087 SearchModel::GetInstance()->ResetMaxLength();
1088 }
1089 }
1090
SetDecoration(const JSCallbackInfo & info)1091 void JSSearch::SetDecoration(const JSCallbackInfo& info)
1092 {
1093 do {
1094 auto tmpInfo = info[0];
1095 if (!tmpInfo->IsObject()) {
1096 SearchModel::GetInstance()->SetTextDecoration(TextDecoration::NONE);
1097 SearchModel::GetInstance()->SetTextDecorationColor(Color::BLACK);
1098 SearchModel::GetInstance()->SetTextDecorationStyle(TextDecorationStyle::SOLID);
1099 break;
1100 }
1101 JSRef<JSObject> obj = JSRef<JSObject>::Cast(tmpInfo);
1102 JSRef<JSVal> typeValue = obj->GetProperty("type");
1103 JSRef<JSVal> colorValue = obj->GetProperty("color");
1104 JSRef<JSVal> styleValue = obj->GetProperty("style");
1105
1106 auto pipelineContext = PipelineBase::GetCurrentContext();
1107 CHECK_NULL_VOID(pipelineContext);
1108 auto theme = pipelineContext->GetTheme<SearchTheme>();
1109 CHECK_NULL_VOID(theme);
1110 TextDecoration textDecoration = theme->GetTextStyle().GetTextDecoration();
1111 if (typeValue->IsNumber()) {
1112 textDecoration = static_cast<TextDecoration>(typeValue->ToNumber<int32_t>());
1113 }
1114 Color result = theme->GetTextStyle().GetTextDecorationColor();
1115 ParseJsColor(colorValue, result, Color::BLACK);
1116 std::optional<TextDecorationStyle> textDecorationStyle;
1117 if (styleValue->IsNumber()) {
1118 textDecorationStyle = static_cast<TextDecorationStyle>(styleValue->ToNumber<int32_t>());
1119 } else {
1120 textDecorationStyle = DEFAULT_TEXT_DECORATION_STYLE;
1121 }
1122 SearchModel::GetInstance()->SetTextDecoration(textDecoration);
1123 SearchModel::GetInstance()->SetTextDecorationColor(result);
1124 if (textDecorationStyle) {
1125 SearchModel::GetInstance()->SetTextDecorationStyle(textDecorationStyle.value());
1126 }
1127 } while (false);
1128 }
1129
SetMinFontSize(const JSCallbackInfo & info)1130 void JSSearch::SetMinFontSize(const JSCallbackInfo& info)
1131 {
1132 if (info.Length() < 1) {
1133 return;
1134 }
1135 CalcDimension minFontSize;
1136 if (!ParseJsDimensionFpNG(info[0], minFontSize, false)) {
1137 SearchModel::GetInstance()->SetAdaptMinFontSize(CalcDimension());
1138 return;
1139 }
1140 if (minFontSize.IsNegative()) {
1141 minFontSize = CalcDimension();
1142 }
1143 SearchModel::GetInstance()->SetAdaptMinFontSize(minFontSize);
1144 }
1145
SetMaxFontSize(const JSCallbackInfo & info)1146 void JSSearch::SetMaxFontSize(const JSCallbackInfo& info)
1147 {
1148 if (info.Length() < 1) {
1149 return;
1150 }
1151 auto pipelineContext = PipelineBase::GetCurrentContext();
1152 CHECK_NULL_VOID(pipelineContext);
1153 auto theme = pipelineContext->GetTheme<SearchTheme>();
1154 CHECK_NULL_VOID(theme);
1155 CalcDimension maxFontSize = theme->GetTextStyle().GetAdaptMaxFontSize();
1156 if (!ParseJsDimensionFpNG(info[0], maxFontSize, false)) {
1157 maxFontSize = theme->GetTextStyle().GetAdaptMaxFontSize();
1158 SearchModel::GetInstance()->SetAdaptMaxFontSize(maxFontSize);
1159 return;
1160 }
1161 if (maxFontSize.IsNegative()) {
1162 maxFontSize = theme->GetTextStyle().GetAdaptMaxFontSize();
1163 }
1164 SearchModel::GetInstance()->SetAdaptMaxFontSize(maxFontSize);
1165 }
1166
SetLetterSpacing(const JSCallbackInfo & info)1167 void JSSearch::SetLetterSpacing(const JSCallbackInfo& info)
1168 {
1169 CalcDimension value;
1170 if (!ParseJsDimensionFpNG(info[0], value, false)) {
1171 value.Reset();
1172 SearchModel::GetInstance()->SetLetterSpacing(value);
1173 return;
1174 }
1175 SearchModel::GetInstance()->SetLetterSpacing(value);
1176 }
1177
SetLineHeight(const JSCallbackInfo & info)1178 void JSSearch::SetLineHeight(const JSCallbackInfo& info)
1179 {
1180 CalcDimension value;
1181 if (!ParseJsDimensionFpNG(info[0], value)) {
1182 value.Reset();
1183 SearchModel::GetInstance()->SetLineHeight(value);
1184 return;
1185 }
1186 if (value.IsNegative()) {
1187 value.Reset();
1188 }
1189 SearchModel::GetInstance()->SetLineHeight(value);
1190 }
1191
EditMenuOptions(const JSCallbackInfo & info)1192 void JSSearch::EditMenuOptions(const JSCallbackInfo& info)
1193 {
1194 NG::OnCreateMenuCallback onCreateMenuCallback;
1195 NG::OnMenuItemClickCallback onMenuItemClick;
1196 JSViewAbstract::ParseEditMenuOptions(info, onCreateMenuCallback, onMenuItemClick);
1197 SearchModel::GetInstance()->SetSelectionMenuOptions(std::move(onCreateMenuCallback), std::move(onMenuItemClick));
1198 }
1199
SetEnablePreviewText(const JSCallbackInfo & info)1200 void JSSearch::SetEnablePreviewText(const JSCallbackInfo& info)
1201 {
1202 auto jsValue = info[0];
1203 if (!jsValue->IsBoolean()) {
1204 SearchModel::GetInstance()->SetEnablePreviewText(true);
1205 return;
1206 }
1207 SearchModel::GetInstance()->SetEnablePreviewText(jsValue->ToBoolean());
1208 }
1209
SetEnableHapticFeedback(const JSCallbackInfo & info)1210 void JSSearch::SetEnableHapticFeedback(const JSCallbackInfo& info)
1211 {
1212 bool state = true;
1213 if (info.Length() > 0 && info[0]->IsBoolean()) {
1214 state = info[0]->ToBoolean();
1215 }
1216 SearchModel::GetInstance()->SetEnableHapticFeedback(state);
1217 }
1218 } // namespace OHOS::Ace::Framework
1219