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