/* * Copyright (c) 2021-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "bridge/declarative_frontend/jsview/js_search.h" #include #include #include "base/log/ace_scoring_log.h" #include "bridge/declarative_frontend/engine/functions/js_function.h" #include "bridge/declarative_frontend/jsview/js_text_editable_controller.h" #include "bridge/declarative_frontend/jsview/js_textfield.h" #include "bridge/declarative_frontend/jsview/js_textinput.h" #include "bridge/declarative_frontend/jsview/js_view_common_def.h" #include "bridge/declarative_frontend/jsview/models/search_model_impl.h" #include "core/components/common/layout/constants.h" #include "core/components/search/search_theme.h" #include "core/components_ng/pattern/search/search_model_ng.h" #include "core/components_ng/pattern/text_field/text_field_model_ng.h" namespace OHOS::Ace { std::unique_ptr SearchModel::instance_ = nullptr; std::mutex SearchModel::mutex_; SearchModel* SearchModel::GetInstance() { if (!instance_) { std::lock_guard lock(mutex_); if (!instance_) { #ifdef NG_BUILD instance_.reset(new NG::SearchModelNG()); #else if (Container::IsCurrentUseNewPipeline()) { instance_.reset(new NG::SearchModelNG()); } else { instance_.reset(new Framework::SearchModelImpl()); } #endif } } return instance_.get(); } } // namespace OHOS::Ace namespace OHOS::Ace::Framework { namespace { const std::vector TEXT_ALIGNS = { TextAlign::START, TextAlign::CENTER, TextAlign::END }; } // namespace void JSSearch::JSBind(BindingTarget globalObj) { JSClass::Declare("Search"); MethodOptions opt = MethodOptions::NONE; JSClass::StaticMethod("create", &JSSearch::Create, opt); JSClass::StaticMethod("searchButton", &JSSearch::SetSearchButton, opt); JSClass::StaticMethod("searchIcon", &JSSearch::SetSearchIcon, opt); JSClass::StaticMethod("cancelButton", &JSSearch::SetCancelButton, opt); JSClass::StaticMethod("fontColor", &JSSearch::SetTextColor, opt); JSClass::StaticMethod("caretStyle", &JSSearch::SetCaret, opt); JSClass::StaticMethod("placeholderColor", &JSSearch::SetPlaceholderColor, opt); JSClass::StaticMethod("placeholderFont", &JSSearch::SetPlaceholderFont, opt); JSClass::StaticMethod("textFont", &JSSearch::SetTextFont, opt); JSClass::StaticMethod("textAlign", &JSSearch::SetTextAlign, opt); JSClass::StaticMethod("onSubmit", &JSSearch::OnSubmit, opt); JSClass::StaticMethod("onChange", &JSSearch::OnChange, opt); JSClass::StaticMethod("onTextSelectionChange", &JSSearch::SetOnTextSelectionChange); JSClass::StaticMethod("onContentScroll", &JSSearch::SetOnScroll); JSClass::StaticMethod("border", &JSSearch::JsBorder); JSClass::StaticMethod("borderWidth", &JSSearch::JsBorderWidth); JSClass::StaticMethod("borderColor", &JSSearch::JsBorderColor); JSClass::StaticMethod("borderStyle", &JSSearch::JsBorderStyle); JSClass::StaticMethod("borderRadius", &JSSearch::JsBorderRadius); JSClass::StaticMethod("onTouch", &JSInteractableView::JsOnTouch); JSClass::StaticMethod("height", &JSSearch::SetHeight); JSClass::StaticMethod("width", &JSViewAbstract::JsWidth); JSClass::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey); JSClass::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete); JSClass::StaticMethod("onClick", &JSInteractableView::JsOnClick); JSClass::StaticMethod("requestKeyboardOnFocus", &JSSearch::SetEnableKeyboardOnFocus); JSClass::StaticMethod("enableKeyboardOnFocus", &JSSearch::SetEnableKeyboardOnFocus); JSClass::StaticMethod("onAppear", &JSInteractableView::JsOnAppear); JSClass::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear); JSClass::StaticMethod("onCopy", &JSSearch::SetOnCopy); JSClass::StaticMethod("onCut", &JSSearch::SetOnCut); JSClass::StaticMethod("onPaste", &JSSearch::SetOnPaste); JSClass::StaticMethod("copyOption", &JSSearch::SetCopyOption); JSClass::StaticMethod("textMenuOptions", &JSSearch::JsMenuOptionsExtension); JSClass::StaticMethod("selectionMenuHidden", &JSSearch::SetSelectionMenuHidden); JSClass::StaticMethod("customKeyboard", &JSSearch::SetCustomKeyboard); JSClass::StaticMethod("maxLength", &JSSearch::SetMaxLength); JSClass::StaticMethod("type", &JSSearch::SetType); JSClass::InheritAndBind(globalObj); } void ParseSearchValueObject(const JSCallbackInfo& info, const JSRef& changeEventVal) { CHECK_NULL_VOID(changeEventVal->IsFunction()); JsEventCallback onChangeEvent( info.GetExecutionContext(), JSRef::Cast(changeEventVal)); SearchModel::GetInstance()->SetOnChangeEvent(std::move(onChangeEvent)); } void JSSearch::Create(const JSCallbackInfo& info) { std::optional key; std::optional tip; std::optional src; JSTextEditableController* jsController = nullptr; JSRef changeEventVal; if (info[0]->IsObject()) { auto param = JSRef::Cast(info[0]); std::string placeholder; if (param->GetProperty("placeholder")->IsUndefined()) { tip = ""; } if (ParseJsString(param->GetProperty("placeholder"), placeholder)) { tip = placeholder; } std::string text; JSRef textValue = param->GetProperty("value"); if (textValue->IsObject()) { JSRef valueObj = JSRef::Cast(textValue); changeEventVal = valueObj->GetProperty("changeEvent"); if (changeEventVal->IsFunction()) { textValue = valueObj->GetProperty("value"); } if (ParseJsString(textValue, text)) { key = text; } } else if (param->HasProperty("value") && textValue->IsUndefined()) { key = ""; } else { if (ParseJsString(textValue, text)) { key = text; } } std::string icon; if (ParseJsString(param->GetProperty("icon"), icon)) { src = icon; } auto controllerObj = param->GetProperty("controller"); if (!controllerObj->IsUndefined() && !controllerObj->IsNull()) { jsController = JSRef::Cast(controllerObj)->Unwrap(); } } auto controller = SearchModel::GetInstance()->Create(key, tip, src); if (jsController) { jsController->SetController(controller); } SearchModel::GetInstance()->SetFocusable(true); SearchModel::GetInstance()->SetFocusNode(true); if (!changeEventVal->IsUndefined() && changeEventVal->IsFunction()) { ParseSearchValueObject(info, changeEventVal); } } void JSSearch::SetEnableKeyboardOnFocus(const JSCallbackInfo& info) { if (info[0]->IsUndefined() || !info[0]->IsBoolean()) { SearchModel::GetInstance()->RequestKeyboardOnFocus(true); return; } SearchModel::GetInstance()->RequestKeyboardOnFocus(info[0]->ToBoolean()); } void JSSearch::SetSearchButton(const JSCallbackInfo& info) { auto theme = GetTheme(); CHECK_NULL_VOID(theme); std::string buttonValue; if (!ParseJsString(info[0], buttonValue)) { return; } SearchModel::GetInstance()->SetSearchButton(buttonValue); SearchModel::GetInstance()->SetSearchButtonFontSize(theme->GetFontSize()); SearchModel::GetInstance()->SetSearchButtonFontColor(theme->GetSearchButtonTextColor()); if (info[1]->IsObject()) { auto param = JSRef::Cast(info[1]); // set button font size, unit FP auto fontSize = param->GetProperty("fontSize"); CalcDimension size = theme->GetFontSize(); if (ParseJsDimensionVpNG(fontSize, size) && size.Unit() != DimensionUnit::PERCENT && GreatOrEqual(size.Value(), 0.0)) { ParseJsDimensionFp(fontSize, size); } else { size = theme->GetFontSize(); } SearchModel::GetInstance()->SetSearchButtonFontSize(size); // set font color Color fontColor; auto fontColorProp = param->GetProperty("fontColor"); if (fontColorProp->IsUndefined() || fontColorProp->IsNull() || !ParseJsColor(fontColorProp, fontColor)) { fontColor = theme->GetSearchButtonTextColor(); } SearchModel::GetInstance()->SetSearchButtonFontColor(fontColor); } } void JSSearch::SetSearchIcon(const JSCallbackInfo& info) { if (info[0]->IsObject()) { auto param = JSRef::Cast(info[0]); auto theme = GetTheme(); CHECK_NULL_VOID(theme); // set icon size CalcDimension size; auto sizeProp = param->GetProperty("size"); if (!sizeProp->IsUndefined() && !sizeProp->IsNull() && ParseJsDimensionVpNG(sizeProp, size)) { if (LessNotEqual(size.Value(), 0.0) || size.Unit() == DimensionUnit::PERCENT) { size = theme->GetIconHeight(); } } else { size = theme->GetIconHeight(); } SearchModel::GetInstance()->SetSearchIconSize(size); // set icon src std::string src; auto srcPathProp = param->GetProperty("src"); if (srcPathProp->IsUndefined() || srcPathProp->IsNull() || !ParseJsMedia(srcPathProp, src)) { src = ""; } std::string bundleName; std::string moduleName; GetJsMediaBundleInfo(srcPathProp, bundleName, moduleName); SearchModel::GetInstance()->SetSearchSrcPath(src, bundleName, moduleName); // set icon color Color colorVal; auto colorProp = param->GetProperty("color"); if (!colorProp->IsUndefined() && !colorProp->IsNull() && ParseJsColor(colorProp, colorVal)) { SearchModel::GetInstance()->SetSearchIconColor(colorVal); } } } static CancelButtonStyle ConvertStrToCancelButtonStyle(const std::string& value) { if (value == "CONSTANT") { return CancelButtonStyle::CONSTANT; } else if (value == "INVISIBLE") { return CancelButtonStyle::INVISIBLE; } else { return CancelButtonStyle::INPUT; } } void JSSearch::SetCancelButton(const JSCallbackInfo& info) { if (!info[0]->IsObject()) { return; } auto param = JSRef::Cast(info[0]); auto theme = GetTheme(); CHECK_NULL_VOID(theme); // set style std::string styleStr; CancelButtonStyle cancelButtonStyle; auto styleProp = param->GetProperty("style"); if (!styleProp->IsUndefined() && !styleProp->IsNull() && ParseJsString(styleProp, styleStr)) { cancelButtonStyle = ConvertStrToCancelButtonStyle(styleStr); } else { cancelButtonStyle = theme->GetCancelButtonStyle(); } SearchModel::GetInstance()->SetCancelButtonStyle(cancelButtonStyle); auto iconProp = param->GetProperty("icon"); if (iconProp->IsUndefined() || iconProp->IsNull()) { SearchModel::GetInstance()->SetCancelIconSize(theme->GetIconHeight()); SearchModel::GetInstance()->SetCancelIconColor(theme->GetSearchIconColor()); SearchModel::GetInstance()->SetRightIconSrcPath(""); } else { SetIconStyle(info); } } void JSSearch::SetIconStyle(const JSCallbackInfo& info) { if (!info[0]->IsObject()) { return; } auto param = JSRef::Cast(info[0]); auto iconJsVal = param->GetProperty("icon"); if (!iconJsVal->IsObject()) { return; } auto iconParam = JSRef::Cast(iconJsVal); // set icon size CalcDimension iconSize; auto iconSizeProp = iconParam->GetProperty("size"); auto theme = GetTheme(); if (!iconSizeProp->IsUndefined() && !iconSizeProp->IsNull() && ParseJsDimensionVpNG(iconSizeProp, iconSize)) { if (LessNotEqual(iconSize.Value(), 0.0) || iconSize.Unit() == DimensionUnit::PERCENT) { iconSize = theme->GetIconHeight(); } } else { iconSize = theme->GetIconHeight(); } SearchModel::GetInstance()->SetCancelIconSize(iconSize); // set icon src std::string iconSrc; auto iconSrcProp = iconParam->GetProperty("src"); if (iconSrcProp->IsUndefined() || iconSrcProp->IsNull() || !ParseJsMedia(iconSrcProp, iconSrc)) { iconSrc = ""; } SearchModel::GetInstance()->SetRightIconSrcPath(iconSrc); // set icon color Color iconColor; auto iconColorProp = iconParam->GetProperty("color"); if (!iconColorProp->IsUndefined() && !iconColorProp->IsNull() && ParseJsColor(iconColorProp, iconColor)) { SearchModel::GetInstance()->SetCancelIconColor(iconColor); } } void JSSearch::SetTextColor(const JSCallbackInfo& info) { auto theme = GetTheme(); CHECK_NULL_VOID(theme); auto value = JSRef::Cast(info[0]); Color colorVal; if (!ParseJsColor(value, colorVal)) { colorVal = theme->GetTextColor(); } SearchModel::GetInstance()->SetTextColor(colorVal); } void JSSearch::SetCaret(const JSCallbackInfo& info) { if (info[0]->IsObject()) { auto param = JSRef::Cast(info[0]); auto textFieldTheme = GetTheme(); CHECK_NULL_VOID(textFieldTheme); // set caret width CalcDimension caretWidth = textFieldTheme->GetCursorWidth(); auto caretWidthProp = param->GetProperty("width"); if (!ParseJsDimensionVpNG(caretWidthProp, caretWidth, false) || LessNotEqual(caretWidth.Value(), 0.0)) { caretWidth = textFieldTheme->GetCursorWidth(); } SearchModel::GetInstance()->SetCaretWidth(caretWidth); // set caret color Color caretColor; auto caretColorProp = param->GetProperty("color"); if (caretColorProp->IsUndefined() || caretColorProp->IsNull() || !ParseJsColor(caretColorProp, caretColor)) { caretColor = textFieldTheme->GetCursorColor(); } SearchModel::GetInstance()->SetCaretColor(caretColor); } } void JSSearch::SetPlaceholderColor(const JSCallbackInfo& info) { auto value = JSRef::Cast(info[0]); Color colorVal; if (!ParseJsColor(value, colorVal)) { auto theme = GetTheme(); CHECK_NULL_VOID(theme); colorVal = theme->GetPlaceholderColor(); } SearchModel::GetInstance()->SetPlaceholderColor(colorVal); } void JSSearch::SetPlaceholderFont(const JSCallbackInfo& info) { if (!info[0]->IsObject()) { return; } auto param = JSRef::Cast(info[0]); auto theme = GetTheme(); CHECK_NULL_VOID(theme); auto themeFontSize = theme->GetFontSize(); Font font; auto fontSize = param->GetProperty("size"); if (fontSize->IsNull() || fontSize->IsUndefined()) { font.fontSize = themeFontSize; } else { auto versionTenOrLarger = Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN); CalcDimension size; if ((versionTenOrLarger ? ParseJsDimensionVpNG(fontSize, size) : ParseJsDimensionVp(fontSize, size)) && size.Unit() != DimensionUnit::PERCENT) { ParseJsDimensionFp(fontSize, size); font.fontSize = size; } else { font.fontSize = themeFontSize; } } auto weight = param->GetProperty("weight"); if (!weight->IsNull()) { std::string weightVal; if (weight->IsNumber()) { weightVal = std::to_string(weight->ToNumber()); } else { ParseJsString(weight, weightVal); } font.fontWeight = ConvertStrToFontWeight(weightVal); } auto family = param->GetProperty("family"); if (!family->IsNull() && family->IsString()) { auto familyVal = family->ToString(); font.fontFamilies = ConvertStrToFontFamilies(familyVal); } auto style = param->GetProperty("style"); if (!style->IsNull() && style->IsNumber()) { FontStyle styleVal = static_cast(style->ToNumber()); font.fontStyle = styleVal; } SearchModel::GetInstance()->SetPlaceholderFont(font); } void JSSearch::SetTextFont(const JSCallbackInfo& info) { if (info.Length() < 1 || !info[0]->IsObject()) { return; } auto param = JSRef::Cast(info[0]); auto theme = GetTheme(); CHECK_NULL_VOID(theme); auto themeFontSize = theme->GetFontSize(); Font font; auto fontSize = param->GetProperty("size"); CalcDimension size = themeFontSize; if (ParseJsDimensionVpNG(fontSize, size) && size.Unit() != DimensionUnit::PERCENT && GreatOrEqual(size.Value(), 0.0)) { ParseJsDimensionFp(fontSize, size); } else { size = themeFontSize; } font.fontSize = size; auto weight = param->GetProperty("weight"); if (!weight->IsNull()) { std::string weightVal; if (weight->IsNumber()) { weightVal = std::to_string(weight->ToNumber()); } else { ParseJsString(weight, weightVal); } font.fontWeight = ConvertStrToFontWeight(weightVal); } auto family = param->GetProperty("family"); if (!family->IsNull() && family->IsString()) { auto familyVal = family->ToString(); font.fontFamilies = ConvertStrToFontFamilies(familyVal); } auto style = param->GetProperty("style"); if (!style->IsNull() && style->IsNumber()) { FontStyle styleVal = static_cast(style->ToNumber()); font.fontStyle = styleVal; } SearchModel::GetInstance()->SetTextFont(font); } void JSSearch::SetTextAlign(int32_t value) { if (value >= 0 && value < static_cast(TEXT_ALIGNS.size())) { SearchModel::GetInstance()->SetTextAlign(TEXT_ALIGNS[value]); } } void JSSearch::JsBorder(const JSCallbackInfo& info) { JSViewAbstract::JsBorder(info); if (!info[0]->IsObject()) { return; } RefPtr decoration = nullptr; JSRef object = JSRef::Cast(info[0]); auto valueWidth = object->GetProperty("width"); if (!valueWidth->IsUndefined()) { ParseBorderWidth(valueWidth); } auto valueColor = object->GetProperty("color"); if (!valueColor->IsUndefined()) { ParseBorderColor(valueColor); } auto valueRadius = object->GetProperty("radius"); if (!valueRadius->IsUndefined()) { ParseBorderRadius(valueRadius); } auto valueStyle = object->GetProperty("style"); if (!valueStyle->IsUndefined()) { ParseBorderStyle(valueStyle); } SearchModel::GetInstance()->SetBackBorder(); info.ReturnSelf(); } void JSSearch::JsBorderWidth(const JSCallbackInfo& info) { JSViewAbstract::JsBorderWidth(info); if (!info[0]->IsObject() && !info[0]->IsString() && !info[0]->IsNumber()) { return; } SearchModel::GetInstance()->SetBackBorder(); } void JSSearch::JsBorderColor(const JSCallbackInfo& info) { JSViewAbstract::JsBorderColor(info); if (!info[0]->IsObject() && !info[0]->IsString() && !info[0]->IsNumber()) { return; } SearchModel::GetInstance()->SetBackBorder(); } void JSSearch::JsBorderStyle(const JSCallbackInfo& info) { JSViewAbstract::JsBorderStyle(info); if (!info[0]->IsObject() && !info[0]->IsNumber()) { return; } SearchModel::GetInstance()->SetBackBorder(); } void JSSearch::JsBorderRadius(const JSCallbackInfo& info) { JSViewAbstract::JsBorderRadius(info); if (!info[0]->IsObject() && !info[0]->IsString() && !info[0]->IsNumber()) { return; } SearchModel::GetInstance()->SetBackBorder(); } void JSSearch::OnSubmit(const JSCallbackInfo& info) { CHECK_NULL_VOID(info[0]->IsFunction()); JsEventCallback callback(info.GetExecutionContext(), JSRef::Cast(info[0])); SearchModel::GetInstance()->SetOnSubmit(std::move(callback)); } void JSSearch::OnChange(const JSCallbackInfo& info) { CHECK_NULL_VOID(info[0]->IsFunction()); JsEventCallback callback(info.GetExecutionContext(), JSRef::Cast(info[0])); SearchModel::GetInstance()->SetOnChange(std::move(callback)); } void JSSearch::SetOnTextSelectionChange(const JSCallbackInfo& info) { CHECK_NULL_VOID(info[0]->IsFunction()); JsEventCallback callback(info.GetExecutionContext(), JSRef::Cast(info[0])); SearchModel::GetInstance()->SetOnTextSelectionChange(std::move(callback)); } void JSSearch::SetOnScroll(const JSCallbackInfo& info) { CHECK_NULL_VOID(info[0]->IsFunction()); JsEventCallback callback(info.GetExecutionContext(), JSRef::Cast(info[0])); SearchModel::GetInstance()->SetOnScroll(std::move(callback)); } void JSSearch::SetHeight(const JSCallbackInfo& info) { JSViewAbstract::JsHeight(info); CalcDimension value; auto versionTenOrLarger = Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN); if (versionTenOrLarger ? !ParseJsDimensionVpNG(info[0], value) : !ParseJsDimensionVp(info[0], value)) { return; } if (LessNotEqual(value.Value(), 0.0)) { value.SetValue(0.0); } SearchModel::GetInstance()->SetHeight(value); } void JSSearch::SetOnCopy(const JSCallbackInfo& info) { CHECK_NULL_VOID(info[0]->IsFunction()); JsEventCallback callback(info.GetExecutionContext(), JSRef::Cast(info[0])); SearchModel::GetInstance()->SetOnCopy(std::move(callback)); } void JSSearch::SetOnCut(const JSCallbackInfo& info) { CHECK_NULL_VOID(info[0]->IsFunction()); JsEventCallback callback(info.GetExecutionContext(), JSRef::Cast(info[0])); SearchModel::GetInstance()->SetOnCut(std::move(callback)); } JSRef JSSearch::CreateJSTextCommonEvent(NG::TextCommonEvent& event) { JSRef objectTemplate = JSRef::New(); objectTemplate->SetInternalFieldCount(1); JSRef object = objectTemplate->NewInstance(); object->SetPropertyObject("preventDefault", JSRef::New(JsPreventDefault)); object->Wrap(&event); return JSRef::Cast(object); } void JSSearch::SetOnPaste(const JSCallbackInfo& info) { CHECK_NULL_VOID(info[0]->IsFunction()); auto jsTextFunc = AceType::MakeRefPtr>( JSRef::Cast(info[0]), CreateJSTextCommonEvent); auto onPaste = [execCtx = info.GetExecutionContext(), func = std::move(jsTextFunc)]( const std::string& val, NG::TextCommonEvent& info) { JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); ACE_SCORING_EVENT("onPaste"); func->Execute(val, info); }; SearchModel::GetInstance()->SetOnPasteWithEvent(std::move(onPaste)); } void JSSearch::SetCopyOption(const JSCallbackInfo& info) { if (info.Length() == 0) { return; } if (info[0]->IsUndefined()) { SearchModel::GetInstance()->SetCopyOption(CopyOptions::Local); return; } auto copyOptions = CopyOptions::None; if (info[0]->IsNumber()) { auto emunNumber = info[0]->ToNumber(); copyOptions = static_cast(emunNumber); } SearchModel::GetInstance()->SetCopyOption(copyOptions); } void JSSearch::JsMenuOptionsExtension(const JSCallbackInfo& info) { if (info[0]->IsArray()) { std::vector menuOptionsItems; JSViewAbstract::ParseMenuOptions(info, JSRef::Cast(info[0]), menuOptionsItems); SearchModel::GetInstance()->SetMenuOptionItems(std::move(menuOptionsItems)); } } void JSSearch::SetSelectionMenuHidden(const JSCallbackInfo& info) { if (info[0]->IsUndefined() || !info[0]->IsBoolean()) { SearchModel::GetInstance()->SetSelectionMenuHidden(false); return; } SearchModel::GetInstance()->SetSelectionMenuHidden(info[0]->ToBoolean()); } void JSSearch::SetCustomKeyboard(const JSCallbackInfo& info) { if (info.Length() > 0 && (info[0]->IsUndefined() || info[0]->IsNull())) { SearchModel::GetInstance()->SetCustomKeyboard(nullptr); return; } if (info.Length() < 1 || !info[0]->IsObject()) { return; } std::function buildFunc; if (JSTextField::ParseJsCustomKeyboardBuilder(info, 0, buildFunc)) { SearchModel::GetInstance()->SetCustomKeyboard(std::move(buildFunc)); } } void JSSearch::SetType(const JSCallbackInfo& info) { if (info.Length() < 1) { return; } if (info[0]->IsUndefined()) { SearchModel::GetInstance()->SetType(TextInputType::UNSPECIFIED); return; } if (!info[0]->IsNumber()) { return; } TextInputType textInputType = static_cast(info[0]->ToNumber()); SearchModel::GetInstance()->SetType(textInputType); } void JSSearchController::JSBind(BindingTarget globalObj) { JSClass::Declare("SearchController"); JSTextEditableController::JSBind(globalObj); } void JSSearch::SetMaxLength(const JSCallbackInfo& info) { int32_t maxLength = 0; if (info[0]->IsUndefined()) { SearchModel::GetInstance()->ResetMaxLength(); return; } else if (!info[0]->IsNumber()) { SearchModel::GetInstance()->ResetMaxLength(); return; } maxLength = info[0]->ToNumber(); if (GreatOrEqual(maxLength, 0)) { SearchModel::GetInstance()->SetMaxLength(maxLength); } else { SearchModel::GetInstance()->ResetMaxLength(); } } } // namespace OHOS::Ace::Framework