• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2024 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 "frameworks/bridge/declarative_frontend/jsview/js_textfield.h"
17 
18 #include <algorithm>
19 #include <cstdint>
20 #include <string>
21 #include <vector>
22 #include "base/utils/utf_helper.h"
23 #include "bridge/cj_frontend/interfaces/cj_ffi/utils.h"
24 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
25 
26 #include "base/geometry/dimension.h"
27 #include "base/log/ace_scoring_log.h"
28 #include "base/utils/utils.h"
29 #include "bridge/common/utils/utils.h"
30 #include "bridge/declarative_frontend/engine/functions/js_click_function.h"
31 #include "bridge/declarative_frontend/engine/functions/js_clipboard_function.h"
32 #include "bridge/declarative_frontend/engine/functions/js_common_event_function.h"
33 #include "bridge/declarative_frontend/engine/functions/js_cited_event_function.h"
34 #include "bridge/declarative_frontend/engine/functions/js_event_function.h"
35 #include "bridge/declarative_frontend/engine/jsi/js_ui_index.h"
36 #include "bridge/declarative_frontend/jsview/js_container_base.h"
37 #include "bridge/declarative_frontend/jsview/js_interactable_view.h"
38 #include "bridge/declarative_frontend/jsview/js_text_editable_controller.h"
39 #include "bridge/declarative_frontend/jsview/js_textarea.h"
40 #include "bridge/declarative_frontend/jsview/js_textinput.h"
41 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
42 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
43 #include "bridge/declarative_frontend/jsview/models/text_field_model_impl.h"
44 #include "core/common/container.h"
45 #include "core/common/ime/text_input_action.h"
46 #include "core/common/ime/text_input_type.h"
47 #include "core/components/common/layout/constants.h"
48 #include "core/components/common/properties/text_style_parser.h"
49 #include "core/components/text_field/textfield_theme.h"
50 #include "core/components_ng/base/view_abstract.h"
51 #include "core/components_ng/pattern/text_field/text_content_type.h"
52 #include "core/components_ng/pattern/text_field/text_field_model_ng.h"
53 #include "core/image/image_source_info.h"
54 #include "core/text/text_emoji_processor.h"
55 
56 namespace OHOS::Ace {
57 
58 std::unique_ptr<TextFieldModel> TextFieldModel::instance_ = nullptr;
59 std::mutex TextFieldModel::mutex_;
60 
GetInstance()61 TextFieldModel* TextFieldModel::GetInstance()
62 {
63 #ifdef NG_BUILD
64     static NG::TextFieldModelNG instance;
65     return &instance;
66 #else
67     if (Container::IsCurrentUseNewPipeline()) {
68         static NG::TextFieldModelNG instance;
69         return &instance;
70     } else {
71         static Framework::TextFieldModelImpl instance;
72         return &instance;
73     }
74 #endif
75 }
76 
77 } // namespace OHOS::Ace
78 
79 namespace OHOS::Ace::Framework {
80 
81 namespace {
82 
83 const std::vector<TextAlign> TEXT_ALIGNS = { TextAlign::START, TextAlign::CENTER, TextAlign::END, TextAlign::JUSTIFY };
84 const std::vector<LineBreakStrategy> LINE_BREAK_STRATEGY_TYPES = { LineBreakStrategy::GREEDY,
85     LineBreakStrategy::HIGH_QUALITY, LineBreakStrategy::BALANCED };
86 const std::vector<FontStyle> FONT_STYLES = { FontStyle::NORMAL, FontStyle::ITALIC };
87 const std::vector<std::string> INPUT_FONT_FAMILY_VALUE = { "sans-serif" };
88 const std::vector<WordBreak> WORD_BREAK_TYPES = { WordBreak::NORMAL, WordBreak::BREAK_ALL, WordBreak::BREAK_WORD,
89     WordBreak::HYPHENATION };
90 const std::vector<TextOverflow> TEXT_OVERFLOWS = { TextOverflow::NONE, TextOverflow::CLIP, TextOverflow::ELLIPSIS,
91     TextOverflow::MARQUEE, TextOverflow::DEFAULT };
92 const std::vector<EllipsisMode> ELLIPSIS_MODALS = { EllipsisMode::HEAD, EllipsisMode::MIDDLE, EllipsisMode::TAIL };
93 constexpr uint32_t MAX_LINES = 3;
94 constexpr uint32_t MINI_VAILD_VALUE = 1;
95 constexpr uint32_t MAX_VAILD_VALUE = 100;
96 constexpr uint32_t ILLEGAL_VALUE = 0;
97 constexpr uint32_t DEFAULT_MODE = -1;
98 constexpr uint32_t DEFAULT_OVERFLOW = 4;
99 constexpr double DEFAULT_OPACITY = 0.2;
100 const int32_t DEFAULT_ALPHA = 255;
101 const char* TOP_START_PROPERTY = "topStart";
102 const char* TOP_END_PROPERTY = "topEnd";
103 const char* BOTTOM_START_PROPERTY = "bottomStart";
104 const char* BOTTOM_END_PROPERTY = "bottomEnd";
105 const std::vector<TextHeightAdaptivePolicy> HEIGHT_ADAPTIVE_POLICY = { TextHeightAdaptivePolicy::MAX_LINES_FIRST,
106     TextHeightAdaptivePolicy::MIN_FONT_SIZE_FIRST, TextHeightAdaptivePolicy::LAYOUT_CONSTRAINT_FIRST };
107 constexpr TextDecorationStyle DEFAULT_TEXT_DECORATION_STYLE = TextDecorationStyle::SOLID;
108 
ParseJsLengthMetrics(const JSRef<JSObject> & obj,CalcDimension & result)109 bool ParseJsLengthMetrics(const JSRef<JSObject>& obj, CalcDimension& result)
110 {
111     auto value = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
112     if (!value->IsNumber()) {
113         return false;
114     }
115     auto unit = DimensionUnit::VP;
116     auto jsUnit = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::UNIT));
117     if (jsUnit->IsNumber()) {
118         unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
119     }
120     CalcDimension dimension(value->ToNumber<double>(), unit);
121     result = dimension;
122     return true;
123 }
124 } // namespace
125 
ParseTextFieldTextObject(const JSCallbackInfo & info,const JSRef<JSVal> & changeEventVal)126 void ParseTextFieldTextObject(const JSCallbackInfo& info, const JSRef<JSVal>& changeEventVal)
127 {
128     CHECK_NULL_VOID(changeEventVal->IsFunction());
129 
130     JsEventCallback<void(const std::u16string&)> onChangeEvent(
131         info.GetExecutionContext(), JSRef<JSFunc>::Cast(changeEventVal));
132     TextFieldModel::GetInstance()->SetOnChangeEvent(std::move(onChangeEvent));
133 }
134 
ParseTextProperty(const JSRef<JSVal> & textValue,std::optional<std::u16string> & value,std::u16string & text)135 void ParseTextProperty(const JSRef<JSVal>& textValue, std::optional<std::u16string>& value, std::u16string& text)
136 {
137     if (JSViewAbstract::ParseJsString(textValue, text)) {
138         value = text;
139     }
140     if (textValue->IsUndefined()) {
141         value = u"";
142     }
143 }
144 
ParseText(const JSRef<JSObject> & paramObject,std::optional<std::u16string> & value,JSRef<JSVal> & changeEventVal,std::u16string & text,RefPtr<ResourceObject> & textObject)145 bool JSTextField::ParseText(const JSRef<JSObject>& paramObject, std::optional<std::u16string>& value,
146     JSRef<JSVal>& changeEventVal, std::u16string& text, RefPtr<ResourceObject>& textObject)
147 {
148     bool textResult = false;
149     JSRef<JSVal> textValue = paramObject->GetProperty("text");
150     if (textValue->IsObject()) {
151         JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(textValue);
152         changeEventVal = valueObj->GetProperty("changeEvent");
153         if (changeEventVal->IsFunction()) {
154             textValue = valueObj->GetProperty("value");
155         }
156         value = u"";
157         textResult = ParseJsString(textValue, text, textObject);
158         if (textResult) {
159             value = text;
160         }
161     } else if (paramObject->GetProperty("$text")->IsFunction()) {
162         changeEventVal = paramObject->GetProperty("$text");
163         value = u"";
164         textResult = ParseJsString(textValue, text, textObject);
165         if (textResult) {
166             value = text;
167         }
168     } else if (paramObject->HasProperty("text")) {
169         textResult = ParseJsString(textValue, text, textObject);
170         if (textResult) {
171             value = text;
172         }
173         if (textValue->IsUndefined()) {
174             value = u"";
175         }
176     }
177     return textResult;
178 }
179 
CreateTextInput(const JSCallbackInfo & info)180 void JSTextField::CreateTextInput(const JSCallbackInfo& info)
181 {
182     std::optional<std::u16string> placeholderSrc;
183     std::optional<std::u16string> value;
184     bool placeholderResult = false;
185     bool textResult = false;
186     std::u16string placeholder;
187     std::u16string text;
188     RefPtr<ResourceObject> placeholderObject;
189     RefPtr<ResourceObject> textObject;
190     JSTextEditableController* jsController = nullptr;
191     JSRef<JSVal> changeEventVal = JSRef<JSVal>::Make();
192     auto jsValue = info[0];
193     if (jsValue->IsObject()) {
194         auto paramObject = JSRef<JSObject>::Cast(jsValue);
195         placeholderResult = ParseJsString(paramObject->GetProperty("placeholder"), placeholder, placeholderObject);
196         if (placeholderResult) {
197             placeholderSrc = placeholder;
198         }
199         JSRef<JSVal> textValue = paramObject->GetProperty("text");
200         textResult = ParseText(paramObject, value, changeEventVal, text, textObject);
201         auto controllerObj = paramObject->GetProperty("controller");
202         if (!controllerObj->IsUndefined() && !controllerObj->IsNull()) {
203             jsController = JSRef<JSObject>::Cast(controllerObj)->Unwrap<JSTextEditableController>();
204         }
205     }
206     auto controller = TextFieldModel::GetInstance()->CreateTextInput(placeholderSrc, value);
207     if (jsController) {
208         jsController->SetController(controller);
209     }
210     if (!changeEventVal->IsUndefined() && changeEventVal->IsFunction()) {
211         ParseTextFieldTextObject(info, changeEventVal);
212     }
213 
214     TextFieldModel::GetInstance()->SetFocusableAndFocusNode();
215     if (SystemProperties::ConfigChangePerform()) {
216         UnregisterResource("placeholder");
217         if (placeholderResult && placeholderObject) {
218             RegisterResource<std::u16string>("placeholder", placeholderObject, placeholder);
219         }
220     }
221     if (SystemProperties::ConfigChangePerform()) {
222         UnregisterResource("text");
223         if (textResult && textObject) {
224             RegisterResource<std::u16string>("text", textObject, text);
225         }
226     }
227 }
228 
CreateTextArea(const JSCallbackInfo & info)229 void JSTextField::CreateTextArea(const JSCallbackInfo& info)
230 {
231     std::optional<std::u16string> placeholderSrc;
232     std::optional<std::u16string> value;
233     bool placeholderResult = false;
234     bool textResult = false;
235     std::u16string placeholder;
236     std::u16string text;
237     RefPtr<ResourceObject> placeholderObject;
238     RefPtr<ResourceObject> textObject;
239     JSTextEditableController* jsController = nullptr;
240     JSRef<JSVal> changeEventVal = JSRef<JSVal>::Make();
241     auto jsValue = info[0];
242     if (jsValue->IsObject()) {
243         auto paramObject = JSRef<JSObject>::Cast(jsValue);
244         placeholderResult = ParseJsString(paramObject->GetProperty("placeholder"), placeholder, placeholderObject);
245         if (placeholderResult) {
246             placeholderSrc = placeholder;
247         }
248 
249         JSRef<JSVal> textValue = paramObject->GetProperty("text");
250         textResult = ParseText(paramObject, value, changeEventVal, text, textObject);
251         auto controllerObj = paramObject->GetProperty("controller");
252         if (!controllerObj->IsUndefined() && !controllerObj->IsNull()) {
253             jsController = JSRef<JSObject>::Cast(controllerObj)->Unwrap<JSTextEditableController>();
254         }
255     }
256     auto controller = TextFieldModel::GetInstance()->CreateTextArea(placeholderSrc, value);
257     if (jsController) {
258         jsController->SetController(controller);
259     }
260     if (!changeEventVal->IsUndefined() && changeEventVal->IsFunction()) {
261         ParseTextFieldTextObject(info, changeEventVal);
262     }
263 
264     TextFieldModel::GetInstance()->SetFocusableAndFocusNode();
265     if (SystemProperties::ConfigChangePerform()) {
266         UnregisterResource("placeholder");
267         if (placeholderResult && placeholderObject) {
268             RegisterResource<std::u16string>("placeholder", placeholderObject, placeholder);
269         }
270     }
271     if (SystemProperties::ConfigChangePerform()) {
272         UnregisterResource("text");
273         if (textResult && textObject) {
274             RegisterResource<std::u16string>("text", textObject, text);
275         }
276     }
277 }
278 
SetType(const JSCallbackInfo & info)279 void JSTextField::SetType(const JSCallbackInfo& info)
280 {
281     if (info.Length() < 1) {
282         return;
283     }
284     auto jsValue = info[0];
285     if (jsValue->IsUndefined()) {
286         TextFieldModel::GetInstance()->SetType(TextInputType::UNSPECIFIED);
287         return;
288     }
289     if (!jsValue->IsNumber()) {
290         return;
291     }
292     TextInputType textInputType = CastToTextInputType(jsValue->ToNumber<int32_t>());
293     TextFieldModel::GetInstance()->SetType(textInputType);
294 }
295 
SetContentType(const JSCallbackInfo & info)296 void JSTextField::SetContentType(const JSCallbackInfo& info)
297 {
298     if (info.Length() < 1) {
299         return;
300     }
301     auto jsValue = info[0];
302     if (jsValue->IsUndefined()) {
303         TextFieldModel::GetInstance()->SetContentType(NG::TextContentType::UNSPECIFIED);
304         return;
305     }
306     if (!jsValue->IsNumber()) {
307         return;
308     }
309     NG::TextContentType textContentType = static_cast<NG::TextContentType>(jsValue->ToNumber<int32_t>());
310     TextFieldModel::GetInstance()->SetContentType(textContentType);
311 }
312 
SetPlaceholderColor(const JSCallbackInfo & info)313 void JSTextField::SetPlaceholderColor(const JSCallbackInfo& info)
314 {
315     if (info.Length() < 1) {
316         return;
317     }
318 
319     auto theme = GetTheme<TextFieldTheme>();
320     CHECK_NULL_VOID(theme);
321     Color color = theme->GetPlaceholderColor();
322     RefPtr<ResourceObject> resourceObject;
323     UnregisterResource("placeholderColor");
324     if (!CheckColor(info[0], color, V2::TEXTINPUT_ETS_TAG, "PlaceholderColor", resourceObject)) {
325         TextFieldModel::GetInstance()->ResetPlaceholderColor();
326         return;
327     }
328     if (SystemProperties::ConfigChangePerform() && resourceObject) {
329         RegisterResource<Color>("placeholderColor", resourceObject, color);
330     }
331     TextFieldModel::GetInstance()->SetPlaceholderColor(color);
332 }
333 
SetPlaceholderFont(const JSCallbackInfo & info)334 void JSTextField::SetPlaceholderFont(const JSCallbackInfo& info)
335 {
336     if (info.Length() < 1 || !info[0]->IsObject()) {
337         return;
338     }
339     auto theme = GetTheme<TextFieldTheme>();
340     CHECK_NULL_VOID(theme);
341     Font font;
342     auto paramObject = JSRef<JSObject>::Cast(info[0]);
343     auto fontSize = paramObject->GetProperty("size");
344     RefPtr<ResourceObject> resourceObject;
345     UnregisterResource("placeholderFontSize");
346     if (fontSize->IsNull() || fontSize->IsUndefined()) {
347         font.fontSize = Dimension(-1);
348     } else {
349         CalcDimension size;
350         if (fontSize->IsString()) {
351             auto result = StringUtils::StringToDimensionWithThemeValue(
352                 fontSize->ToString(), true, Dimension(theme->GetFontSize()));
353             if (result.Unit() == DimensionUnit::PERCENT) {
354                 result = theme->GetFontSize();
355             }
356             font.fontSize = result;
357         } else if (ParseJsDimensionFp(fontSize, size, resourceObject) && size.Unit() != DimensionUnit::PERCENT) {
358             font.fontSize = size;
359         } else {
360             font.fontSize = Dimension(theme->GetFontSize());
361         }
362         if (SystemProperties::ConfigChangePerform() && resourceObject) {
363             RegisterResource<CalcDimension>("placeholderFontSize", resourceObject, size);
364         }
365     }
366 
367     std::string weight;
368     auto fontWeight = paramObject->GetProperty("weight");
369     if (!fontWeight->IsNull()) {
370         if (fontWeight->IsNumber()) {
371             weight = std::to_string(fontWeight->ToNumber<int32_t>());
372         } else {
373             ParseJsString(fontWeight, weight);
374         }
375         font.fontWeight = ConvertStrToFontWeight(weight);
376     }
377 
378     auto fontFamily = paramObject->GetProperty("family");
379     UnregisterResource("placeholderFontFamily");
380     if (!fontFamily->IsNull()) {
381         std::vector<std::string> fontFamilies;
382         RefPtr<ResourceObject> resourceObject;
383         if (ParseJsFontFamilies(fontFamily, fontFamilies, resourceObject)) {
384             font.fontFamilies = fontFamilies;
385             if (SystemProperties::ConfigChangePerform() && resourceObject) {
386                 RegisterResource<std::vector<std::string>>("placeholderFontFamily", resourceObject, fontFamilies);
387             }
388         }
389     }
390 
391     auto style = paramObject->GetProperty("style");
392     if (!style->IsNull()) {
393         font.fontStyle = static_cast<FontStyle>(style->ToNumber<int32_t>());
394     }
395     TextFieldModel::GetInstance()->SetPlaceholderFont(font);
396 }
397 
SetEnterKeyType(const JSCallbackInfo & info)398 void JSTextField::SetEnterKeyType(const JSCallbackInfo& info)
399 {
400     if (info.Length() < 1) {
401         return;
402     }
403     auto jsValue = info[0];
404     if (jsValue->IsUndefined()) {
405         TextFieldModel::GetInstance()->SetEnterKeyType(TextInputAction::UNSPECIFIED);
406         return;
407     }
408     if (!jsValue->IsNumber()) {
409         return;
410     }
411     TextInputAction textInputAction = CastToTextInputAction(jsValue->ToNumber<int32_t>());
412     TextFieldModel::GetInstance()->SetEnterKeyType(textInputAction);
413 }
414 
SetCapitalizationMode(const JSCallbackInfo & info)415 void JSTextField::SetCapitalizationMode(const JSCallbackInfo& info)
416 {
417     if (info.Length() < 1) {
418         return;
419     }
420     auto jsValue = info[0];
421     auto autoCapitalizationMode = AutoCapitalizationMode::NONE;
422     if (jsValue->IsUndefined() || !jsValue->IsNumber() || jsValue->IsNull()) {
423         TextFieldModel::GetInstance()->SetCapitalizationMode(autoCapitalizationMode);
424         return;
425     }
426     if (jsValue->IsNumber()) {
427         auto emunNumber = jsValue->ToNumber<int32_t>();
428         autoCapitalizationMode = CastToAutoCapitalizationMode(emunNumber);
429     }
430     TextFieldModel::GetInstance()->SetCapitalizationMode(autoCapitalizationMode);
431 }
432 
SetTextAlign(int32_t value)433 void JSTextField::SetTextAlign(int32_t value)
434 {
435     if (value >= 0 && value < static_cast<int32_t>(TEXT_ALIGNS.size())) {
436         TextFieldModel::GetInstance()->SetTextAlign(TEXT_ALIGNS[value]);
437     }
438 }
439 
SetLineBreakStrategy(const JSCallbackInfo & info)440 void JSTextField::SetLineBreakStrategy(const JSCallbackInfo& info)
441 {
442     if (info.Length() < 1) {
443         TextFieldModel::GetInstance()->SetLineBreakStrategy(LineBreakStrategy::GREEDY);
444         return;
445     }
446     if (!info[0]->IsNumber()) {
447         TextFieldModel::GetInstance()->SetLineBreakStrategy(LineBreakStrategy::GREEDY);
448         return;
449     }
450     auto index = info[0]->ToNumber<int32_t>();
451     if (index < 0 || index >= static_cast<int32_t>(LINE_BREAK_STRATEGY_TYPES.size())) {
452         TextFieldModel::GetInstance()->SetLineBreakStrategy(LineBreakStrategy::GREEDY);
453         return;
454     }
455     TextFieldModel::GetInstance()->SetLineBreakStrategy(LINE_BREAK_STRATEGY_TYPES[index]);
456 }
457 
SetInputStyle(const JSCallbackInfo & info)458 void JSTextField::SetInputStyle(const JSCallbackInfo& info)
459 {
460     if (info.Length() < 1) {
461         return;
462     }
463     auto styleString = info[0]->ToString();
464     if (styleString == "Inline") {
465         TextFieldModel::GetInstance()->SetInputStyle(InputStyle::INLINE);
466     } else {
467         TextFieldModel::GetInstance()->SetInputStyle(InputStyle::DEFAULT);
468     }
469 }
470 
SetCaretColor(const JSCallbackInfo & info)471 void JSTextField::SetCaretColor(const JSCallbackInfo& info)
472 {
473     if (info.Length() < 1) {
474         return;
475     }
476 
477     Color color;
478     RefPtr<ResourceObject> resourceObject;
479     UnregisterResource("caretColor");
480     if (!ParseJsColor(info[0], color, resourceObject)) {
481         TextFieldModel::GetInstance()->ResetCaretColor();
482         return;
483     }
484     if (SystemProperties::ConfigChangePerform() && resourceObject) {
485         RegisterResource<Color>("caretColor", resourceObject, color);
486     }
487     TextFieldModel::GetInstance()->SetCaretColor(color);
488 }
489 
SetCaretStyle(const JSCallbackInfo & info)490 void JSTextField::SetCaretStyle(const JSCallbackInfo& info)
491 {
492     if (info.Length() < 1) {
493         return;
494     }
495     UnregisterResource("caretWidth");
496     UnregisterResource("caretColor");
497     auto jsValue = info[0];
498     if (jsValue->IsObject()) {
499         CaretStyle caretStyle;
500         auto paramObject = JSRef<JSObject>::Cast(jsValue);
501         auto caretWidth = paramObject->GetProperty("width");
502 
503         auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
504         CHECK_NULL_VOID(pipeline);
505         auto theme = pipeline->GetThemeManager()->GetTheme<TextFieldTheme>();
506         CHECK_NULL_VOID(theme);
507         if (caretWidth->IsNull() || caretWidth->IsUndefined()) {
508             caretStyle.caretWidth = theme->GetCursorWidth();
509         } else {
510             CalcDimension width;
511             RefPtr<ResourceObject> widthObject;
512             if (!ParseJsDimensionVpNG(caretWidth, width, widthObject, false)) {
513                 width = theme->GetCursorWidth();
514             }
515             if (SystemProperties::ConfigChangePerform() && widthObject) {
516                 RegisterResource<CalcDimension>("caretWidth", widthObject, width);
517             }
518             if (LessNotEqual(width.Value(), 0.0)) {
519                 width = theme->GetCursorWidth();
520             }
521             caretStyle.caretWidth = width;
522         }
523         TextFieldModel::GetInstance()->SetCaretStyle(caretStyle);
524 
525         // set caret color
526         Color caretColor;
527         if (!paramObject->HasProperty("color")) {
528             return;
529         } else {
530             auto caretColorProp = paramObject->GetProperty("color");
531             RefPtr<ResourceObject> colorObject;
532             if (caretColorProp->IsUndefined() || caretColorProp->IsNull()
533                 || !ParseJsColor(caretColorProp, caretColor, colorObject)) {
534                 caretColor = theme->GetCursorColor();
535             }
536             if (SystemProperties::ConfigChangePerform() && colorObject) {
537                 RegisterResource<Color>("caretColor", colorObject, caretColor);
538             }
539             TextFieldModel::GetInstance()->SetCaretColor(caretColor);
540         }
541     }
542 }
543 
SetCaretPosition(const JSCallbackInfo & info)544 void JSTextField::SetCaretPosition(const JSCallbackInfo& info)
545 {
546     if (info.Length() < 1) {
547         return;
548     }
549     int32_t caretPosition = 0;
550     auto tempInfo = info[0];
551     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
552         if (!ParseJsInt32(tempInfo, caretPosition) || caretPosition < 0) {
553             caretPosition = 0;
554         }
555     } else {
556         if (!ParseJsInt32(tempInfo, caretPosition)) {
557             return;
558         }
559         if (caretPosition < 0) {
560             return;
561         }
562     }
563     TextFieldModel::GetInstance()->SetCaretPosition(caretPosition);
564 }
565 
SetSelectedBackgroundColor(const JSCallbackInfo & info)566 void JSTextField::SetSelectedBackgroundColor(const JSCallbackInfo& info)
567 {
568     if (info.Length() < 1) {
569         return;
570     }
571 
572     Color selectedColor;
573     RefPtr<ResourceObject> resourceObject;
574     UnregisterResource("selectedBackgroundColor");
575     if (!ParseJsColor(info[0], selectedColor, resourceObject)) {
576         auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
577         CHECK_NULL_VOID(pipeline);
578         auto theme = pipeline->GetThemeManager()->GetTheme<TextFieldTheme>();
579         CHECK_NULL_VOID(theme);
580         selectedColor = theme->GetSelectedColor();
581     }
582     if (SystemProperties::ConfigChangePerform() && resourceObject) {
583         RegisterResource<Color>("selectedBackgroundColor", resourceObject, selectedColor);
584     }
585     if (selectedColor.GetAlpha() == DEFAULT_ALPHA) {
586         selectedColor = selectedColor.ChangeOpacity(DEFAULT_OPACITY);
587     }
588     TextFieldModel::GetInstance()->SetSelectedBackgroundColor(selectedColor);
589 }
590 
SetMaxLength(const JSCallbackInfo & info)591 void JSTextField::SetMaxLength(const JSCallbackInfo& info)
592 {
593     if (info.Length() < 1) {
594         return;
595     }
596     auto jsValue = info[0];
597     int32_t maxLength = 0;
598     if (jsValue->IsUndefined()) {
599         TextFieldModel::GetInstance()->ResetMaxLength();
600         return;
601     } else if (!jsValue->IsNumber()) {
602         TextFieldModel::GetInstance()->ResetMaxLength();
603         return;
604     }
605     maxLength = jsValue->ToNumber<int32_t>();
606     if (std::isinf(jsValue->ToNumber<float>())) {
607         maxLength = INT32_MAX; // Infinity
608     }
609     if (GreatOrEqual(maxLength, 0)) {
610         TextFieldModel::GetInstance()->SetMaxLength(maxLength);
611     } else {
612         TextFieldModel::GetInstance()->ResetMaxLength();
613     }
614 }
615 
SetFontSize(const JSCallbackInfo & info)616 void JSTextField::SetFontSize(const JSCallbackInfo& info)
617 {
618     if (info.Length() < 1) {
619         return;
620     }
621     CalcDimension fontSize;
622     RefPtr<ResourceObject> resourceObject;
623     UnregisterResource("fontSize");
624     if (!ParseJsDimensionNG(info[0], fontSize, DimensionUnit::FP, resourceObject, false)) {
625         auto theme = GetTheme<TextFieldTheme>();
626         CHECK_NULL_VOID(theme);
627         fontSize = theme->GetFontSize();
628     }
629     if (SystemProperties::ConfigChangePerform() && resourceObject) {
630         RegisterResource<CalcDimension>("fontSize", resourceObject, fontSize);
631     }
632     TextFieldModel::GetInstance()->SetFontSize(fontSize);
633 }
634 
SetFontWeight(const JSCallbackInfo & info)635 void JSTextField::SetFontWeight(const JSCallbackInfo& info)
636 {
637     if (info.Length() < 1) {
638         return;
639     }
640     UnregisterResource("fontWeight");
641     JSRef<JSVal> args = info[0];
642     std::string fontWeight;
643     if (args->IsNumber()) {
644         fontWeight = args->ToString();
645     } else {
646         RefPtr<ResourceObject> resourceObject;
647         ParseJsString(args, fontWeight, resourceObject);
648         if (SystemProperties::ConfigChangePerform() && resourceObject) {
649             RegisterResource<std::string>("fontWeight", resourceObject, fontWeight);
650         }
651     }
652     FontWeight formatFontWeight = ConvertStrToFontWeight(fontWeight);
653     TextFieldModel::GetInstance()->SetFontWeight(formatFontWeight);
654 }
655 
SetMinFontScale(const JSCallbackInfo & info)656 void JSTextField::SetMinFontScale(const JSCallbackInfo& info)
657 {
658     double minFontScale = 0.0;
659     RefPtr<ResourceObject> resourceObject;
660     if (info.Length() < 1 || !ParseJsDouble(info[0], minFontScale, resourceObject)) {
661         return;
662     }
663     if (SystemProperties::ConfigChangePerform() && resourceObject) {
664         RegisterResource<float>("minFontScale", resourceObject, minFontScale);
665     } else {
666         UnregisterResource("minFontScale");
667     }
668     if (LessOrEqual(minFontScale, 0.0f)) {
669         TextFieldModel::GetInstance()->SetMinFontScale(0.0f);
670         return;
671     }
672     if (GreatOrEqual(minFontScale, 1.0f)) {
673         TextFieldModel::GetInstance()->SetMinFontScale(1.0f);
674         return;
675     }
676     TextFieldModel::GetInstance()->SetMinFontScale(static_cast<float>(minFontScale));
677 }
678 
SetMaxFontScale(const JSCallbackInfo & info)679 void JSTextField::SetMaxFontScale(const JSCallbackInfo& info)
680 {
681     double maxFontScale = 0.0;
682     RefPtr<ResourceObject> resourceObject;
683     if (info.Length() < 1 || !ParseJsDouble(info[0], maxFontScale, resourceObject)) {
684         return;
685     }
686     if (SystemProperties::ConfigChangePerform() && resourceObject) {
687         RegisterResource<float>("maxFontScale", resourceObject, maxFontScale);
688     } else {
689         UnregisterResource("maxFontScale");
690     }
691     if (LessOrEqual(maxFontScale, 1.0f)) {
692         TextFieldModel::GetInstance()->SetMaxFontScale(1.0f);
693         return;
694     }
695     TextFieldModel::GetInstance()->SetMaxFontScale(static_cast<float>(maxFontScale));
696 }
697 
SetTextColor(const JSCallbackInfo & info)698 void JSTextField::SetTextColor(const JSCallbackInfo& info)
699 {
700     if (info.Length() < 1) {
701         return;
702     }
703     Color textColor;
704     RefPtr<ResourceObject> resourceObject;
705     if (!ParseJsColor(info[0], textColor, resourceObject)) {
706         UnregisterResource("fontColor");
707         TextFieldModel::GetInstance()->ResetTextColor();
708         return;
709     }
710     if (SystemProperties::ConfigChangePerform() && resourceObject) {
711         RegisterResource<Color>("fontColor", resourceObject, textColor);
712     }
713     TextFieldModel::GetInstance()->SetTextColor(textColor);
714 }
715 
SetWordBreak(const JSCallbackInfo & info)716 void JSTextField::SetWordBreak(const JSCallbackInfo& info)
717 {
718     if (info.Length() < 1) {
719         return;
720     }
721     auto jsValue = info[0];
722     if (!jsValue->IsNumber()) {
723         TextFieldModel::GetInstance()->SetWordBreak(WordBreak::BREAK_WORD);
724         return;
725     }
726     auto index = jsValue->ToNumber<int32_t>();
727     if (index < 0 || index >= static_cast<int32_t>(WORD_BREAK_TYPES.size())) {
728         TextFieldModel::GetInstance()->SetWordBreak(WordBreak::BREAK_WORD);
729         return;
730     }
731     TextFieldModel::GetInstance()->SetWordBreak(WORD_BREAK_TYPES[index]);
732 }
733 
SetForegroundColor(const JSCallbackInfo & info)734 void JSTextField::SetForegroundColor(const JSCallbackInfo& info)
735 {
736     if (info.Length() < 1) {
737         return;
738     }
739     UnregisterResource("foregroundColor");
740     auto jsValue = info[0];
741     ForegroundColorStrategy strategy;
742     if (ParseJsColorStrategy(jsValue, strategy)) {
743         ViewAbstractModel::GetInstance()->SetForegroundColorStrategy(strategy);
744         TextFieldModel::GetInstance()->SetForegroundColor(Color::FOREGROUND);
745         return;
746     }
747     Color foregroundColor;
748     RefPtr<ResourceObject> resourceObject;
749     if (!ParseJsColor(jsValue, foregroundColor, resourceObject)) {
750         return;
751     }
752     if (SystemProperties::ConfigChangePerform() && resourceObject) {
753         RegisterResource<Color>("foregroundColor", resourceObject, foregroundColor);
754     }
755     ViewAbstractModel::GetInstance()->SetForegroundColor(foregroundColor);
756     TextFieldModel::GetInstance()->SetForegroundColor(foregroundColor);
757 }
758 
SetFontStyle(int32_t value)759 void JSTextField::SetFontStyle(int32_t value)
760 {
761     if (value >= 0 && value < static_cast<int32_t>(FONT_STYLES.size())) {
762         TextFieldModel::GetInstance()->SetFontStyle(FONT_STYLES[value]);
763     }
764 }
765 
SetFontFamily(const JSCallbackInfo & info)766 void JSTextField::SetFontFamily(const JSCallbackInfo& info)
767 {
768     if (info.Length() < 1) {
769         return;
770     }
771     std::vector<std::string> fontFamilies;
772     RefPtr<ResourceObject> resourceObject;
773     if (!ParseJsFontFamilies(info[0], fontFamilies, resourceObject)) {
774         return;
775     }
776     if (SystemProperties::ConfigChangePerform() && resourceObject) {
777         RegisterResource<std::vector<std::string>>("fontFamily", resourceObject, fontFamilies);
778     } else {
779         UnregisterResource("fontFamily");
780     }
781     TextFieldModel::GetInstance()->SetFontFamily(fontFamilies);
782 }
783 
SetInputFilter(const JSCallbackInfo & info)784 void JSTextField::SetInputFilter(const JSCallbackInfo& info)
785 {
786     if (info.Length() < 1) {
787         return;
788     }
789     auto jsValue = info[0];
790     std::string inputFilter;
791     if (jsValue->IsUndefined()) {
792         UnregisterResource("inputFilter");
793         TextFieldModel::GetInstance()->SetInputFilter(inputFilter, nullptr);
794         return;
795     }
796 
797     RefPtr<ResourceObject> resourceObject;
798     if (!ParseJsString(jsValue, inputFilter, resourceObject)) {
799         return;
800     }
801     if (SystemProperties::ConfigChangePerform() && resourceObject) {
802         RegisterResource<std::string>("inputFilter", resourceObject, inputFilter);
803     } else {
804         UnregisterResource("inputFilter");
805     }
806 
807     if (!CheckRegexValid(inputFilter)) {
808         inputFilter = "";
809     }
810     if (info.Length() > 1 && info[1]->IsFunction()) {
811         auto jsFunc = AceType::MakeRefPtr<JsClipboardFunction>(JSRef<JSFunc>::Cast(info[1]));
812         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
813         auto resultId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
814                             const std::u16string& info) {
815             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
816             PipelineContext::SetCallBackNode(node);
817             func->Execute(info);
818         };
819         TextFieldModel::GetInstance()->SetInputFilter(inputFilter, resultId);
820         return;
821     }
822     TextFieldModel::GetInstance()->SetInputFilter(inputFilter, nullptr);
823 }
824 
SetShowPasswordIcon(const JSCallbackInfo & info)825 void JSTextField::SetShowPasswordIcon(const JSCallbackInfo& info)
826 {
827     auto jsValue = info[0];
828     if (!jsValue->IsBoolean()) {
829         TextFieldModel::GetInstance()->SetShowPasswordIcon(true);
830         return;
831     }
832 
833     bool isShowPasswordIcon = jsValue->ToBoolean();
834     TextFieldModel::GetInstance()->SetShowPasswordIcon(isShowPasswordIcon);
835 }
836 
ShowPasswordText(const JSCallbackInfo & info)837 void JSTextField::ShowPasswordText(const JSCallbackInfo& info)
838 {
839     auto tmpInfo = info[0];
840     if (!tmpInfo->IsBoolean()) {
841         TextFieldModel::GetInstance()->SetShowPasswordText(false);
842         return;
843     }
844 
845     bool showPassword = tmpInfo->ToBoolean();
846     TextFieldModel::GetInstance()->SetShowPasswordText(showPassword);
847 }
848 
SetBackgroundColor(const JSCallbackInfo & info)849 void JSTextField::SetBackgroundColor(const JSCallbackInfo& info)
850 {
851     if (info.Length() < 1) {
852         return;
853     }
854     Color backgroundColor;
855     RefPtr<ResourceObject> resourceObject;
856     if (!ParseJsColor(info[0], backgroundColor, resourceObject)) {
857         UnregisterResource("backgroundColor");
858         TextFieldModel::GetInstance()->ResetBackgroundColor();
859         return;
860     }
861     if (SystemProperties::ConfigChangePerform() && resourceObject) {
862         RegisterResource<Color>("backgroundColor", resourceObject, backgroundColor);
863     }
864     TextFieldModel::GetInstance()->SetBackgroundColor(backgroundColor, false);
865 }
866 
JsHeight(const JSCallbackInfo & info)867 void JSTextField::JsHeight(const JSCallbackInfo& info)
868 {
869     JSViewAbstract::JsHeight(info);
870     if (info.Length() < 1) {
871         return;
872     }
873     CalcDimension value;
874     auto jsValue = info[0];
875     if (!ParseJsDimensionVp(jsValue, value)) {
876         SetLayoutPolicy(jsValue, false);
877         return;
878     }
879     if (LessNotEqual(value.Value(), 0.0)) {
880         ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
881         return;
882     }
883     TextFieldModel::GetInstance()->SetHeight(value);
884 }
885 
JsWidth(const JSCallbackInfo & info)886 void JSTextField::JsWidth(const JSCallbackInfo& info)
887 {
888     if (info.Length() < 1) {
889         return;
890     }
891     UnregisterResource("width");
892     auto jsValue = info[0];
893     if (jsValue->IsString() && jsValue->ToString().empty()) {
894         return;
895     }
896     if (jsValue->IsString() && jsValue->ToString() == "auto") {
897         ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
898         TextFieldModel::GetInstance()->SetWidthAuto(true);
899         SetLayoutPolicy(jsValue, true);
900         return;
901     }
902 
903     TextFieldModel::GetInstance()->SetWidthAuto(false);
904     CalcDimension value;
905     RefPtr<ResourceObject> resourceObject;
906     if (!ParseJsDimensionVp(jsValue, value, resourceObject)) {
907         SetLayoutPolicy(jsValue, true);
908         return;
909     }
910     if (SystemProperties::ConfigChangePerform() && resourceObject) {
911         RegisterResource<CalcDimension>("width", resourceObject, value);
912     }
913     if (LessNotEqual(value.Value(), 0.0)) {
914         return;
915     }
916     ViewAbstractModel::GetInstance()->SetWidth(value);
917 }
918 
CheckIsIllegalString(const std::string & value)919 bool CheckIsIllegalString(const std::string& value)
920 {
921     if (value.empty()) {
922         return true;
923     }
924     errno = 0;
925     char* pEnd = nullptr;
926     std::strtod(value.c_str(), &pEnd);
927     return (pEnd == value.c_str() || errno == ERANGE);
928 }
929 
JsMargin(const JSCallbackInfo & info)930 void JSTextField::JsMargin(const JSCallbackInfo& info)
931 {
932     JSViewAbstract::JsMargin(info);
933     TextFieldModel::GetInstance()->SetMargin();
934 }
935 
JsPadding(const JSCallbackInfo & info)936 void JSTextField::JsPadding(const JSCallbackInfo& info)
937 {
938     auto jsValue = info[0];
939     if (jsValue->IsUndefined() || (jsValue->IsString() && CheckIsIllegalString(jsValue->ToString()))) {
940         return;
941     };
942     CalcDimension length;
943     ParseJsDimensionVp(jsValue, length);
944     if (length.IsNegative()) {
945         TextFieldModel::GetInstance()->SetPadding(NG::PaddingProperty(), Edge(), true, false);
946         return;
947     }
948     bool tmp = !jsValue->IsString() && !jsValue->IsNumber() && !jsValue->IsObject();
949     bool hasRegist = false;
950     NG::PaddingProperty newPadding = GetNewPadding(info, hasRegist);
951     Edge oldPadding = Edge(GetOldPadding(info));
952     TextFieldModel::GetInstance()->SetPadding(newPadding, oldPadding, tmp, hasRegist);
953 }
954 
GetOldPadding(const JSCallbackInfo & info)955 Edge JSTextField::GetOldPadding(const JSCallbackInfo& info)
956 {
957     Edge padding;
958     auto jsValue = info[0];
959     if (jsValue->IsNumber() || jsValue->IsString()) {
960         CalcDimension edgeValue;
961         if (ParseJsDimensionVp(jsValue, edgeValue)) {
962             padding = Edge(edgeValue);
963         }
964     }
965     if (jsValue->IsObject()) {
966         JSRef<JSObject> object = JSRef<JSObject>::Cast(jsValue);
967         CalcDimension left = CalcDimension(0.0, DimensionUnit::VP);
968         CalcDimension top = CalcDimension(0.0, DimensionUnit::VP);
969         CalcDimension right = CalcDimension(0.0, DimensionUnit::VP);
970         CalcDimension bottom = CalcDimension(0.0, DimensionUnit::VP);
971         ParseJsDimensionVp(object->GetProperty("left"), left);
972         ParseJsDimensionVp(object->GetProperty("top"), top);
973         ParseJsDimensionVp(object->GetProperty("right"), right);
974         ParseJsDimensionVp(object->GetProperty("bottom"), bottom);
975         padding = Edge(left, top, right, bottom);
976     }
977     return padding;
978 }
979 
GetNewPadding(const JSCallbackInfo & info,bool & hasRegist)980 NG::PaddingProperty JSTextField::GetNewPadding(const JSCallbackInfo& info, bool& hasRegist)
981 {
982     NG::PaddingProperty padding;
983     auto jsValue = info[0];
984     if (jsValue->IsObject()) {
985         JSRef<JSObject> paddingObj = JSRef<JSObject>::Cast(jsValue);
986         CommonCalcDimension commonCalcDimension;
987         ParseCommonMarginOrPaddingCorner(paddingObj, commonCalcDimension);
988         if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() ||
989             commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) {
990             padding = GetEdgePaddingsOrSafeAreaPaddings(commonCalcDimension);
991             return padding;
992         }
993     }
994 
995     CalcDimension length;
996     RefPtr<ResourceObject> lengthResObj;
997     if (!ParseJsDimensionVp(jsValue, length, lengthResObj)) {
998         // use default value.
999         length.Reset();
1000     }
1001     if (SystemProperties::ConfigChangePerform() && lengthResObj) {
1002         NG::ViewAbstract::SetPadding(lengthResObj);
1003         hasRegist = true;
1004         return padding;
1005     }
1006     padding.SetEdges(NG::CalcLength(length.IsNonNegative() ? length : CalcDimension()));
1007     return padding;
1008 }
1009 
SetPaddings(const std::optional<CalcDimension> & top,const std::optional<CalcDimension> & bottom,const std::optional<CalcDimension> & left,const std::optional<CalcDimension> & right)1010 NG::PaddingProperty JSTextField::SetPaddings(const std::optional<CalcDimension>& top,
1011     const std::optional<CalcDimension>& bottom, const std::optional<CalcDimension>& left,
1012     const std::optional<CalcDimension>& right)
1013 {
1014     NG::PaddingProperty paddings;
1015     if (top.has_value()) {
1016         if (top.value().Unit() == DimensionUnit::CALC) {
1017             paddings.top =
1018                 NG::CalcLength(top.value().IsNonNegative() ? top.value().CalcValue() : CalcDimension().CalcValue());
1019         } else {
1020             paddings.top = NG::CalcLength(top.value().IsNonNegative() ? top.value() : CalcDimension());
1021         }
1022     }
1023     if (bottom.has_value()) {
1024         if (bottom.value().Unit() == DimensionUnit::CALC) {
1025             paddings.bottom = NG::CalcLength(
1026                 bottom.value().IsNonNegative() ? bottom.value().CalcValue() : CalcDimension().CalcValue());
1027         } else {
1028             paddings.bottom = NG::CalcLength(bottom.value().IsNonNegative() ? bottom.value() : CalcDimension());
1029         }
1030     }
1031     if (left.has_value()) {
1032         if (left.value().Unit() == DimensionUnit::CALC) {
1033             paddings.left =
1034                 NG::CalcLength(left.value().IsNonNegative() ? left.value().CalcValue() : CalcDimension().CalcValue());
1035         } else {
1036             paddings.left = NG::CalcLength(left.value().IsNonNegative() ? left.value() : CalcDimension());
1037         }
1038     }
1039     if (right.has_value()) {
1040         if (right.value().Unit() == DimensionUnit::CALC) {
1041             paddings.right =
1042                 NG::CalcLength(right.value().IsNonNegative() ? right.value().CalcValue() : CalcDimension().CalcValue());
1043         } else {
1044             paddings.right = NG::CalcLength(right.value().IsNonNegative() ? right.value() : CalcDimension());
1045         }
1046     }
1047 
1048     return paddings;
1049 }
1050 
JsBorder(const JSCallbackInfo & info)1051 void JSTextField::JsBorder(const JSCallbackInfo& info)
1052 {
1053     if (!info[0]->IsObject()) {
1054         CalcDimension borderWidth;
1055         ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
1056         ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
1057         ViewAbstractModel::GetInstance()->SetBorderRadius(borderWidth);
1058         ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
1059         ViewAbstractModel::GetInstance()->SetDashGap(Dimension(-1));
1060         ViewAbstractModel::GetInstance()->SetDashWidth(Dimension(-1));
1061         return;
1062     }
1063     JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
1064 
1065     auto valueWidth = object->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH));
1066     if (!valueWidth->IsUndefined()) {
1067         JSViewAbstract::ParseBorderWidth(valueWidth);
1068     }
1069 
1070     // use default value when undefined.
1071     JSViewAbstract::ParseBorderColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR)));
1072 
1073     auto valueRadius = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS));
1074     if (!valueRadius->IsUndefined()) {
1075         JSViewAbstract::ParseBorderRadius(valueRadius);
1076     }
1077     // use default value when undefined.
1078     JSViewAbstract::ParseBorderStyle(object->GetProperty(static_cast<int32_t>(ArkUIIndex::STYLE)));
1079 
1080     auto dashGap = object->GetProperty("dashGap");
1081     if (!dashGap->IsUndefined()) {
1082         JSViewAbstract::ParseDashGap(dashGap);
1083     }
1084     auto dashWidth = object->GetProperty("dashWidth");
1085     if (!dashWidth->IsUndefined()) {
1086         JSViewAbstract::ParseDashWidth(dashWidth);
1087     }
1088 
1089     TextFieldModel::GetInstance()->SetBackBorder();
1090     info.ReturnSelf();
1091 }
1092 
JsBorderWidth(const JSCallbackInfo & info)1093 void JSTextField::JsBorderWidth(const JSCallbackInfo& info)
1094 {
1095     auto jsValue = info[0];
1096     if (!jsValue->IsObject() && !jsValue->IsString() && !jsValue->IsNumber()) {
1097         return;
1098     }
1099     JSViewAbstract::JsBorderWidth(info);
1100     TextFieldModel::GetInstance()->SetBackBorder();
1101 }
1102 
JsBorderColor(const JSCallbackInfo & info)1103 void JSTextField::JsBorderColor(const JSCallbackInfo& info)
1104 {
1105     auto jsValue = info[0];
1106     if (!jsValue->IsObject() && !jsValue->IsString() && !jsValue->IsNumber()) {
1107         return;
1108     }
1109     JSViewAbstract::JsBorderColor(info);
1110     TextFieldModel::GetInstance()->SetBackBorder();
1111 }
1112 
JsBorderStyle(const JSCallbackInfo & info)1113 void JSTextField::JsBorderStyle(const JSCallbackInfo& info)
1114 {
1115     auto jsValue = info[0];
1116     if (!jsValue->IsObject() && !jsValue->IsNumber()) {
1117         return;
1118     }
1119     JSViewAbstract::JsBorderStyle(info);
1120     TextFieldModel::GetInstance()->SetBackBorder();
1121 }
1122 
GetBorderRadiusByLengthMetrics(const char * key,JSRef<JSObject> & object,std::optional<CalcDimension> & radius)1123 void JSTextField::GetBorderRadiusByLengthMetrics(const char* key, JSRef<JSObject>& object,
1124     std::optional<CalcDimension>& radius)
1125 {
1126     if (object->HasProperty(key) && object->GetProperty(key)->IsObject()) {
1127         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(object->GetProperty(key));
1128         CalcDimension value;
1129         ParseJsLengthMetrics(startObj, value);
1130         radius = value;
1131     }
1132 }
1133 
ParseAllBorderRadiuses(JSRef<JSObject> & object,CalcDimension & topLeft,CalcDimension & topRight,CalcDimension & bottomLeft,CalcDimension & bottomRight)1134 bool JSTextField::ParseAllBorderRadiuses(JSRef<JSObject>& object, CalcDimension& topLeft,
1135     CalcDimension& topRight, CalcDimension& bottomLeft, CalcDimension& bottomRight)
1136 {
1137     if (object->HasProperty(TOP_START_PROPERTY) || object->HasProperty(TOP_END_PROPERTY) ||
1138         object->HasProperty(BOTTOM_START_PROPERTY) || object->HasProperty(BOTTOM_END_PROPERTY)) {
1139         std::optional<CalcDimension> topStart;
1140         std::optional<CalcDimension> topEnd;
1141         std::optional<CalcDimension> bottomStart;
1142         std::optional<CalcDimension> bottomEnd;
1143         GetBorderRadiusByLengthMetrics(TOP_START_PROPERTY, object, topStart);
1144         GetBorderRadiusByLengthMetrics(TOP_END_PROPERTY, object, topEnd);
1145         GetBorderRadiusByLengthMetrics(BOTTOM_START_PROPERTY, object, bottomStart);
1146         GetBorderRadiusByLengthMetrics(BOTTOM_END_PROPERTY, object, bottomEnd);
1147         topLeft = topStart.has_value() ? topStart.value() : topLeft;
1148         topRight = topEnd.has_value() ? topEnd.value() : topRight;
1149         bottomLeft = bottomStart.has_value() ? bottomStart.value() : bottomLeft;
1150         bottomRight = bottomEnd.has_value() ? bottomEnd.value() : bottomRight;
1151         return true;
1152     }
1153     JSViewAbstract::ParseJsDimensionVp(object->GetProperty("topLeft"), topLeft);
1154     JSViewAbstract::ParseJsDimensionVp(object->GetProperty("topRight"), topRight);
1155     JSViewAbstract::ParseJsDimensionVp(object->GetProperty("bottomLeft"), bottomLeft);
1156     JSViewAbstract::ParseJsDimensionVp(object->GetProperty("bottomRight"), bottomRight);
1157     return false;
1158 }
1159 
ParseBorderRadius(const JSRef<JSVal> & args)1160 void JSTextField::ParseBorderRadius(const JSRef<JSVal>& args)
1161 {
1162     CalcDimension borderRadius;
1163     if (ParseJsDimensionVp(args, borderRadius)) {
1164         ViewAbstractModel::GetInstance()->SetBorderRadius(borderRadius);
1165     } else if (args->IsObject()) {
1166         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
1167         CalcDimension topLeft;
1168         CalcDimension topRight;
1169         CalcDimension bottomLeft;
1170         CalcDimension bottomRight;
1171         if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) {
1172             ViewAbstractModel::GetInstance()->SetBorderRadius(
1173                 JSViewAbstract::GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
1174                 return;
1175         }
1176         ViewAbstractModel::GetInstance()->SetBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
1177     }
1178 }
1179 
JsBorderRadius(const JSCallbackInfo & info)1180 void JSTextField::JsBorderRadius(const JSCallbackInfo& info)
1181 {
1182     auto jsValue = info[0];
1183     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING,
1184         JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
1185     if (!CheckJSCallbackInfo("JsBorderRadius", jsValue, checkList)) {
1186         auto textFieldTheme = GetTheme<TextFieldTheme>();
1187         CHECK_NULL_VOID(textFieldTheme);
1188         auto borderRadiusTheme = textFieldTheme->GetBorderRadius();
1189         NG::BorderRadiusProperty defaultBorderRadius {
1190             borderRadiusTheme.GetX(), borderRadiusTheme.GetY(),
1191             borderRadiusTheme.GetY(), borderRadiusTheme.GetX(),
1192         };
1193         ViewAbstractModel::GetInstance()->SetBorderRadius(defaultBorderRadius);
1194         return;
1195     }
1196     ParseBorderRadius(jsValue);
1197     TextFieldModel::GetInstance()->SetBackBorder();
1198 }
1199 
JsHoverEffect(const JSCallbackInfo & info)1200 void JSTextField::JsHoverEffect(const JSCallbackInfo& info)
1201 {
1202     auto jsValue = info[0];
1203     if (!jsValue->IsNumber()) {
1204         return;
1205     }
1206     TextFieldModel::GetInstance()->SetHoverEffect(static_cast<HoverEffectType>(jsValue->ToNumber<int32_t>()));
1207 }
1208 
SetOnEditChanged(const JSCallbackInfo & info)1209 void JSTextField::SetOnEditChanged(const JSCallbackInfo& info)
1210 {
1211     auto jsValue = info[0];
1212     CHECK_NULL_VOID(jsValue->IsFunction());
1213     JsEventCallback<void(bool)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(jsValue));
1214     TextFieldModel::GetInstance()->SetOnEditChanged(std::move(callback));
1215 }
1216 
JsKeepEditableState(panda::JsiRuntimeCallInfo * info)1217 Local<JSValueRef> JSTextField::JsKeepEditableState(panda::JsiRuntimeCallInfo *info)
1218 {
1219     Local<JSValueRef> thisObj = info->GetThisRef();
1220     auto eventInfo = static_cast<NG::TextFieldCommonEvent*>(
1221         panda::Local<panda::ObjectRef>(thisObj)->GetNativePointerField(info->GetVM(), 0));
1222     if (eventInfo) {
1223         eventInfo->SetKeepEditable(true);
1224     }
1225     return JSValueRef::Undefined(info->GetVM());
1226 }
1227 
CreateJsTextFieldCommonEvent(const JSCallbackInfo & info)1228 void JSTextField::CreateJsTextFieldCommonEvent(const JSCallbackInfo &info)
1229 {
1230     if (info.Length() < 1 || !info[0]->IsObject()) {
1231         return;
1232     }
1233     auto jsValue = info[0];
1234     auto jsTextFunc = AceType::MakeRefPtr<JsCommonEventFunction<NG::TextFieldCommonEvent, 2>>(
1235         JSRef<JSFunc>::Cast(jsValue));
1236     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1237     auto callback = [execCtx = info.GetExecutionContext(), func = std::move(jsTextFunc), node = targetNode](int32_t key,
1238                        NG::TextFieldCommonEvent& event) {
1239         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1240         ACE_SCORING_EVENT("onSubmit");
1241         PipelineContext::SetCallBackNode(node);
1242         JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
1243         objectTemplate->SetInternalFieldCount(2);
1244         JSRef<JSObject> object = objectTemplate->NewInstance();
1245         object->SetProperty<std::u16string>("text", event.GetText());
1246         object->SetPropertyObject("keepEditableState", JSRef<JSFunc>::New<FunctionCallback>(JsKeepEditableState));
1247         object->Wrap<NG::TextFieldCommonEvent>(&event);
1248         JSRef<JSVal> keyEvent = JSRef<JSVal>::Make(ToJSValue(key));
1249         JSRef<JSVal> dataObject = JSRef<JSVal>::Cast(object);
1250         JSRef<JSVal> param[2] = {keyEvent, dataObject};
1251         func->Execute(param);
1252         UiSessionManager::GetInstance()->ReportComponentChangeEvent("event", "onSubmit");
1253     };
1254     TextFieldModel::GetInstance()->SetOnSubmit(std::move(callback));
1255 }
1256 
SetOnSubmit(const JSCallbackInfo & info)1257 void JSTextField::SetOnSubmit(const JSCallbackInfo& info)
1258 {
1259     auto jsValue = info[0];
1260     CHECK_NULL_VOID(jsValue->IsFunction());
1261 #ifdef NG_BUILD
1262     CreateJsTextFieldCommonEvent(info);
1263 #else
1264     if (Container::IsCurrentUseNewPipeline()) {
1265         CreateJsTextFieldCommonEvent(info);
1266     } else {
1267         JsEventCallback<void(int32_t)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(jsValue));
1268         TextFieldModel::GetInstance()->SetOnSubmit(std::move(callback));
1269     }
1270 #endif
1271 }
1272 
CreateJsOnChangeObj(const PreviewText & previewText)1273 JSRef<JSVal> JSTextField::CreateJsOnChangeObj(const PreviewText& previewText)
1274 {
1275     JSRef<JSObject> previewTextObj = JSRef<JSObject>::New();
1276     previewTextObj->SetProperty<int32_t>("offset", previewText.offset);
1277     previewTextObj->SetProperty<std::u16string>("value", previewText.value);
1278     return JSRef<JSVal>::Cast(previewTextObj);
1279 }
1280 
SetOnChange(const JSCallbackInfo & info)1281 void JSTextField::SetOnChange(const JSCallbackInfo& info)
1282 {
1283     auto jsValue = info[0];
1284     CHECK_NULL_VOID(jsValue->IsFunction());
1285     auto jsChangeFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(jsValue));
1286     auto onChange = [execCtx = info.GetExecutionContext(), func = std::move(jsChangeFunc)](
1287         const ChangeValueInfo& changeValueInfo) {
1288         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1289         ACE_SCORING_EVENT("onChange");
1290         JSRef<JSVal> valueObj = JSRef<JSVal>::Make(ToJSValue(changeValueInfo.value));
1291         auto previewTextObj = CreateJsOnChangeObj(changeValueInfo.previewText);
1292         auto optionsObj = JSRef<JSObject>::New();
1293         auto rangeBeforeObj = JSRef<JSObject>::New();
1294         rangeBeforeObj->SetProperty<int32_t>("start", changeValueInfo.rangeBefore.start);
1295         rangeBeforeObj->SetProperty<int32_t>("end", changeValueInfo.rangeBefore.end);
1296         optionsObj->SetPropertyObject("rangeBefore", rangeBeforeObj);
1297         auto rangeAfterObj = JSRef<JSObject>::New();
1298         rangeAfterObj->SetProperty<int32_t>("start", changeValueInfo.rangeAfter.start);
1299         rangeAfterObj->SetProperty<int32_t>("end", changeValueInfo.rangeAfter.end);
1300         optionsObj->SetPropertyObject("rangeAfter", rangeAfterObj);
1301         optionsObj->SetProperty<std::u16string>("oldContent", changeValueInfo.oldContent);
1302         auto oldPreviewTextObj = CreateJsOnChangeObj(changeValueInfo.oldPreviewText);
1303         optionsObj->SetPropertyObject("oldPreviewText", oldPreviewTextObj);
1304         JSRef<JSVal> argv[] = { valueObj, previewTextObj, optionsObj };
1305         func->ExecuteJS(3, argv);
1306     };
1307     TextFieldModel::GetInstance()->SetOnChange(std::move(onChange));
1308 }
1309 
SetOnTextSelectionChange(const JSCallbackInfo & info)1310 void JSTextField::SetOnTextSelectionChange(const JSCallbackInfo& info)
1311 {
1312     auto jsValue = info[0];
1313     CHECK_NULL_VOID(jsValue->IsFunction());
1314     JsEventCallback<void(int32_t, int32_t)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(jsValue));
1315     TextFieldModel::GetInstance()->SetOnTextSelectionChange(std::move(callback));
1316 }
1317 
SetOnSecurityStateChange(const JSCallbackInfo & info)1318 void JSTextField::SetOnSecurityStateChange(const JSCallbackInfo& info)
1319 {
1320     auto jsValue = info[0];
1321     CHECK_NULL_VOID(jsValue->IsFunction());
1322     JsEventCallback<void(bool)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(jsValue));
1323     TextFieldModel::GetInstance()->SetOnSecurityStateChange(std::move(callback));
1324 }
1325 
SetOnContentScroll(const JSCallbackInfo & info)1326 void JSTextField::SetOnContentScroll(const JSCallbackInfo& info)
1327 {
1328     auto jsValue = info[0];
1329     CHECK_NULL_VOID(jsValue->IsFunction());
1330     JsEventCallback<void(float, float)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(jsValue));
1331     TextFieldModel::GetInstance()->SetOnContentScroll(std::move(callback));
1332 }
1333 
SetOnCopy(const JSCallbackInfo & info)1334 void JSTextField::SetOnCopy(const JSCallbackInfo& info)
1335 {
1336     auto jsValue = info[0];
1337     CHECK_NULL_VOID(jsValue->IsFunction());
1338     JsEventCallback<void(const std::u16string&)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(jsValue));
1339     TextFieldModel::GetInstance()->SetOnCopy(std::move(callback));
1340 }
1341 
SetOnCut(const JSCallbackInfo & info)1342 void JSTextField::SetOnCut(const JSCallbackInfo& info)
1343 {
1344     auto jsValue = info[0];
1345     CHECK_NULL_VOID(jsValue->IsFunction());
1346     JsEventCallback<void(const std::u16string&)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(jsValue));
1347     TextFieldModel::GetInstance()->SetOnCut(std::move(callback));
1348 }
1349 
CreateJSTextCommonEvent(NG::TextCommonEvent & event)1350 JSRef<JSVal> JSTextField::CreateJSTextCommonEvent(NG::TextCommonEvent& event)
1351 {
1352     JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
1353     objectTemplate->SetInternalFieldCount(1);
1354     JSRef<JSObject> object = objectTemplate->NewInstance();
1355     object->SetPropertyObject("preventDefault", JSRef<JSFunc>::New<FunctionCallback>(JsPreventDefault));
1356     object->Wrap<NG::TextCommonEvent>(&event);
1357     return JSRef<JSVal>::Cast(object);
1358 }
1359 
SetOnPaste(const JSCallbackInfo & info)1360 void JSTextField::SetOnPaste(const JSCallbackInfo& info)
1361 {
1362     auto jsValue = info[0];
1363     CHECK_NULL_VOID(jsValue->IsFunction());
1364     auto jsTextFunc = AceType::MakeRefPtr<JsCitedEventFunction<NG::TextCommonEvent, 2>>(
1365         JSRef<JSFunc>::Cast(jsValue), CreateJSTextCommonEvent);
1366 
1367     auto onPaste = [execCtx = info.GetExecutionContext(), func = std::move(jsTextFunc)](
1368         const std::u16string& val, NG::TextCommonEvent& info) {
1369         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1370         ACE_SCORING_EVENT("onPaste");
1371         func->Execute(val, info);
1372     };
1373     TextFieldModel::GetInstance()->SetOnPasteWithEvent(std::move(onPaste));
1374 }
1375 
SetOnClick(const JSCallbackInfo & info)1376 void JSTextField::SetOnClick(const JSCallbackInfo& info)
1377 {
1378     if (Container::IsCurrentUseNewPipeline()) {
1379         JSInteractableView::JsOnClick(info);
1380         return;
1381     }
1382     JsEventCallback<void(const ClickInfo&)> callback(info.GetExecutionContext(), JSRef<JSFunc>::Cast(info[0]));
1383     TextFieldModel::GetInstance()->SetOnClick(std::move(callback));
1384     info.ReturnSelf();
1385 }
1386 
SetCopyOption(const JSCallbackInfo & info)1387 void JSTextField::SetCopyOption(const JSCallbackInfo& info)
1388 {
1389     if (info.Length() == 0) {
1390         return;
1391     }
1392     auto jsValue = info[0];
1393     if (jsValue->IsUndefined()) {
1394         TextFieldModel::GetInstance()->SetCopyOption(CopyOptions::Local);
1395         return;
1396     }
1397     auto copyOptions = CopyOptions::Local;
1398     if (jsValue->IsNumber()) {
1399         auto emunNumber = jsValue->ToNumber<int>();
1400         copyOptions = static_cast<CopyOptions>(emunNumber);
1401     }
1402     TextFieldModel::GetInstance()->SetCopyOption(copyOptions);
1403 }
1404 
SetShowUnderline(const JSCallbackInfo & info)1405 void JSTextField::SetShowUnderline(const JSCallbackInfo& info)
1406 {
1407     auto jsValue = info[0];
1408     if (!jsValue->IsBoolean()) {
1409         TextFieldModel::GetInstance()->SetShowUnderline(false);
1410         return;
1411     }
1412     TextFieldModel::GetInstance()->SetShowUnderline(jsValue->ToBoolean());
1413 }
1414 
SetUnderlineColorObject(const JSRef<JSObject> & param)1415 void JSTextField::SetUnderlineColorObject(const JSRef<JSObject>& param)
1416 {
1417     UnregisterResource("underlineColorTyping");
1418     UnregisterResource("underlineColorNormal");
1419     UnregisterResource("underlineColorError");
1420     UnregisterResource("underlineColorDisable");
1421     UserUnderlineColor userColor = UserUnderlineColor();
1422     auto typingColorProp = param->GetProperty("typing");
1423     Color typing;
1424     RefPtr<ResourceObject> typingObject;
1425     if (ParseJsColor(typingColorProp, typing, typingObject)) {
1426         userColor.typing = typing;
1427         if (SystemProperties::ConfigChangePerform() && typingObject) {
1428             RegisterResource<Color>("underlineColorTyping", typingObject, typing);
1429         }
1430     }
1431     auto normalColorProp = param->GetProperty("normal");
1432     Color normal;
1433     RefPtr<ResourceObject> normalObject;
1434     if (ParseJsColor(normalColorProp, normal, normalObject)) {
1435         userColor.normal = normal;
1436         if (SystemProperties::ConfigChangePerform() && normalObject) {
1437             RegisterResource<Color>("underlineColorNormal", normalObject, normal);
1438         }
1439     }
1440     auto errorColorProp = param->GetProperty("error");
1441     Color error;
1442     RefPtr<ResourceObject> errorObject;
1443     if (ParseJsColor(errorColorProp, error, errorObject)) {
1444         userColor.error = error;
1445         if (SystemProperties::ConfigChangePerform() && errorObject) {
1446             RegisterResource<Color>("underlineColorError", errorObject, error);
1447         }
1448     }
1449     auto disableColorProp = param->GetProperty("disable");
1450     Color disable;
1451     RefPtr<ResourceObject> disableObject;
1452     if (ParseJsColor(disableColorProp, disable, disableObject)) {
1453         userColor.disable = disable;
1454         if (SystemProperties::ConfigChangePerform() && disableObject) {
1455             RegisterResource<Color>("underlineColorDisable", disableObject, disable);
1456         }
1457     }
1458     TextFieldModel::GetInstance()->SetUserUnderlineColor(userColor);
1459 }
1460 
SetUnderlineColor(const JSCallbackInfo & info)1461 void JSTextField::SetUnderlineColor(const JSCallbackInfo& info)
1462 {
1463     if (info.Length() < 1) {
1464         return;
1465     }
1466     auto jsValue = info[0];
1467     Color underlineColor;
1468     RefPtr<ResourceObject> resourceObject;
1469     if (ParseJsColor(jsValue, underlineColor, resourceObject)) {
1470         TextFieldModel::GetInstance()->SetNormalUnderlineColor(underlineColor);
1471         if (SystemProperties::ConfigChangePerform() && resourceObject) {
1472             RegisterResource<Color>("underlineColorNormal", resourceObject, underlineColor);
1473         } else {
1474             UnregisterResource("underlineColorNormal");
1475         }
1476     } else if (jsValue->IsObject()) {
1477         SetUnderlineColorObject(JSRef<JSObject>::Cast(jsValue));
1478     } else {
1479         TextFieldModel::GetInstance()->SetUserUnderlineColor(UserUnderlineColor());
1480         if (SystemProperties::ConfigChangePerform()) {
1481             UnregisterResource("underlineColorTyping");
1482             UnregisterResource("underlineColorNormal");
1483             UnregisterResource("underlineColorError");
1484             UnregisterResource("underlineColorDisable");
1485         }
1486     }
1487 }
1488 
ParseOnIconSrc(const JSRef<JSVal> & showVal,PasswordIcon & passwordIcon)1489 void JSTextField::ParseOnIconSrc(const JSRef<JSVal>& showVal, PasswordIcon& passwordIcon)
1490 {
1491     UnregisterResource("onIconSrc");
1492     if (showVal->IsString()) {
1493         passwordIcon.showResult = showVal->ToString();
1494     }
1495     if (showVal->IsObject()) {
1496         JSRef<JSVal> bundleName = JSRef<JSObject>::Cast(showVal)->GetProperty("bundleName");
1497         JSRef<JSVal> moduleName = JSRef<JSObject>::Cast(showVal)->GetProperty("moduleName");
1498         if (bundleName->IsString()) {
1499             passwordIcon.showBundleName = bundleName->ToString();
1500         }
1501         if (moduleName->IsString()) {
1502             passwordIcon.showModuleName = moduleName->ToString();
1503         }
1504         RefPtr<ResourceObject> resourceObject;
1505         ParseJsMedia(JSRef<JSObject>::Cast(showVal), passwordIcon.showResult, resourceObject);
1506         if (SystemProperties::ConfigChangePerform() && resourceObject) {
1507             RegisterResource<std::string>("onIconSrc", resourceObject, passwordIcon.showResult);
1508         }
1509     }
1510     if (!showVal->IsString() && !showVal->IsObject()) {
1511         passwordIcon.showResult = "";
1512     }
1513 }
1514 
ParseOffIconSrc(const JSRef<JSVal> & hideVal,PasswordIcon & passwordIcon)1515 void JSTextField::ParseOffIconSrc(const JSRef<JSVal>& hideVal, PasswordIcon& passwordIcon)
1516 {
1517     UnregisterResource("offIconSrc");
1518     if (hideVal->IsString()) {
1519         passwordIcon.hideResult = hideVal->ToString();
1520     }
1521     if (hideVal->IsObject()) {
1522         JSRef<JSVal> bundleName = JSRef<JSObject>::Cast(hideVal)->GetProperty("bundleName");
1523         JSRef<JSVal> moduleName = JSRef<JSObject>::Cast(hideVal)->GetProperty("moduleName");
1524         if (bundleName->IsString()) {
1525             passwordIcon.hideBundleName = bundleName->ToString();
1526         }
1527         if (moduleName->IsString()) {
1528             passwordIcon.hideModuleName = moduleName->ToString();
1529         }
1530         RefPtr<ResourceObject> resourceObject;
1531         ParseJsMedia(JSRef<JSObject>::Cast(hideVal), passwordIcon.hideResult);
1532         if (SystemProperties::ConfigChangePerform() && resourceObject) {
1533             RegisterResource<std::string>("offIconSrc", resourceObject, passwordIcon.hideResult);
1534         }
1535     }
1536     if (!hideVal->IsString() && !hideVal->IsObject()) {
1537         passwordIcon.hideResult = "";
1538     }
1539 }
1540 
SetPasswordIcon(const JSCallbackInfo & info)1541 void JSTextField::SetPasswordIcon(const JSCallbackInfo& info)
1542 {
1543     if (!Container::IsCurrentUseNewPipeline()) {
1544         return;
1545     }
1546     auto jsValue = info[0];
1547     if (!jsValue->IsObject()) {
1548         return;
1549     }
1550     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
1551     JSRef<JSVal> showVal = jsObj->GetProperty("onIconSrc");
1552     JSRef<JSVal> hideVal = jsObj->GetProperty("offIconSrc");
1553     PasswordIcon passwordIcon;
1554     ParseOnIconSrc(showVal, passwordIcon);
1555     ParseOffIconSrc(hideVal, passwordIcon);
1556     TextFieldModel::GetInstance()->SetPasswordIcon(passwordIcon);
1557 }
1558 
UpdateDecoration(const RefPtr<BoxComponent> & boxComponent,const RefPtr<TextFieldComponent> & component,const Border & boxBorder,const OHOS::Ace::RefPtr<OHOS::Ace::TextFieldTheme> & textFieldTheme)1559 void JSTextField::UpdateDecoration(const RefPtr<BoxComponent>& boxComponent,
1560     const RefPtr<TextFieldComponent>& component, const Border& boxBorder,
1561     const OHOS::Ace::RefPtr<OHOS::Ace::TextFieldTheme>& textFieldTheme)
1562 {
1563     if (!textFieldTheme) {
1564         return;
1565     }
1566 
1567     RefPtr<Decoration> decoration = component->GetDecoration();
1568     RefPtr<Decoration> boxDecoration = boxComponent->GetBackDecoration();
1569     if (!decoration) {
1570         decoration = AceType::MakeRefPtr<Decoration>();
1571     }
1572     if (boxDecoration) {
1573         Border border = decoration->GetBorder();
1574         border.SetLeftEdge(boxBorder.Left());
1575         border.SetRightEdge(boxBorder.Right());
1576         border.SetTopEdge(boxBorder.Top());
1577         border.SetBottomEdge(boxBorder.Bottom());
1578         border.SetBorderRadius(textFieldTheme->GetBorderRadius());
1579         decoration->SetBorder(border);
1580         component->SetOriginBorder(decoration->GetBorder());
1581 
1582         if (boxDecoration->GetImage() || boxDecoration->GetGradient().IsValid()) {
1583             // clear box properties except background image and radius.
1584             boxDecoration->SetBackgroundColor(Color::TRANSPARENT);
1585             Border border;
1586             border.SetBorderRadius(textFieldTheme->GetBorderRadius());
1587             boxDecoration->SetBorder(border);
1588         }
1589     } else {
1590         boxDecoration = AceType::MakeRefPtr<Decoration>();
1591         boxDecoration->SetBorderRadius(textFieldTheme->GetBorderRadius());
1592         boxComponent->SetBackDecoration(boxDecoration);
1593     }
1594 }
1595 
SetShowUnit(const JSCallbackInfo & info)1596 void JSTextField::SetShowUnit(const JSCallbackInfo& info)
1597 {
1598     auto jsValue = info[0];
1599     if (!jsValue->IsFunction()) {
1600         TextFieldModel::GetInstance()->SetShowUnit(nullptr);
1601         return;
1602     }
1603 
1604     auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(jsValue));
1605     auto unitFunc = [builderFunc]() { builderFunc->Execute(); };
1606     TextFieldModel::GetInstance()->SetShowUnit(std::move(unitFunc));
1607 }
1608 
SetShowError(const JSCallbackInfo & info)1609 void JSTextField::SetShowError(const JSCallbackInfo& info)
1610 {
1611     auto jsValue = info[0];
1612     if (Container::IsCurrentUseNewPipeline()) {
1613         bool isVisible = false;
1614         std::u16string errorText;
1615         RefPtr<ResourceObject> resourceObject;
1616         UnregisterResource("errorString");
1617         if (ParseJsString(jsValue, errorText, resourceObject)) {
1618             isVisible = true;
1619         }
1620         if (SystemProperties::ConfigChangePerform() && resourceObject) {
1621             RegisterResource<std::u16string>("errorString", resourceObject, errorText);
1622         }
1623         TextFieldModel::GetInstance()->SetShowError(errorText, isVisible);
1624     }
1625 }
1626 
SetShowCounter(const JSCallbackInfo & info)1627 void JSTextField::SetShowCounter(const JSCallbackInfo& info)
1628 {
1629     auto jsValue = info[0];
1630     auto secondJSValue = info[1];
1631     if ((!jsValue->IsBoolean() && !secondJSValue->IsObject())) {
1632         LOGI("The info is wrong, it is supposed to be a boolean");
1633         TextFieldModel::GetInstance()->SetShowCounter(false);
1634         return;
1635     }
1636     if (secondJSValue->IsObject()) {
1637         auto paramObject = JSRef<JSObject>::Cast(secondJSValue);
1638         auto param = paramObject->GetProperty("highlightBorder");
1639         auto isBorderShow = param->ToBoolean();
1640         if (!param->IsBoolean() || param->IsUndefined() || param->IsNull()) {
1641             TextFieldModel::GetInstance()->SetShowCounterBorder(true);
1642         } else {
1643             TextFieldModel::GetInstance()->SetShowCounterBorder(isBorderShow);
1644         }
1645         auto parameter = paramObject->GetProperty("thresholdPercentage");
1646         auto inputNumber = parameter->ToNumber<int32_t>();
1647         TextFieldModel::GetInstance()->SetCounterType(inputNumber);
1648         if (parameter->IsNull() || parameter->IsUndefined()) {
1649             TextFieldModel::GetInstance()->SetShowCounter(jsValue->ToBoolean());
1650             TextFieldModel::GetInstance()->SetCounterType(DEFAULT_MODE);
1651             return;
1652         }
1653         if (static_cast<uint32_t>(inputNumber) < MINI_VAILD_VALUE ||
1654             static_cast<uint32_t>(inputNumber) > MAX_VAILD_VALUE) {
1655             LOGI("The info is wrong, it is supposed to be a right number");
1656             TextFieldModel::GetInstance()->SetCounterType(ILLEGAL_VALUE);
1657             TextFieldModel::GetInstance()->SetShowCounter(false);
1658             return;
1659         }
1660         TextFieldModel::GetInstance()->SetShowCounter(jsValue->ToBoolean());
1661         return;
1662     }
1663     TextFieldModel::GetInstance()->SetShowCounter(jsValue->ToBoolean());
1664     TextFieldModel::GetInstance()->SetCounterType(DEFAULT_MODE);
1665     TextFieldModel::GetInstance()->SetShowCounterBorder(true);
1666 }
1667 
SetBarState(const JSCallbackInfo & info)1668 void JSTextField::SetBarState(const JSCallbackInfo& info)
1669 {
1670     if (info.Length() < 1) {
1671         TextFieldModel::GetInstance()->SetBarState(DisplayMode::AUTO);
1672         return;
1673     }
1674     auto jsValue = info[0];
1675     if (!jsValue->IsNumber()) {
1676         TextFieldModel::GetInstance()->SetBarState(DisplayMode::AUTO);
1677         return;
1678     }
1679     DisplayMode displayMode = static_cast<DisplayMode>(jsValue->ToNumber<int32_t>());
1680     TextFieldModel::GetInstance()->SetBarState(displayMode);
1681 }
1682 
SetMaxLines(const JSCallbackInfo & info)1683 void JSTextField::SetMaxLines(const JSCallbackInfo& info)
1684 {
1685     if (info.Length() < 1) {
1686         TextFieldModel::GetInstance()->SetMaxViewLines(MAX_LINES);
1687         return;
1688     }
1689     auto jsValue = info[0];
1690     if (!jsValue->IsNumber() || jsValue->ToNumber<int32_t>() <= 0) {
1691         TextFieldModel::GetInstance()->SetMaxViewLines(MAX_LINES);
1692         return;
1693     }
1694     TextFieldModel::GetInstance()->SetMaxViewLines(jsValue->ToNumber<uint32_t>());
1695 }
1696 
SetEnableKeyboardOnFocus(const JSCallbackInfo & info)1697 void JSTextField::SetEnableKeyboardOnFocus(const JSCallbackInfo& info)
1698 {
1699     if (info.Length() < 1) {
1700         return;
1701     }
1702     auto jsValue = info[0];
1703     if (jsValue->IsUndefined() || !jsValue->IsBoolean()) {
1704         TextFieldModel::GetInstance()->RequestKeyboardOnFocus(true);
1705         return;
1706     }
1707     TextFieldModel::GetInstance()->RequestKeyboardOnFocus(jsValue->ToBoolean());
1708 }
1709 
SetSelectionMenuHidden(const JSCallbackInfo & info)1710 void JSTextField::SetSelectionMenuHidden(const JSCallbackInfo& info)
1711 {
1712     if (info.Length() < 1) {
1713         return;
1714     }
1715     auto jsValue = info[0];
1716     if (jsValue->IsUndefined() || !jsValue->IsBoolean()) {
1717         TextFieldModel::GetInstance()->SetSelectionMenuHidden(false);
1718         return;
1719     }
1720     TextFieldModel::GetInstance()->SetSelectionMenuHidden(jsValue->ToBoolean());
1721 }
1722 
ParseJsCustomKeyboardBuilder(const JSCallbackInfo & info,int32_t index,std::function<void ()> & buildFunc)1723 bool JSTextField::ParseJsCustomKeyboardBuilder(
1724     const JSCallbackInfo& info, int32_t index, std::function<void()>& buildFunc)
1725 {
1726     if (info.Length() <= static_cast<uint32_t>(index) || !info[index]->IsObject()) {
1727         return false;
1728     }
1729     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[index]);
1730     auto builder = obj->GetProperty("builder");
1731     if (!builder->IsFunction()) {
1732         return false;
1733     }
1734     auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1735     CHECK_NULL_RETURN(builderFunc, false);
1736     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1737     buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = targetNode]() {
1738         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1739         ACE_SCORING_EVENT("CustomKeyboard");
1740         PipelineContext::SetCallBackNode(node);
1741         func->Execute();
1742     };
1743     return true;
1744 }
1745 
SetCustomKeyboard(const JSCallbackInfo & info)1746 void JSTextField::SetCustomKeyboard(const JSCallbackInfo& info)
1747 {
1748     if (info.Length() < 1) {
1749         return;
1750     }
1751     auto jsValue = info[0];
1752     if (jsValue->IsUndefined() || jsValue->IsNull() || !jsValue->IsObject()) {
1753         TextFieldModel::GetInstance()->SetCustomKeyboard(nullptr);
1754         return;
1755     }
1756     bool supportAvoidance = false;
1757     if (info.Length() == 2 && info[1]->IsObject()) {  //  2 here refers to the number of parameters
1758         auto paramObject = JSRef<JSObject>::Cast(info[1]);
1759         auto isSupportAvoidance = paramObject->GetProperty("supportAvoidance");
1760         if (!isSupportAvoidance->IsNull() && isSupportAvoidance->IsBoolean()) {
1761             supportAvoidance = isSupportAvoidance->ToBoolean();
1762         }
1763     }
1764     std::function<void()> buildFunc;
1765     if (ParseJsCustomKeyboardBuilder(info, 0, buildFunc)) {
1766         TextFieldModel::GetInstance()->SetCustomKeyboard(std::move(buildFunc), supportAvoidance);
1767     }
1768 }
1769 
SetPasswordRules(const JSCallbackInfo & info)1770 void JSTextField::SetPasswordRules(const JSCallbackInfo& info)
1771 {
1772     auto jsValue = info[0];
1773     if (!jsValue->IsString()) {
1774         return;
1775     }
1776     auto passwordRules = jsValue->ToString();
1777     TextFieldModel::GetInstance()->SetPasswordRules(passwordRules);
1778 }
1779 
SetEnableAutoFill(const JSCallbackInfo & info)1780 void JSTextField::SetEnableAutoFill(const JSCallbackInfo& info)
1781 {
1782     auto jsValue = info[0];
1783     if (!jsValue->IsBoolean()) {
1784         TextFieldModel::GetInstance()->SetEnableAutoFill(true);
1785         return;
1786     }
1787     TextFieldModel::GetInstance()->SetEnableAutoFill(jsValue->ToBoolean());
1788 }
1789 
SetEnableAutoFillAnimation(const JSCallbackInfo & info)1790 void JSTextField::SetEnableAutoFillAnimation(const JSCallbackInfo& info)
1791 {
1792     auto jsValue = info[0];
1793     if (!jsValue->IsBoolean()) {
1794         TextFieldModel::GetInstance()->SetEnableAutoFillAnimation(true);
1795         return;
1796     }
1797     TextFieldModel::GetInstance()->SetEnableAutoFillAnimation(jsValue->ToBoolean());
1798 }
1799 
ConvertStrToCleanNodeStyle(const std::string & value)1800 static CleanNodeStyle ConvertStrToCleanNodeStyle(const std::string& value)
1801 {
1802     if (value == "CONSTANT") {
1803         return CleanNodeStyle::CONSTANT;
1804     } else if (value == "INVISIBLE") {
1805         return CleanNodeStyle::INVISIBLE;
1806     } else {
1807         return CleanNodeStyle::INPUT;
1808     }
1809 }
1810 
SetCancelButton(const JSCallbackInfo & info)1811 void JSTextField::SetCancelButton(const JSCallbackInfo& info)
1812 {
1813     UnregisterResource("cancelButtonIconColorDefault");
1814     if (info.Length() < 1 || !info[0]->IsObject()) {
1815         return;
1816     }
1817     auto param = JSRef<JSObject>::Cast(info[0]);
1818     auto theme = GetTheme<TextFieldTheme>();
1819     CHECK_NULL_VOID(theme);
1820 
1821     // set style
1822     std::string styleStr;
1823     CleanNodeStyle cleanNodeStyle;
1824     auto styleProp = param->GetProperty("style");
1825     if (!styleProp->IsNull() && ParseJsString(styleProp, styleStr)) {
1826         cleanNodeStyle = ConvertStrToCleanNodeStyle(styleStr);
1827     } else {
1828         cleanNodeStyle = CleanNodeStyle::INPUT;
1829     }
1830     TextFieldModel::GetInstance()->SetCleanNodeStyle(cleanNodeStyle);
1831     TextFieldModel::GetInstance()->SetIsShowCancelButton(true);
1832 
1833     // set default icon
1834     auto iconJsVal = param->GetProperty("icon");
1835     if (iconJsVal->IsUndefined() || iconJsVal->IsNull() || !iconJsVal->IsObject()) {
1836         SetCancelDefaultIcon();
1837         return;
1838     }
1839 
1840     auto iconParam = JSRef<JSObject>::Cast(iconJsVal);
1841     bool isSymbolIcon = iconParam->HasProperty("fontColor"); // only SymbolGlyph has fontColor property
1842     if (isSymbolIcon) {
1843         SetCancelSymbolIcon(info);
1844         return;
1845     }
1846 
1847     // set icon size
1848     CalcDimension iconSize;
1849     auto iconSizeProp = iconParam->GetProperty("size");
1850     RefPtr<ResourceObject> resourceObject;
1851     UnregisterResource("cancelButtonIconSize");
1852     if (!iconSizeProp->IsUndefined() && !iconSizeProp->IsNull() &&
1853         ParseJsDimensionVpNG(iconSizeProp, iconSize, resourceObject)) {
1854         if (LessNotEqual(iconSize.Value(), 0.0) || iconSize.Unit() == DimensionUnit::PERCENT) {
1855             iconSize = theme->GetCancelIconSize();
1856         }
1857     } else {
1858         iconSize = theme->GetCancelIconSize();
1859     }
1860     if (SystemProperties::ConfigChangePerform() && resourceObject) {
1861         RegisterResource<CalcDimension>("cancelButtonIconSize", resourceObject, iconSize);
1862     }
1863     TextFieldModel::GetInstance()->SetCancelIconSize(iconSize);
1864     SetCancelIconColorAndIconSrc(iconParam);
1865 }
1866 
SetCancelDefaultIcon()1867 void JSTextField::SetCancelDefaultIcon()
1868 {
1869     auto theme = GetTheme<TextFieldTheme>();
1870     CHECK_NULL_VOID(theme);
1871     if (Container::CurrentColorMode() == ColorMode::DARK) {
1872         TextFieldModel::GetInstance()->SetCancelIconColor(theme->GetCancelButtonIconColor());
1873     } else {
1874         TextFieldModel::GetInstance()->SetCancelIconColor(Color());
1875     }
1876     TextFieldModel::GetInstance()->SetCancelIconSize(theme->GetCancelIconSize());
1877     TextFieldModel::GetInstance()->SetCanacelIconSrc(std::string(), std::string(), std::string());
1878     TextFieldModel::GetInstance()->SetCancelSymbolIcon(nullptr);
1879     TextFieldModel::GetInstance()->SetCancelButtonSymbol(true);
1880 }
1881 
SetCancelSymbolIcon(const JSCallbackInfo & info)1882 void JSTextField::SetCancelSymbolIcon(const JSCallbackInfo& info)
1883 {
1884     if (info[0]->IsObject()) {
1885         std::function<void(WeakPtr<NG::FrameNode>)> iconSymbol = nullptr;
1886         auto param = JSRef<JSObject>::Cast(info[0]);
1887         auto iconProp = param->GetProperty("icon");
1888         SetSymbolOptionApply(info, iconSymbol, iconProp);
1889         TextFieldModel::GetInstance()->SetCancelSymbolIcon(iconSymbol);
1890         TextFieldModel::GetInstance()->SetCancelButtonSymbol(true);
1891     }
1892 }
1893 
SetCancelIconColorAndIconSrc(const JSRef<JSObject> & iconParam)1894 void JSTextField::SetCancelIconColorAndIconSrc(const JSRef<JSObject>& iconParam)
1895 {
1896     auto theme = GetTheme<TextFieldTheme>();
1897     CHECK_NULL_VOID(theme);
1898     // set icon src
1899     std::string iconSrc;
1900     std::string bundleName;
1901     std::string moduleName;
1902     auto iconSrcProp = iconParam->GetProperty("src");
1903     RefPtr<ResourceObject> resourceObject;
1904     if (iconSrcProp->IsUndefined() || iconSrcProp->IsNull() ||
1905         !ParseJsMedia(iconSrcProp, iconSrc, resourceObject)) {
1906         UnregisterResource("cancelButtonIconSrc");
1907         iconSrc = "";
1908     }
1909     if (SystemProperties::ConfigChangePerform() && resourceObject) {
1910         RegisterResource<std::string>("cancelButtonIconSrc", resourceObject, iconSrc);
1911     }
1912 
1913     GetJsMediaBundleInfo(iconSrcProp, bundleName, moduleName);
1914     TextFieldModel::GetInstance()->SetCanacelIconSrc(iconSrc, bundleName, moduleName);
1915     TextFieldModel::GetInstance()->SetCancelButtonSymbol(false);
1916     // set icon color
1917     Color iconColor;
1918     RefPtr<ResourceObject> colorObject;
1919     UnregisterResource("cancelButtonIconColor");
1920     auto iconColorProp = iconParam->GetProperty("color");
1921     if (!iconColorProp->IsUndefined() && !iconColorProp->IsNull() &&
1922         ParseJsColor(iconColorProp, iconColor, colorObject)) {
1923         if (SystemProperties::ConfigChangePerform() && colorObject) {
1924             RegisterResource<Color>("cancelButtonIconColor", colorObject, iconColor);
1925         }
1926         TextFieldModel::GetInstance()->SetCancelIconColor(iconColor);
1927         return;
1928     }
1929     auto info = ImageSourceInfo(iconSrc, bundleName, moduleName);
1930     if (info.IsSvg() && iconSrc != "") {
1931         // svg need not default color, otherwise multi color svg will render fault
1932         return;
1933     }
1934     if (SystemProperties::ConfigChangePerform()) {
1935         RefPtr<ResourceObject> resObj = AceType::MakeRefPtr<ResourceObject>("", "", -1);
1936         RegisterResource<Color>("cancelButtonIconColorDefault", resObj, iconColor);
1937     }
1938     if (Container::CurrentColorMode() == ColorMode::DARK) {
1939         TextFieldModel::GetInstance()->SetCancelIconColor(theme->GetCancelButtonIconColor());
1940     } else {
1941         TextFieldModel::GetInstance()->SetCancelIconColor(iconColor);
1942     }
1943 }
1944 
SetSelectAllValue(const JSCallbackInfo & info)1945 void JSTextField::SetSelectAllValue(const JSCallbackInfo& info)
1946 {
1947     auto infoValue = info[0];
1948     if (!infoValue->IsBoolean() || infoValue->IsUndefined() || infoValue->IsNull()) {
1949         TextFieldModel::GetInstance()->SetSelectAllValue(false);
1950         return;
1951     }
1952 
1953     bool isSetSelectAllValue = infoValue->ToBoolean();
1954     TextFieldModel::GetInstance()->SetSelectAllValue(isSetSelectAllValue);
1955 }
1956 
SetFontFeature(const JSCallbackInfo & info)1957 void JSTextField::SetFontFeature(const JSCallbackInfo& info)
1958 {
1959     if (info.Length() < 1) {
1960         return;
1961     }
1962     auto jsValue = info[0];
1963     std::string fontFeatureSettings = "";
1964     if (jsValue->IsString()) {
1965         fontFeatureSettings = jsValue->ToString();
1966     }
1967     TextFieldModel::GetInstance()->SetFontFeature(ParseFontFeatureSettings(fontFeatureSettings));
1968 }
1969 
SetKeyboardAppearance(const JSCallbackInfo & info)1970 void JSTextField::SetKeyboardAppearance(const JSCallbackInfo& info)
1971 {
1972     if (info.Length() != 1 || !info[0]->IsNumber()) {
1973         TextFieldModel::GetInstance()->SetKeyboardAppearance(
1974             static_cast<KeyboardAppearance>(KeyboardAppearance::NONE_IMMERSIVE));
1975         return;
1976     }
1977     auto keyboardAppearance = info[0]->ToNumber<uint32_t>();
1978     if (keyboardAppearance < static_cast<uint32_t>(KeyboardAppearance::NONE_IMMERSIVE) ||
1979         keyboardAppearance > static_cast<uint32_t>(KeyboardAppearance::DARK_IMMERSIVE)) {
1980         TextFieldModel::GetInstance()->SetKeyboardAppearance(
1981             static_cast<KeyboardAppearance>(KeyboardAppearance::NONE_IMMERSIVE));
1982         return;
1983     }
1984     TextFieldModel::GetInstance()->
1985         SetKeyboardAppearance(static_cast<KeyboardAppearance>(keyboardAppearance));
1986 }
1987 
SetDecoration(const JSCallbackInfo & info)1988 void JSTextField::SetDecoration(const JSCallbackInfo& info)
1989 {
1990     auto tmpInfo = info[0];
1991     UnregisterResource("decorationColor");
1992     if (!tmpInfo->IsObject()) {
1993         TextFieldModel::GetInstance()->SetTextDecoration(TextDecoration::NONE);
1994         TextFieldModel::GetInstance()->SetTextDecorationColor(Color::BLACK);
1995         TextFieldModel::GetInstance()->SetTextDecorationStyle(TextDecorationStyle::SOLID);
1996         return;
1997     }
1998     JSRef<JSObject> obj = JSRef<JSObject>::Cast(tmpInfo);
1999     JSRef<JSVal> typeValue = obj->GetProperty("type");
2000     JSRef<JSVal> colorValue = obj->GetProperty("color");
2001     JSRef<JSVal> styleValue = obj->GetProperty("style");
2002 
2003     auto pipelineContext = PipelineContext::GetCurrentContextSafelyWithCheck();
2004     CHECK_NULL_VOID(pipelineContext);
2005     auto theme = pipelineContext->GetTheme<TextFieldTheme>();
2006     CHECK_NULL_VOID(theme);
2007     TextDecoration textDecoration = theme->GetTextDecoration();
2008     if (typeValue->IsNumber()) {
2009         textDecoration = static_cast<TextDecoration>(typeValue->ToNumber<int32_t>());
2010     }
2011     Color result = theme->GetTextStyle().GetTextDecorationColor();
2012     RefPtr<ResourceObject> resourceObject;
2013     ParseJsColor(colorValue, result, Color::BLACK, resourceObject);
2014     if (resourceObject && SystemProperties::ConfigChangePerform()) {
2015         RegisterResource<Color>("decorationColor", resourceObject, result);
2016     }
2017     std::optional<TextDecorationStyle> textDecorationStyle;
2018     if (styleValue->IsNumber()) {
2019         textDecorationStyle = static_cast<TextDecorationStyle>(styleValue->ToNumber<int32_t>());
2020     } else {
2021         textDecorationStyle = DEFAULT_TEXT_DECORATION_STYLE;
2022     }
2023     TextFieldModel::GetInstance()->SetTextDecoration(textDecoration);
2024     TextFieldModel::GetInstance()->SetTextDecorationColor(result);
2025     if (textDecorationStyle) {
2026         TextFieldModel::GetInstance()->SetTextDecorationStyle(textDecorationStyle.value());
2027     }
2028 }
2029 
SetMinFontSize(const JSCallbackInfo & info)2030 void JSTextField::SetMinFontSize(const JSCallbackInfo& info)
2031 {
2032     if (info.Length() < 1) {
2033         return;
2034     }
2035     CalcDimension minFontSize;
2036     RefPtr<ResourceObject> resourceObject;
2037     UnregisterResource("minFontSize");
2038     if (!ParseJsDimensionFpNG(info[0], minFontSize, resourceObject, false)) {
2039         TextFieldModel::GetInstance()->SetAdaptMinFontSize(CalcDimension());
2040         return;
2041     }
2042     if (SystemProperties::ConfigChangePerform() && resourceObject) {
2043         RegisterResource<CalcDimension>("minFontSize", resourceObject, minFontSize);
2044     }
2045     if (minFontSize.IsNegative()) {
2046         minFontSize = CalcDimension();
2047     }
2048     TextFieldModel::GetInstance()->SetAdaptMinFontSize(minFontSize);
2049 }
2050 
SetMaxFontSize(const JSCallbackInfo & info)2051 void JSTextField::SetMaxFontSize(const JSCallbackInfo& info)
2052 {
2053     if (info.Length() < 1) {
2054         return;
2055     }
2056     auto pipelineContext = PipelineContext::GetCurrentContextSafelyWithCheck();
2057     CHECK_NULL_VOID(pipelineContext);
2058     auto theme = pipelineContext->GetTheme<TextFieldTheme>();
2059     CHECK_NULL_VOID(theme);
2060     CalcDimension maxFontSize = theme->GetTextStyle().GetAdaptMaxFontSize();
2061     RefPtr<ResourceObject> resourceObject;
2062     UnregisterResource("maxFontSize");
2063     if (!ParseJsDimensionFpNG(info[0], maxFontSize, resourceObject, false)) {
2064         maxFontSize = theme->GetTextStyle().GetAdaptMaxFontSize();
2065         TextFieldModel::GetInstance()->SetAdaptMaxFontSize(maxFontSize);
2066         return;
2067     }
2068     if (SystemProperties::ConfigChangePerform() && resourceObject) {
2069         RegisterResource<CalcDimension>("maxFontSize", resourceObject, maxFontSize);
2070     }
2071     if (maxFontSize.IsNegative()) {
2072         maxFontSize = theme->GetTextStyle().GetAdaptMaxFontSize();
2073     }
2074     TextFieldModel::GetInstance()->SetAdaptMaxFontSize(maxFontSize);
2075 }
2076 
SetHeightAdaptivePolicy(int32_t value)2077 void JSTextField::SetHeightAdaptivePolicy(int32_t value)
2078 {
2079     if (value < 0 || value >= static_cast<int32_t>(HEIGHT_ADAPTIVE_POLICY.size())) {
2080         value = 0;
2081     }
2082     TextFieldModel::GetInstance()->SetHeightAdaptivePolicy(HEIGHT_ADAPTIVE_POLICY[value]);
2083 }
2084 
SetLetterSpacing(const JSCallbackInfo & info)2085 void JSTextField::SetLetterSpacing(const JSCallbackInfo& info)
2086 {
2087     CalcDimension value;
2088     RefPtr<ResourceObject> resourceObject;
2089     if (!ParseJsDimensionFpNG(info[0], value, resourceObject, false)) {
2090         value.Reset();
2091         TextFieldModel::GetInstance()->SetLetterSpacing(value);
2092         UnregisterResource("letterSpacing");
2093         return;
2094     }
2095     if (SystemProperties::ConfigChangePerform() && resourceObject) {
2096         RegisterResource<CalcDimension>("letterSpacing", resourceObject, value);
2097     }
2098     TextFieldModel::GetInstance()->SetLetterSpacing(value);
2099 }
2100 
SetLineHeight(const JSCallbackInfo & info)2101 void JSTextField::SetLineHeight(const JSCallbackInfo& info)
2102 {
2103     CalcDimension value;
2104     RefPtr<ResourceObject> resourceObject;
2105     UnregisterResource("lineHeight");
2106     if (!ParseJsDimensionFpNG(info[0], value, resourceObject)) {
2107         value.Reset();
2108         TextFieldModel::GetInstance()->SetLineHeight(value);
2109         return;
2110     }
2111     if (SystemProperties::ConfigChangePerform() && resourceObject) {
2112         RegisterResource<CalcDimension>("lineHeight", resourceObject, value);
2113     }
2114     if (value.IsNegative()) {
2115         value.Reset();
2116     }
2117     TextFieldModel::GetInstance()->SetLineHeight(value);
2118 }
2119 
SetHalfLeading(const JSCallbackInfo & info)2120 void JSTextField::SetHalfLeading(const JSCallbackInfo& info)
2121 {
2122     if (info.Length() < 1) {
2123         return;
2124     }
2125     auto jsValue = info[0];
2126     bool halfLeading = jsValue->IsBoolean() ? jsValue->ToBoolean() : false;
2127     TextFieldModel::GetInstance()->SetHalfLeading(halfLeading);
2128 }
2129 
SetLineSpacing(const JSCallbackInfo & info)2130 void JSTextField::SetLineSpacing(const JSCallbackInfo& info)
2131 {
2132     CalcDimension value;
2133     if (!ParseLengthMetricsToPositiveDimension(info[0], value)) {
2134         value.Reset();
2135     }
2136     if (value.IsNegative()) {
2137         value.Reset();
2138     }
2139     TextFieldModel::GetInstance()->SetLineSpacing(value);
2140     if (info.Length() < 2) { // 2 : two args
2141         TextFieldModel::GetInstance()->SetIsOnlyBetweenLines(false);
2142         return;
2143     }
2144     auto jsonValue = info[1];
2145     if (!jsonValue->IsObject()) {
2146         TextFieldModel::GetInstance()->SetIsOnlyBetweenLines(false);
2147         return;
2148     }
2149     auto paramObject = JSRef<JSObject>::Cast(jsonValue);
2150     auto param = paramObject->GetProperty("onlyBetweenLines");
2151     if (!param->IsBoolean() || param->IsUndefined() || param->IsNull()) {
2152         TextFieldModel::GetInstance()->SetIsOnlyBetweenLines(false);
2153     } else {
2154         auto isOnlyBetweenLines = param->ToBoolean();
2155         TextFieldModel::GetInstance()->SetIsOnlyBetweenLines(isOnlyBetweenLines);
2156     }
2157 }
2158 
SetTextOverflow(const JSCallbackInfo & info)2159 void JSTextField::SetTextOverflow(const JSCallbackInfo& info)
2160 {
2161     do {
2162         if (info.Length() < 1) {
2163             break;
2164         }
2165         auto tmpInfo = info[0];
2166         int32_t overflow = 0;
2167         if (tmpInfo->IsUndefined() || tmpInfo->IsNull() || !tmpInfo->IsNumber()) {
2168             overflow = DEFAULT_OVERFLOW;
2169         } else if (tmpInfo->IsNumber()) {
2170             overflow = tmpInfo->ToNumber<int32_t>();
2171             if (overflow < 0 || overflow >= static_cast<int32_t>(TEXT_OVERFLOWS.size())) {
2172                 overflow = DEFAULT_OVERFLOW;
2173             }
2174         }
2175         TextFieldModel::GetInstance()->SetTextOverflow(TEXT_OVERFLOWS[overflow]);
2176     } while (false);
2177 
2178     info.SetReturnValue(info.This());
2179 }
2180 
SetTextIndent(const JSCallbackInfo & info)2181 void JSTextField::SetTextIndent(const JSCallbackInfo& info)
2182 {
2183     CalcDimension value;
2184     RefPtr<ResourceObject> resourceObject;
2185     if (!ParseJsDimensionVpNG(info[0], value, resourceObject, true)) {
2186         value.Reset();
2187         UnregisterResource("textIndent");
2188     }
2189     if (SystemProperties::ConfigChangePerform() && resourceObject) {
2190         RegisterResource<CalcDimension>("textIndent", resourceObject, value);
2191     }
2192     TextFieldModel::GetInstance()->SetTextIndent(value);
2193 }
2194 
CreateJsAboutToIMEInputObj(const InsertValueInfo & insertValue)2195 JSRef<JSVal> JSTextField::CreateJsAboutToIMEInputObj(const InsertValueInfo& insertValue)
2196 {
2197     JSRef<JSObject> aboutToIMEInputObj = JSRef<JSObject>::New();
2198     aboutToIMEInputObj->SetProperty<int32_t>("insertOffset", insertValue.insertOffset);
2199     aboutToIMEInputObj->SetProperty<std::u16string>("insertValue", insertValue.insertValue);
2200     return JSRef<JSVal>::Cast(aboutToIMEInputObj);
2201 }
2202 
OnWillInsertValue(const JSCallbackInfo & info)2203 void JSTextField::OnWillInsertValue(const JSCallbackInfo& info)
2204 {
2205     auto jsValue = info[0];
2206     CHECK_NULL_VOID(jsValue->IsFunction());
2207     auto jsAboutToIMEInputFunc = AceType::MakeRefPtr<JsEventFunction<InsertValueInfo, 1>>(
2208         JSRef<JSFunc>::Cast(jsValue), CreateJsAboutToIMEInputObj);
2209     auto callback = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToIMEInputFunc)](
2210                         const InsertValueInfo& insertValue) -> bool {
2211         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, true);
2212         auto ret = func->ExecuteWithValue(insertValue);
2213         if (ret->IsBoolean()) {
2214             return ret->ToBoolean();
2215         }
2216         return true;
2217     };
2218     TextFieldModel::GetInstance()->SetOnWillInsertValueEvent(std::move(callback));
2219 }
2220 
CreateJsDeleteToIMEObj(const DeleteValueInfo & deleteValueInfo)2221 JSRef<JSVal> JSTextField::CreateJsDeleteToIMEObj(const DeleteValueInfo& deleteValueInfo)
2222 {
2223     JSRef<JSObject> aboutToIMEInputObj = JSRef<JSObject>::New();
2224     aboutToIMEInputObj->SetProperty<int32_t>("deleteOffset", deleteValueInfo.deleteOffset);
2225     aboutToIMEInputObj->SetProperty<int32_t>("direction", static_cast<int32_t>(deleteValueInfo.direction));
2226     aboutToIMEInputObj->SetProperty<std::u16string>("deleteValue", deleteValueInfo.deleteValue);
2227     return JSRef<JSVal>::Cast(aboutToIMEInputObj);
2228 }
2229 
OnDidInsertValue(const JSCallbackInfo & info)2230 void JSTextField::OnDidInsertValue(const JSCallbackInfo& info)
2231 {
2232     auto jsValue = info[0];
2233     CHECK_NULL_VOID(jsValue->IsFunction());
2234     auto jsAboutToIMEInputFunc = AceType::MakeRefPtr<JsEventFunction<InsertValueInfo, 1>>(
2235         JSRef<JSFunc>::Cast(jsValue), CreateJsAboutToIMEInputObj);
2236     auto callback = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToIMEInputFunc)](
2237                         const InsertValueInfo& insertValue) {
2238         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2239         func->ExecuteWithValue(insertValue);
2240     };
2241     TextFieldModel::GetInstance()->SetOnDidInsertValueEvent(std::move(callback));
2242 }
2243 
OnWillDelete(const JSCallbackInfo & info)2244 void JSTextField::OnWillDelete(const JSCallbackInfo& info)
2245 {
2246     auto jsValue = info[0];
2247     CHECK_NULL_VOID(jsValue->IsFunction());
2248     auto jsAboutToIMEInputFunc =
2249         AceType::MakeRefPtr<JsEventFunction<DeleteValueInfo, 1>>(JSRef<JSFunc>::Cast(jsValue), CreateJsDeleteToIMEObj);
2250     auto callback = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToIMEInputFunc)](
2251                         const DeleteValueInfo& deleteValue) {
2252         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, true);
2253         auto ret = func->ExecuteWithValue(deleteValue);
2254         if (ret->IsBoolean()) {
2255             return ret->ToBoolean();
2256         }
2257         return true;
2258     };
2259     TextFieldModel::GetInstance()->SetOnWillDeleteEvent(std::move(callback));
2260 }
2261 
OnDidDelete(const JSCallbackInfo & info)2262 void JSTextField::OnDidDelete(const JSCallbackInfo& info)
2263 {
2264     auto jsValue = info[0];
2265     CHECK_NULL_VOID(jsValue->IsFunction());
2266     auto jsAboutToIMEInputFunc =
2267         AceType::MakeRefPtr<JsEventFunction<DeleteValueInfo, 1>>(JSRef<JSFunc>::Cast(jsValue), CreateJsDeleteToIMEObj);
2268     auto callback = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToIMEInputFunc)](
2269                         const DeleteValueInfo& deleteValue) {
2270         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2271         func->ExecuteWithValue(deleteValue);
2272     };
2273     TextFieldModel::GetInstance()->SetOnDidDeleteEvent(std::move(callback));
2274 }
2275 
EditMenuOptions(const JSCallbackInfo & info)2276 void JSTextField::EditMenuOptions(const JSCallbackInfo& info)
2277 {
2278     NG::OnCreateMenuCallback onCreateMenuCallback;
2279     NG::OnMenuItemClickCallback onMenuItemClick;
2280     NG::OnPrepareMenuCallback onPrepareMenuCallback;
2281     JSViewAbstract::ParseEditMenuOptions(info, onCreateMenuCallback, onMenuItemClick, onPrepareMenuCallback);
2282     TextFieldModel::GetInstance()->SetSelectionMenuOptions(
2283         std::move(onCreateMenuCallback), std::move(onMenuItemClick), std::move(onPrepareMenuCallback));
2284 }
2285 
SetEnablePreviewText(const JSCallbackInfo & info)2286 void JSTextField::SetEnablePreviewText(const JSCallbackInfo& info)
2287 {
2288     auto jsValue = info[0];
2289     if (!jsValue->IsBoolean()) {
2290         TextFieldModel::GetInstance()->SetEnablePreviewText(true);
2291         return;
2292     }
2293     TextFieldModel::GetInstance()->SetEnablePreviewText(jsValue->ToBoolean());
2294 }
2295 
SetEnableHapticFeedback(const JSCallbackInfo & info)2296 void JSTextField::SetEnableHapticFeedback(const JSCallbackInfo& info)
2297 {
2298     bool state = true;
2299     if (info.Length() > 0 && info[0]->IsBoolean()) {
2300         state = info[0]->ToBoolean();
2301     }
2302     TextFieldModel::GetInstance()->SetEnableHapticFeedback(state);
2303 }
2304 
SetEllipsisMode(const JSCallbackInfo & info)2305 void JSTextField::SetEllipsisMode(const JSCallbackInfo& info)
2306 {
2307     JSRef<JSVal> args = info[0];
2308     if (!args->IsNumber()) {
2309         TextFieldModel::GetInstance()->SetEllipsisMode(EllipsisMode::TAIL);
2310         return;
2311     }
2312     uint32_t index = args->ToNumber<uint32_t>();
2313     if (index < ELLIPSIS_MODALS.size()) {
2314         TextFieldModel::GetInstance()->SetEllipsisMode(ELLIPSIS_MODALS[index]);
2315     }
2316 }
2317 
SetStopBackPress(const JSCallbackInfo & info)2318 void JSTextField::SetStopBackPress(const JSCallbackInfo& info)
2319 {
2320     bool isStopBackPress = true;
2321     if (info.Length() > 0 && info[0]->IsBoolean()) {
2322         isStopBackPress = info[0]->ToBoolean();
2323     }
2324     TextFieldModel::GetInstance()->SetStopBackPress(isStopBackPress);
2325 }
2326 
CreateJsOnWillChangeObj(const ChangeValueInfo & changeValueInfo)2327 JSRef<JSVal> JSTextField::CreateJsOnWillChangeObj(const ChangeValueInfo& changeValueInfo)
2328 {
2329     JSRef<JSObject> ChangeValueInfo = JSRef<JSObject>::New();
2330     ChangeValueInfo->SetProperty<std::u16string>("content", changeValueInfo.value);
2331 
2332     auto previewTextObj = CreateJsOnChangeObj(changeValueInfo.previewText);
2333     ChangeValueInfo->SetPropertyObject("previewText", previewTextObj);
2334 
2335     auto optionsObj = JSRef<JSObject>::New();
2336     auto rangeBeforeObj = JSRef<JSObject>::New();
2337     rangeBeforeObj->SetProperty<int32_t>("start", changeValueInfo.rangeBefore.start);
2338     rangeBeforeObj->SetProperty<int32_t>("end", changeValueInfo.rangeBefore.end);
2339     optionsObj->SetPropertyObject("rangeBefore", rangeBeforeObj);
2340     auto rangeAfterObj = JSRef<JSObject>::New();
2341     rangeAfterObj->SetProperty<int32_t>("start", changeValueInfo.rangeAfter.start);
2342     rangeAfterObj->SetProperty<int32_t>("end", changeValueInfo.rangeAfter.end);
2343     optionsObj->SetPropertyObject("rangeAfter", rangeAfterObj);
2344     optionsObj->SetProperty<std::u16string>("oldContent", changeValueInfo.oldContent);
2345     auto oldPreviewTextObj = CreateJsOnChangeObj(changeValueInfo.oldPreviewText);
2346     optionsObj->SetPropertyObject("oldPreviewText", oldPreviewTextObj);
2347 
2348     ChangeValueInfo->SetPropertyObject("options", optionsObj);
2349     return JSRef<JSVal>::Cast(ChangeValueInfo);
2350 }
2351 
SetOnWillChange(const JSCallbackInfo & info)2352 void JSTextField::SetOnWillChange(const JSCallbackInfo& info)
2353 {
2354     auto jsValue = info[0];
2355     CHECK_NULL_VOID(jsValue->IsFunction());
2356     auto jsChangeFunc = AceType::MakeRefPtr<JsEventFunction<ChangeValueInfo, 1>>(
2357         JSRef<JSFunc>::Cast(jsValue), CreateJsOnWillChangeObj);
2358     auto onWillChange = [execCtx = info.GetExecutionContext(), func = std::move(jsChangeFunc)](
2359         const ChangeValueInfo& changeValue) {
2360         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, true);
2361         ACE_SCORING_EVENT("onWillChange");
2362         auto ret = func->ExecuteWithValue(changeValue);
2363         if (ret->IsBoolean()) {
2364             return ret->ToBoolean();
2365         }
2366         return true;
2367     };
2368     TextFieldModel::GetInstance()->SetOnWillChangeEvent(std::move(onWillChange));
2369 }
2370 
SetEnableAutoSpacing(const JSCallbackInfo & info)2371 void JSTextField::SetEnableAutoSpacing(const JSCallbackInfo& info)
2372 {
2373     bool enabled = false;
2374     if (info.Length() > 0 && info[0]->IsBoolean()) {
2375         enabled = info[0]->ToBoolean();
2376     }
2377     TextFieldModel::GetInstance()->SetEnableAutoSpacing(enabled);
2378 }
2379 
SetStrokeWidth(const JSCallbackInfo & info)2380 void JSTextField::SetStrokeWidth(const JSCallbackInfo& info)
2381 {
2382     if (info.Length() < 1) {
2383         return;
2384     }
2385     CalcDimension value;
2386     if (!ParseLengthMetricsToDimension(info[0], value)) {
2387         value.Reset();
2388     }
2389     TextFieldModel::GetInstance()->SetStrokeWidth(value);
2390 }
2391 
SetStrokeColor(const JSCallbackInfo & info)2392 void JSTextField::SetStrokeColor(const JSCallbackInfo& info)
2393 {
2394     if (info.Length() < 1) {
2395         return;
2396     }
2397     Color strokeColor;
2398     if (!ParseJsColor(info[0], strokeColor)) {
2399         TextFieldModel::GetInstance()->ResetStrokeColor();
2400         return;
2401     }
2402     TextFieldModel::GetInstance()->SetStrokeColor(strokeColor);
2403 }
2404 
ParseKeyboardAppearanceConfig(const JSRef<JSObject> & obj)2405 NG::KeyboardAppearanceConfig JSTextField::ParseKeyboardAppearanceConfig(const JSRef<JSObject>& obj)
2406 {
2407     NG::KeyboardAppearanceConfig config;
2408     auto gradientModeJsVal = obj->GetProperty("gradientMode");
2409     if (gradientModeJsVal->IsNull() || gradientModeJsVal->IsUndefined() || !gradientModeJsVal->IsNumber()) {
2410         config.gradientMode = NG::KeyboardGradientMode::NONE;
2411     } else {
2412         int32_t value = gradientModeJsVal->ToNumber<int32_t>();
2413         if (value <= static_cast<int32_t>(NG::KeyboardGradientMode::BEGIN) ||
2414             value > static_cast<int32_t>(NG::KeyboardGradientMode::END)) {
2415             config.gradientMode = NG::KeyboardGradientMode::NONE;
2416         } else {
2417             config.gradientMode = static_cast<NG::KeyboardGradientMode>(value);
2418         }
2419     }
2420     auto fluidLightModeJsVal = obj->GetProperty("fluidLightMode");
2421     if (fluidLightModeJsVal->IsNull() || fluidLightModeJsVal->IsUndefined() || !fluidLightModeJsVal->IsNumber()) {
2422         config.fluidLightMode = NG::KeyboardFluidLightMode::NONE;
2423     } else {
2424         int32_t value = fluidLightModeJsVal->ToNumber<int32_t>();
2425         if (value <= static_cast<int32_t>(NG::KeyboardFluidLightMode::BEGIN) ||
2426             value > static_cast<int32_t>(NG::KeyboardFluidLightMode::END)) {
2427             config.fluidLightMode = NG::KeyboardFluidLightMode::NONE;
2428         } else {
2429             config.fluidLightMode = static_cast<NG::KeyboardFluidLightMode>(value);
2430         }
2431     }
2432     return config;
2433 }
2434 
SetOnWillAttachIME(const JSCallbackInfo & info)2435 void JSTextField::SetOnWillAttachIME(const JSCallbackInfo& info)
2436 {
2437     auto jsValue = info[0];
2438     CHECK_NULL_VOID(jsValue->IsFunction());
2439     auto jsOnWillAttachIMEFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(jsValue));
2440     auto onWillAttachIME = [execCtx = info.GetExecutionContext(), func = std::move(jsOnWillAttachIMEFunc)](
2441         const IMEClient& imeClientInfo) {
2442         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2443         ACE_SCORING_EVENT("onWillAttachIME");
2444         JSRef<JSObject> imeClientObj = JSRef<JSObject>::New();
2445         imeClientObj->SetProperty<int32_t>("nodeId", imeClientInfo.nodeId);
2446         JSRef<JSVal> argv[] = { imeClientObj };
2447         func->ExecuteJS(1, argv);
2448     };
2449     TextFieldModel::GetInstance()->SetOnWillAttachIME(std::move(onWillAttachIME));
2450 }
2451 
SetKeyboardAppearanceConfig(const JSCallbackInfo & info)2452 void JSTextField::SetKeyboardAppearanceConfig(const JSCallbackInfo& info)
2453 {
2454     EcmaVM* vm = info.GetVm();
2455     CHECK_NULL_VOID(vm);
2456     auto jsTargetNode = info[0];
2457     auto* targetNodePtr = jsTargetNode->GetLocalHandle()->ToNativePointer(vm)->Value();
2458     auto* frameNode = reinterpret_cast<NG::FrameNode*>(targetNodePtr);
2459     CHECK_NULL_VOID(frameNode);
2460     if (!info[1]->IsObject()) {
2461         return;
2462     }
2463     NG::KeyboardAppearanceConfig config = ParseKeyboardAppearanceConfig(JSRef<JSObject>::Cast(info[1]));
2464     NG::TextFieldModelNG::SetKeyboardAppearanceConfig(frameNode, config);
2465 }
2466 
SetLayoutPolicy(const JSRef<JSVal> & jsValue,bool isWidth)2467 void JSTextField::SetLayoutPolicy(const JSRef<JSVal>& jsValue, bool isWidth)
2468 {
2469     if (!jsValue->IsObject()) {
2470         ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(LayoutCalPolicy::NO_MATCH, isWidth);
2471         return;
2472     }
2473     JSRef<JSObject> object = JSRef<JSObject>::Cast(jsValue);
2474     JSRef<JSVal> layoutPolicy = object->GetProperty("id_");
2475     if (layoutPolicy->IsString()) {
2476         auto policy = ParseLayoutPolicy(layoutPolicy->ToString());
2477         ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(policy, isWidth);
2478     }
2479 }
2480 
UnregisterResource(const std::string & key)2481 void JSTextField::UnregisterResource(const std::string& key)
2482 {
2483     auto frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
2484     CHECK_NULL_VOID(frameNode);
2485     auto pattern = frameNode->GetPattern();
2486     CHECK_NULL_VOID(pattern);
2487     pattern->RemoveResObj(key);
2488 }
2489 } // namespace OHOS::Ace::Framework
2490