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_indexer.h"
17 
18 #include "base/geometry/dimension.h"
19 #include "base/log/ace_scoring_log.h"
20 #include "base/utils/utils.h"
21 #include "bridge/declarative_frontend/jsview/js_interactable_view.h"
22 #include "bridge/declarative_frontend/jsview/js_scroller.h"
23 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
24 #include "bridge/declarative_frontend/jsview/models/indexer_model_impl.h"
25 #include "bridge/declarative_frontend/ark_theme/theme_apply/js_indexer_theme.h"
26 #include "core/components/common/layout/constants.h"
27 #include "core/components/common/properties/decoration.h"
28 #include "core/components/common/properties/text_style.h"
29 #include "core/components/indexer/indexer_theme.h"
30 #include "core/components_ng/pattern/indexer/indexer_model_ng.h"
31 
32 namespace OHOS::Ace {
33 std::unique_ptr<IndexerModel> IndexerModel::instance_ = nullptr;
34 std::mutex IndexerModel::mutex_;
GetInstance()35 IndexerModel* IndexerModel::GetInstance()
36 {
37     if (!instance_) {
38         std::lock_guard<std::mutex> lock(mutex_);
39         if (!instance_) {
40 #ifdef NG_BUILD
41             instance_.reset(new NG::IndexerModelNG());
42 #else
43             if (Container::IsCurrentUseNewPipeline()) {
44                 instance_.reset(new NG::IndexerModelNG());
45             } else {
46                 instance_.reset(new Framework::IndexerModelImpl());
47             }
48 #endif
49         }
50     }
51     return instance_.get();
52 }
53 } // namespace OHOS::Ace
54 
55 namespace OHOS::Ace::Framework {
56 namespace {
57 const std::vector<FontStyle> FONT_STYLES = { FontStyle::NORMAL, FontStyle::ITALIC };
58 const std::vector<V2::AlignStyle> ALIGN_STYLE = { V2::AlignStyle::LEFT, V2::AlignStyle::RIGHT, V2::AlignStyle::START,
59     V2::AlignStyle::END };
60 const std::vector<NG::AlignStyle> NG_ALIGN_STYLE = { NG::AlignStyle::LEFT, NG::AlignStyle::RIGHT, NG::AlignStyle::START,
61     NG::AlignStyle::END };
62 constexpr Dimension DEFAULT_ITEM_SIZE = 16.0_vp;
63 constexpr double ZERO_RADIUS = 0.0;
64 constexpr double POPUP_ITEM_DEFAULT_RADIUS = 24.0;
65 constexpr double ITEM_DEFAULT_RADIUS = 8.0;
66 constexpr double RADIUS_OFFSET = 4.0;
67 }; // namespace
68 
ParseIndexerSelectedObject(const JSCallbackInfo & info,const JSRef<JSVal> & changeEventVal,bool isMethodProp=false)69 void JSIndexer::ParseIndexerSelectedObject(
70     const JSCallbackInfo& info, const JSRef<JSVal>& changeEventVal, bool isMethodProp = false)
71 {
72     CHECK_NULL_VOID(changeEventVal->IsFunction());
73     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
74     auto changeEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const int32_t selected) {
75         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
76         ACE_SCORING_EVENT("Indexer.SelectedChangeEvent");
77         auto newJSVal = JSRef<JSVal>::Make(ToJSValue(selected));
78         func->ExecuteJS(1, &newJSVal);
79     };
80 
81     if (isMethodProp) {
82         IndexerModel::GetInstance()->SetChangeEvent(changeEvent);
83     } else {
84         IndexerModel::GetInstance()->SetCreatChangeEvent(changeEvent);
85     }
86 }
87 
Create(const JSCallbackInfo & args)88 void JSIndexer::Create(const JSCallbackInfo& args)
89 {
90     if (args.Length() < 1 || !args[0]->IsObject()) {
91         return;
92     }
93     size_t length = 0;
94     int32_t selectedVal = 0;
95     std::vector<std::string> indexerArray;
96     JSRef<JSObject> paramObj = JSRef<JSObject>::Cast(args[0]);
97     JSRef<JSVal> arrayVal = paramObj->GetProperty("arrayValue");
98     if (arrayVal->IsArray()) {
99         JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(arrayVal);
100         length = jsArray->Length();
101         for (size_t i = 0; i < length; i++) {
102             auto value = jsArray->GetValueAt(i);
103             if (value->IsString()) {
104                 indexerArray.emplace_back(value->ToString());
105             }
106         }
107     }
108 
109     JSRef<JSVal> selectedProperty = paramObj->GetProperty("selected");
110     if (selectedProperty->IsNumber()) {
111         selectedVal = selectedProperty->ToNumber<int32_t>();
112         IndexerModel::GetInstance()->Create(indexerArray, selectedVal);
113         JSIndexerTheme::ApplyTheme();
114     } else if (length > 0 && selectedProperty->IsObject()) {
115         JSRef<JSObject> selectedObj = JSRef<JSObject>::Cast(selectedProperty);
116         auto selectedValueProperty = selectedObj->GetProperty("value");
117         if (selectedValueProperty->IsNumber()) {
118             selectedVal = selectedValueProperty->ToNumber<int32_t>();
119         }
120         IndexerModel::GetInstance()->Create(indexerArray, selectedVal);
121         JSIndexerTheme::ApplyTheme();
122         JSRef<JSVal> changeEventVal = selectedObj->GetProperty("changeEvent");
123         if (!changeEventVal.IsEmpty()) {
124             if (!changeEventVal->IsUndefined() && changeEventVal->IsFunction()) {
125                 ParseIndexerSelectedObject(args, changeEventVal);
126             }
127             return;
128         }
129 
130         args.ReturnSelf();
131     } else {
132         IndexerModel::GetInstance()->Create(indexerArray, selectedVal);
133         JSIndexerTheme::ApplyTheme();
134     }
135 }
136 
SetSelectedColor(const JSCallbackInfo & args)137 void JSIndexer::SetSelectedColor(const JSCallbackInfo& args)
138 {
139     if (args.Length() < 1) {
140         return;
141     }
142     IndexerModel::GetInstance()->SetSelectedColor(PaseColor(args));
143 }
144 
SetColor(const JSCallbackInfo & args)145 void JSIndexer::SetColor(const JSCallbackInfo& args)
146 {
147     if (args.Length() < 1) {
148         return;
149     }
150     IndexerModel::GetInstance()->SetColor(PaseColor(args));
151 }
152 
SetPopupColor(const JSCallbackInfo & args)153 void JSIndexer::SetPopupColor(const JSCallbackInfo& args)
154 {
155     if (args.Length() < 1) {
156         return;
157     }
158     IndexerModel::GetInstance()->SetPopupColor(PaseColor(args));
159 }
160 
SetSelectedBackgroundColor(const JSCallbackInfo & args)161 void JSIndexer::SetSelectedBackgroundColor(const JSCallbackInfo& args)
162 {
163     if (args.Length() < 1) {
164         return;
165     }
166     IndexerModel::GetInstance()->SetSelectedBackgroundColor(PaseColor(args));
167 }
168 
SetPopupBackground(const JSCallbackInfo & args)169 void JSIndexer::SetPopupBackground(const JSCallbackInfo& args)
170 {
171     if (args.Length() < 1) {
172         return;
173     }
174     IndexerModel::GetInstance()->SetPopupBackground(PaseColor(args));
175 }
176 
SetUsingPopup(bool state)177 void JSIndexer::SetUsingPopup(bool state)
178 {
179     IndexerModel::GetInstance()->SetUsingPopup(state);
180 }
181 
SetSelectedFont(const JSCallbackInfo & args)182 void JSIndexer::SetSelectedFont(const JSCallbackInfo& args)
183 {
184     if (args.Length() < 1) {
185         return;
186     }
187     std::optional<Dimension> fontSize;
188     std::optional<FontWeight> fontWeight;
189     std::optional<std::vector<std::string>> fontFamily;
190     std::optional<FontStyle> fontStyle;
191     if (args[0]->IsObject()) {
192         GetFontContent(args, fontSize, fontWeight, fontFamily, fontStyle);
193     }
194     IndexerModel::GetInstance()->SetSelectedFont(fontSize, fontWeight, fontFamily, fontStyle);
195 }
196 
SetPopupFont(const JSCallbackInfo & args)197 void JSIndexer::SetPopupFont(const JSCallbackInfo& args)
198 {
199     if (args.Length() < 1) {
200         return;
201     }
202     std::optional<Dimension> fontSize;
203     std::optional<FontWeight> fontWeight;
204     std::optional<std::vector<std::string>> fontFamily;
205     std::optional<FontStyle> fontStyle;
206     if (args[0]->IsObject()) {
207         GetFontContent(args, fontSize, fontWeight, fontFamily, fontStyle);
208     }
209     IndexerModel::GetInstance()->SetPopupFont(fontSize, fontWeight, fontFamily, fontStyle);
210 }
211 
SetFont(const JSCallbackInfo & args)212 void JSIndexer::SetFont(const JSCallbackInfo& args)
213 {
214     if (args.Length() < 1) {
215         return;
216     }
217     std::optional<Dimension> fontSize;
218     std::optional<FontWeight> fontWeight;
219     std::optional<std::vector<std::string>> fontFamily;
220     std::optional<FontStyle> fontStyle;
221     if (args[0]->IsObject()) {
222         GetFontContent(args, fontSize, fontWeight, fontFamily, fontStyle);
223     }
224     IndexerModel::GetInstance()->SetFont(fontSize, fontWeight, fontFamily, fontStyle);
225 }
226 
JsOnSelected(const JSCallbackInfo & args)227 void JSIndexer::JsOnSelected(const JSCallbackInfo& args)
228 {
229     if (args[0]->IsFunction()) {
230         auto onSelected = [execCtx = args.GetExecutionContext(), func = JSRef<JSFunc>::Cast(args[0])](
231                               const int32_t selected) {
232             JAVASCRIPT_EXECUTION_SCOPE(execCtx);
233             auto params = ConvertToJSValues(selected);
234             func->Call(JSRef<JSObject>(), params.size(), params.data());
235         };
236         IndexerModel::GetInstance()->SetOnSelected(onSelected);
237     }
238 }
239 
JsOnRequestPopupData(const JSCallbackInfo & args)240 void JSIndexer::JsOnRequestPopupData(const JSCallbackInfo& args)
241 {
242     if (args[0]->IsFunction()) {
243         auto requestPopupData = [execCtx = args.GetExecutionContext(), func = JSRef<JSFunc>::Cast(args[0])](
244                                     const int32_t selected) {
245             std::vector<std::string> popupData;
246             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, popupData);
247             auto params = ConvertToJSValues(selected);
248             JSRef<JSArray> result = func->Call(JSRef<JSObject>(), params.size(), params.data());
249             if (result.IsEmpty()) {
250                 return popupData;
251             }
252 
253             if (!result->IsArray()) {
254                 return popupData;
255             }
256 
257             for (size_t i = 0; i < result->Length(); i++) {
258                 if (result->GetValueAt(i)->IsString()) {
259                     auto item = result->GetValueAt(i);
260                     popupData.emplace_back(item->ToString());
261                 }
262             }
263             return popupData;
264         };
265         IndexerModel::GetInstance()->SetOnRequestPopupData(requestPopupData);
266     }
267 }
268 
JsOnPopupSelected(const JSCallbackInfo & args)269 void JSIndexer::JsOnPopupSelected(const JSCallbackInfo& args)
270 {
271     if (args[0]->IsFunction()) {
272         auto onPopupSelected = [execCtx = args.GetExecutionContext(), func = JSRef<JSFunc>::Cast(args[0])](
273                                    const int32_t selected) {
274             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
275             auto params = ConvertToJSValues(selected);
276             func->Call(JSRef<JSObject>(), params.size(), params.data());
277         };
278         IndexerModel::GetInstance()->SetOnPopupSelected(onPopupSelected);
279     }
280 }
281 
GetFontContent(const JSCallbackInfo & args,std::optional<Dimension> & fontSize,std::optional<FontWeight> & fontWeight,std::optional<std::vector<std::string>> & fontFamily,std::optional<FontStyle> & fontStyle)282 void JSIndexer::GetFontContent(const JSCallbackInfo& args, std::optional<Dimension>& fontSize,
283     std::optional<FontWeight>& fontWeight, std::optional<std::vector<std::string>>& fontFamily,
284     std::optional<FontStyle>& fontStyle)
285 {
286     JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
287     JSRef<JSVal> size = obj->GetProperty("size");
288     CalcDimension fontSizeData;
289     if (ParseJsDimensionFp(size, fontSizeData) && !fontSizeData.IsNegative() &&
290         fontSizeData.Unit() != DimensionUnit::PERCENT) {
291         fontSize = fontSizeData;
292     }
293 
294     JSRef<JSVal> weight = obj->GetProperty("weight");
295     if (weight->IsString() || weight->IsNumber()) {
296         fontWeight = ConvertStrToFontWeight(weight->ToString());
297     }
298 
299     JSRef<JSVal> family = obj->GetProperty("family");
300     std::vector<std::string> fontFamilies;
301     if (ParseJsFontFamilies(family, fontFamilies)) {
302         fontFamily = fontFamilies;
303     }
304 
305     JSRef<JSVal> style = obj->GetProperty("style");
306     if (style->IsNumber()) {
307         int32_t value = style->ToNumber<int32_t>();
308         if (value >= 0 && value < static_cast<int32_t>(FONT_STYLES.size())) {
309             fontStyle = FONT_STYLES[value];
310         }
311     }
312 }
313 
SetItemSize(const JSCallbackInfo & args)314 void JSIndexer::SetItemSize(const JSCallbackInfo& args)
315 {
316     if (args.Length() < 1) {
317         return;
318     }
319     CalcDimension itemSize;
320     if (ParseJsDimensionVp(args[0], itemSize) && GreatNotEqual(itemSize.Value(), 0.0) &&
321         itemSize.Unit() != DimensionUnit::PERCENT) {
322         IndexerModel::GetInstance()->SetItemSize(itemSize);
323         return;
324     }
325     IndexerModel::GetInstance()->SetItemSize(DEFAULT_ITEM_SIZE);
326 }
327 
SetAlignStyle(const JSCallbackInfo & args)328 void JSIndexer::SetAlignStyle(const JSCallbackInfo& args)
329 {
330     if (args.Length() < 1) {
331         return;
332     }
333     int32_t value = Container::IsCurrentUseNewPipeline() ? static_cast<int32_t>(NG::AlignStyle::END)
334                                                          : static_cast<int32_t>(V2::AlignStyle::END);
335     auto alignValue = -1;
336     if (args[0]->IsNumber()) {
337         alignValue = args[0]->ToNumber<int32_t>();
338     }
339     if (alignValue >= 0 && alignValue < static_cast<int32_t>(ALIGN_STYLE.size())) {
340         value = alignValue;
341     }
342     IndexerModel::GetInstance()->SetAlignStyle(value);
343     CalcDimension popupHorizontalSpace(-1.0);
344     if (args.Length() > 1) {
345         ParseJsDimensionVp(args[1], popupHorizontalSpace);
346     }
347     IndexerModel::GetInstance()->SetPopupHorizontalSpace(popupHorizontalSpace);
348 }
349 
SetSelected(const JSCallbackInfo & args)350 void JSIndexer::SetSelected(const JSCallbackInfo& args)
351 {
352     if (args.Length() >= 1) {
353         int32_t selected = 0;
354         if (ParseJsInteger<int32_t>(args[0], selected)) {
355             IndexerModel::GetInstance()->SetSelected(selected);
356         }
357         if (args.Length() > 1 && args[1]->IsFunction()) {
358             ParseIndexerSelectedObject(args, args[1], true);
359         }
360     }
361 }
362 
SetPopupPosition(const JSCallbackInfo & args)363 void JSIndexer::SetPopupPosition(const JSCallbackInfo& args)
364 {
365     std::optional<Dimension> xOpt;
366     std::optional<Dimension> yOpt;
367     if (args[0]->IsObject()) {
368         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
369         CalcDimension x;
370         CalcDimension y;
371         JSRef<JSVal> xVal = obj->GetProperty("x");
372         JSRef<JSVal> yVal = obj->GetProperty("y");
373         if ((xVal->IsString() && StringUtils::StringToCalcDimensionNG(xVal->ToString(), x, false)) ||
374             (!xVal->IsString() && JSViewAbstract::ParseJsDimensionVp(xVal, x))) {
375             xOpt = x;
376         }
377         if ((yVal->IsString() && StringUtils::StringToCalcDimensionNG(yVal->ToString(), y, false)) ||
378             (!yVal->IsString() && JSViewAbstract::ParseJsDimensionVp(yVal, y))) {
379             yOpt = y;
380         }
381     } else if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
382         return;
383     }
384     IndexerModel::GetInstance()->SetPopupPositionX(xOpt);
385     IndexerModel::GetInstance()->SetPopupPositionY(yOpt);
386 }
387 
SetPopupSelectedColor(const JSCallbackInfo & args)388 void JSIndexer::SetPopupSelectedColor(const JSCallbackInfo& args)
389 {
390     if (args.Length() < 1) {
391         return;
392     }
393     IndexerModel::GetInstance()->SetPopupSelectedColor(PaseColor(args));
394 }
395 
SetPopupUnselectedColor(const JSCallbackInfo & args)396 void JSIndexer::SetPopupUnselectedColor(const JSCallbackInfo& args)
397 {
398     if (args.Length() < 1) {
399         return;
400     }
401     IndexerModel::GetInstance()->SetPopupUnselectedColor(PaseColor(args));
402 }
403 
SetPopupItemFont(const JSCallbackInfo & args)404 void JSIndexer::SetPopupItemFont(const JSCallbackInfo& args)
405 {
406     CalcDimension fontSize;
407     std::string weight;
408     if (args[0]->IsObject()) {
409         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
410         JSRef<JSVal> size = obj->GetProperty("size");
411         if (!size->IsNull()) {
412             CalcDimension fontSizeData;
413             if (ParseJsDimensionFp(size, fontSizeData) && !fontSizeData.IsNegative() &&
414                 fontSizeData.Unit() != DimensionUnit::PERCENT) {
415                 fontSize = fontSizeData;
416             }
417         }
418 
419         auto jsWeight = obj->GetProperty("weight");
420         if (!jsWeight->IsNull()) {
421             if (jsWeight->IsNumber()) {
422                 weight = std::to_string(jsWeight->ToNumber<int32_t>());
423             } else {
424                 ParseJsString(jsWeight, weight);
425             }
426         }
427     }
428     IndexerModel::GetInstance()->SetFontSize(fontSize);
429     IndexerModel::GetInstance()->SetFontWeight(ConvertStrToFontWeight(weight, FontWeight::MEDIUM));
430 }
431 
SetPopupItemBackgroundColor(const JSCallbackInfo & args)432 void JSIndexer::SetPopupItemBackgroundColor(const JSCallbackInfo& args)
433 {
434     if (args.Length() < 1) {
435         return;
436     }
437     IndexerModel::GetInstance()->SetPopupItemBackground(PaseColor(args));
438 }
439 
PaseColor(const JSCallbackInfo & args)440 std::optional<Color> JSIndexer::PaseColor(const JSCallbackInfo& args)
441 {
442     std::optional<Color> colorOpt;
443     Color color;
444     if (ParseJsColor(args[0], color)) {
445         colorOpt = color;
446     }
447     return colorOpt;
448 }
449 
SetAutoCollapse(const JSCallbackInfo & args)450 void JSIndexer::SetAutoCollapse(const JSCallbackInfo& args)
451 {
452     bool state = true;
453     if (args[0]->IsBoolean()) {
454         state = args[0]->ToBoolean();
455     }
456     IndexerModel::GetInstance()->SetAutoCollapse(state);
457 }
458 
SetPopupItemBorderRadius(const JSCallbackInfo & args)459 void JSIndexer::SetPopupItemBorderRadius(const JSCallbackInfo& args)
460 {
461     auto radius = Dimension(ZERO_RADIUS, DimensionUnit::VP);
462     auto popupRadius = Dimension(ZERO_RADIUS, DimensionUnit::VP);
463     if (args.Length() > 0 && args[0]->IsNumber()) {
464         auto radiusValue = args[0]->ToNumber<double>();
465         if (radiusValue >= 0) {
466             radius.SetValue(radiusValue);
467             radius.SetUnit(DimensionUnit::VP);
468             popupRadius.SetValue(radiusValue + RADIUS_OFFSET);
469             popupRadius.SetUnit(DimensionUnit::VP);
470         }
471     } else {
472         radius.SetValue(POPUP_ITEM_DEFAULT_RADIUS);
473         radius.SetUnit(DimensionUnit::VP);
474         popupRadius.SetValue(radius.Value() + RADIUS_OFFSET);
475         popupRadius.SetUnit(DimensionUnit::VP);
476     }
477     IndexerModel::GetInstance()->SetPopupItemBorderRadius(radius);
478     IndexerModel::GetInstance()->SetPopupBorderRadius(popupRadius);
479 }
480 
SetItemBorderRadius(const JSCallbackInfo & args)481 void JSIndexer::SetItemBorderRadius(const JSCallbackInfo& args)
482 {
483     auto radius = Dimension(ZERO_RADIUS, DimensionUnit::VP);
484     auto indexerRadius = Dimension(ZERO_RADIUS, DimensionUnit::VP);
485     if (args.Length() > 0 && args[0]->IsNumber()) {
486         auto radiusValue = args[0]->ToNumber<double>();
487         if (radiusValue >= 0) {
488             radius.SetValue(radiusValue);
489             radius.SetUnit(DimensionUnit::VP);
490             indexerRadius.SetValue(radiusValue + RADIUS_OFFSET);
491             indexerRadius.SetUnit(DimensionUnit::VP);
492         }
493     } else {
494         radius.SetValue(ITEM_DEFAULT_RADIUS);
495         radius.SetUnit(DimensionUnit::VP);
496         indexerRadius.SetValue(radius.Value() + RADIUS_OFFSET);
497         indexerRadius.SetUnit(DimensionUnit::VP);
498     }
499     IndexerModel::GetInstance()->SetItemBorderRadius(radius);
500     IndexerModel::GetInstance()->SetIndexerBorderRadius(indexerRadius);
501 }
502 
SetPopupBackgroundBlurStyle(const JSCallbackInfo & args)503 void JSIndexer::SetPopupBackgroundBlurStyle(const JSCallbackInfo& args)
504 {
505     if (args.Length() < 1) {
506         return;
507     }
508 
509     BlurStyleOption styleOption;
510     if (args[0]->IsNumber()) {
511         auto blurStyle = args[0]->ToNumber<int32_t>();
512         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
513             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
514             styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
515         } else {
516             styleOption.blurStyle = BlurStyle::COMPONENT_REGULAR;
517         }
518     } else {
519         styleOption.blurStyle = BlurStyle::COMPONENT_REGULAR;
520     }
521     IndexerModel::GetInstance()->SetPopupBackgroundBlurStyle(styleOption);
522 }
523 
SetPopupTitleBackground(const JSCallbackInfo & args)524 void JSIndexer::SetPopupTitleBackground(const JSCallbackInfo& args)
525 {
526     if (args.Length() < 1) {
527         return;
528     }
529     IndexerModel::GetInstance()->SetPopupTitleBackground(PaseColor(args));
530 }
531 
SetWidth(const JSCallbackInfo & args)532 void JSIndexer::SetWidth(const JSCallbackInfo& args)
533 {
534     JSViewAbstract::JsWidth(args);
535     if (args[0]->IsString() && args[0]->ToString() == "auto") {
536         IndexerModel::GetInstance()->SetAdaptiveWidth(true);
537     } else {
538         IndexerModel::GetInstance()->SetAdaptiveWidth(false);
539     }
540 }
541 
SetEnableHapticFeedback(const JSCallbackInfo & args)542 void JSIndexer::SetEnableHapticFeedback(const JSCallbackInfo& args)
543 {
544     bool state = true;
545     if (args.Length() > 0 && args[0]->IsBoolean()) {
546         state = args[0]->ToBoolean();
547     }
548     IndexerModel::GetInstance()->SetEnableHapticFeedback(state);
549 }
550 
JSBind(BindingTarget globalObj)551 void JSIndexer::JSBind(BindingTarget globalObj)
552 {
553     MethodOptions opt = MethodOptions::NONE;
554     JSClass<JSIndexer>::Declare("AlphabetIndexer");
555     JSClass<JSIndexer>::StaticMethod("create", &JSIndexer::Create);
556     // API7 onSelected deprecated
557     JSClass<JSIndexer>::StaticMethod("onSelected", &JSIndexer::JsOnSelected);
558     JSClass<JSIndexer>::StaticMethod("onSelect", &JSIndexer::JsOnSelected);
559     JSClass<JSIndexer>::StaticMethod("color", &JSIndexer::SetColor, opt);
560     JSClass<JSIndexer>::StaticMethod("selectedColor", &JSIndexer::SetSelectedColor, opt);
561     JSClass<JSIndexer>::StaticMethod("popupColor", &JSIndexer::SetPopupColor, opt);
562     JSClass<JSIndexer>::StaticMethod("selectedBackgroundColor", &JSIndexer::SetSelectedBackgroundColor, opt);
563     JSClass<JSIndexer>::StaticMethod("popupBackground", &JSIndexer::SetPopupBackground, opt);
564     JSClass<JSIndexer>::StaticMethod("usingPopup", &JSIndexer::SetUsingPopup, opt);
565     JSClass<JSIndexer>::StaticMethod("selectedFont", &JSIndexer::SetSelectedFont);
566     JSClass<JSIndexer>::StaticMethod("font", &JSIndexer::SetFont);
567     JSClass<JSIndexer>::StaticMethod("popupFont", &JSIndexer::SetPopupFont);
568     JSClass<JSIndexer>::StaticMethod("itemSize", &JSIndexer::SetItemSize, opt);
569     JSClass<JSIndexer>::StaticMethod("alignStyle", &JSIndexer::SetAlignStyle, opt);
570     JSClass<JSIndexer>::StaticMethod("onRequestPopupData", &JSIndexer::JsOnRequestPopupData, opt);
571     JSClass<JSIndexer>::StaticMethod("selected", &JSIndexer::SetSelected, opt);
572     JSClass<JSIndexer>::StaticMethod("popupPosition", &JSIndexer::SetPopupPosition, opt);
573     JSClass<JSIndexer>::StaticMethod("popupSelectedColor", &JSIndexer::SetPopupSelectedColor, opt);
574     JSClass<JSIndexer>::StaticMethod("popupUnselectedColor", &JSIndexer::SetPopupUnselectedColor, opt);
575     JSClass<JSIndexer>::StaticMethod("popupItemFont", &JSIndexer::SetPopupItemFont);
576     JSClass<JSIndexer>::StaticMethod("popupItemBackgroundColor", &JSIndexer::SetPopupItemBackgroundColor, opt);
577     JSClass<JSIndexer>::StaticMethod("autoCollapse", &JSIndexer::SetAutoCollapse, opt);
578     JSClass<JSIndexer>::StaticMethod("popupItemBorderRadius", &JSIndexer::SetPopupItemBorderRadius);
579     JSClass<JSIndexer>::StaticMethod("itemBorderRadius", &JSIndexer::SetItemBorderRadius);
580     JSClass<JSIndexer>::StaticMethod("popupBackgroundBlurStyle", &JSIndexer::SetPopupBackgroundBlurStyle);
581     JSClass<JSIndexer>::StaticMethod("popupTitleBackground", &JSIndexer::SetPopupTitleBackground, opt);
582     JSClass<JSIndexer>::StaticMethod("width", &JSIndexer::SetWidth);
583     JSClass<JSIndexer>::StaticMethod("enableHapticFeedback", &JSIndexer::SetEnableHapticFeedback, opt);
584     // keep compatible, need remove after
585     JSClass<JSIndexer>::StaticMethod("onPopupSelected", &JSIndexer::JsOnPopupSelected, opt);
586     JSClass<JSIndexer>::StaticMethod("onPopupSelect", &JSIndexer::JsOnPopupSelected, opt);
587     JSClass<JSIndexer>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
588     JSClass<JSIndexer>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
589     JSClass<JSIndexer>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
590     JSClass<JSIndexer>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
591     JSClass<JSIndexer>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
592     JSClass<JSIndexer>::InheritAndBind<JSViewAbstract>(globalObj);
593 }
594 } // namespace OHOS::Ace::Framework
595