1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components_ng/pattern/text_field/text_field_manager.h"
17 
18 #include "base/geometry/dimension.h"
19 #include "base/memory/ace_type.h"
20 #include "base/utils/utils.h"
21 #include "core/common/ime/text_input_type.h"
22 #include "core/components_ng/event/focus_hub.h"
23 #include "core/components_ng/pattern/navigation/navigation_pattern.h"
24 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h"
25 #include "core/components_ng/pattern/text/text_base.h"
26 #include "core/components_ng/pattern/text_field/text_field_pattern.h"
27 
28 namespace OHOS::Ace::NG {
29 namespace {
30 constexpr Dimension RESERVE_BOTTOM_HEIGHT = 24.0_vp;
31 } // namespace
32 
ClearOnFocusTextField()33 void TextFieldManagerNG::ClearOnFocusTextField()
34 {
35     onFocusTextField_ = nullptr;
36 }
37 
ClearOnFocusTextField(int32_t id)38 void TextFieldManagerNG::ClearOnFocusTextField(int32_t id)
39 {
40     if (onFocusTextFieldId == id) {
41         onFocusTextField_ = nullptr;
42         focusFieldIsInline = false;
43         optionalPosition_ = std::nullopt;
44         usingCustomKeyboardAvoid_ = false;
45         isScrollableChild_ = false;
46     }
47 }
48 
OnBackPressed()49 bool TextFieldManagerNG::OnBackPressed()
50 {
51     auto pattern = onFocusTextField_.Upgrade();
52     CHECK_NULL_RETURN(pattern, false);
53     auto textBasePattern = AceType::DynamicCast<TextBase>(pattern);
54     CHECK_NULL_RETURN(textBasePattern, false);
55     return textBasePattern->OnBackPressed();
56 }
57 
SetClickPosition(const Offset & position)58 void TextFieldManagerNG::SetClickPosition(const Offset& position)
59 {
60     auto pipeline = PipelineContext::GetCurrentContextSafely();
61     CHECK_NULL_VOID(pipeline);
62     auto rootHeight = pipeline->GetRootHeight();
63     if (GreatOrEqual(position.GetY(), rootHeight)) {
64         auto pattern = onFocusTextField_.Upgrade();
65         CHECK_NULL_VOID(pattern);
66         auto host = pattern->GetHost();
67         CHECK_NULL_VOID(host);
68         auto parent = host->GetAncestorNodeOfFrame();
69         while (parent) {
70             if (parent->GetTag() == "Panel" || parent->GetTag() == "SheetPage") {
71                 return;
72             }
73             parent = parent->GetAncestorNodeOfFrame();
74         }
75     }
76     if (LessOrEqual(position.GetY(), 0.0f)) {
77         return;
78     }
79     auto rootWidth = pipeline->GetRootWidth();
80     if (GreatOrEqual(position.GetX(), rootWidth) || LessNotEqual(position.GetX(), 0.0f)) {
81         return;
82     }
83     position_ = position;
84     optionalPosition_ = position;
85 }
86 
FindScrollableOfFocusedTextField(const RefPtr<FrameNode> & textField)87 RefPtr<FrameNode> TextFieldManagerNG::FindScrollableOfFocusedTextField(const RefPtr<FrameNode>& textField)
88 {
89     CHECK_NULL_RETURN(textField, {});
90     auto parent = textField->GetAncestorNodeOfFrame();
91     while (parent) {
92         auto pattern = parent->GetPattern<ScrollablePattern>();
93         if (pattern) {
94             return parent;
95         }
96         parent = parent->GetAncestorNodeOfFrame();
97     }
98     return {};
99 }
100 
GetFocusedNodeCaretRect()101 RectF TextFieldManagerNG::GetFocusedNodeCaretRect()
102 {
103     auto node = onFocusTextField_.Upgrade();
104     CHECK_NULL_RETURN(node, RectF());
105     auto frameNode = node->GetHost();
106     CHECK_NULL_RETURN(frameNode, RectF());
107     auto textBase = DynamicCast<TextBase>(node);
108     CHECK_NULL_RETURN(textBase, RectF());
109     auto caretRect = textBase->GetCaretRect() + frameNode->GetTransformRectRelativeToWindow();
110     return caretRect;
111 }
112 
TriggerCustomKeyboardAvoid()113 void TextFieldManagerNG::TriggerCustomKeyboardAvoid()
114 {
115     CHECK_NULL_VOID(UsingCustomKeyboardAvoid());
116     auto pattern = onFocusTextField_.Upgrade();
117     CHECK_NULL_VOID(pattern);
118     auto curPattern = DynamicCast<TextFieldPattern>(pattern);
119     CHECK_NULL_VOID(curPattern);
120     if (!curPattern->GetIsCustomKeyboardAttached()) {
121         return;
122     }
123     auto caretHeight = curPattern->GetCaretRect().Height();
124     auto safeHeight = caretHeight + curPattern->GetCaretRect().GetY();
125     if (curPattern->GetCaretRect().GetY() > caretHeight) {
126         safeHeight = caretHeight;
127     }
128     auto keyboardOverLay = curPattern->GetKeyboardOverLay();
129     CHECK_NULL_VOID(keyboardOverLay);
130     auto host = curPattern->GetHost();
131     CHECK_NULL_VOID(host);
132     auto nodeId = host->GetId();
133     keyboardOverLay->AvoidCustomKeyboard(nodeId, safeHeight);
134 }
135 
TriggerAvoidOnCaretChange()136 void TextFieldManagerNG::TriggerAvoidOnCaretChange()
137 {
138     auto pattern = onFocusTextField_.Upgrade();
139     CHECK_NULL_VOID(pattern);
140     auto host = pattern->GetHost();
141     CHECK_NULL_VOID(host);
142     auto pipeline = host->GetContext();
143     CHECK_NULL_VOID(pipeline);
144     auto safeAreaManager = pipeline->GetSafeAreaManager();
145     CHECK_NULL_VOID(safeAreaManager);
146     if (!pipeline->UsingCaretAvoidMode() || NearEqual(safeAreaManager->GetKeyboardInset().Length(), 0)) {
147         return;
148     }
149     if (UsingCustomKeyboardAvoid()) {
150         ScrollTextFieldToSafeArea();
151         TriggerCustomKeyboardAvoid();
152     } else {
153         ScrollTextFieldToSafeArea();
154         auto keyboardInset = safeAreaManager->GetKeyboardInset();
155         lastKeyboardOffset_ = safeAreaManager->GetKeyboardOffsetDirectly();
156         Rect keyboardRect;
157         keyboardRect.SetRect(0, 0, 0, keyboardInset.Length());
158         pipeline->OnVirtualKeyboardAreaChange(keyboardRect,
159             GetFocusedNodeCaretRect().Top(), GetHeight());
160     }
161     auto currentKeyboardOffset = safeAreaManager->GetKeyboardOffsetDirectly();
162     if (currentKeyboardOffset != lastKeyboardOffset_) {
163         AvoidKeyboardInSheet(host);
164     }
165 }
166 
GetOnFocusTextFieldInfo(const WeakPtr<Pattern> & onFocusTextField)167 void TextFieldManagerNG::GetOnFocusTextFieldInfo(const WeakPtr<Pattern>& onFocusTextField)
168 {
169     auto node = onFocusTextField.Upgrade();
170     CHECK_NULL_VOID(node);
171     auto frameNode = node->GetHost();
172     CHECK_NULL_VOID(frameNode);
173     auto scrollableNode = FindScrollableOfFocusedTextField(frameNode);
174     CHECK_NULL_VOID(scrollableNode);
175     auto scrollPattern = scrollableNode->GetPattern<ScrollablePattern>();
176     CHECK_NULL_VOID(scrollPattern);
177     isScrollableChild_ = scrollPattern->IsScrollToSafeAreaHelper();
178     TAG_LOGI(ACE_KEYBOARD, "isScrollableChild_: %{public}d", isScrollableChild_);
179 }
180 
ScrollToSafeAreaHelper(const SafeAreaInsets::Inset & bottomInset,bool isShowKeyboard)181 bool TextFieldManagerNG::ScrollToSafeAreaHelper(
182     const SafeAreaInsets::Inset& bottomInset, bool isShowKeyboard)
183 {
184     auto node = onFocusTextField_.Upgrade();
185     CHECK_NULL_RETURN(node, false);
186     auto frameNode = node->GetHost();
187     CHECK_NULL_RETURN(frameNode, false);
188     auto textBase = DynamicCast<TextBase>(node);
189     CHECK_NULL_RETURN(textBase, false);
190     textBase->OnVirtualKeyboardAreaChanged();
191 
192     auto scrollableNode = FindScrollableOfFocusedTextField(frameNode);
193     CHECK_NULL_RETURN(scrollableNode, false);
194     auto scrollPattern = scrollableNode->GetPattern<ScrollablePattern>();
195     CHECK_NULL_RETURN(scrollPattern && scrollPattern->IsScrollToSafeAreaHelper(), false);
196     CHECK_NULL_RETURN(scrollPattern->GetAxis() != Axis::HORIZONTAL, false);
197 
198     auto scrollableRect = scrollableNode->GetTransformRectRelativeToWindow();
199     if (isShowKeyboard) {
200         CHECK_NULL_RETURN(scrollableRect.Top() < bottomInset.start, false);
201     }
202 
203     auto pipeline = frameNode->GetContext();
204     CHECK_NULL_RETURN(pipeline, false);
205     auto safeAreaManager = pipeline->GetSafeAreaManager();
206     CHECK_NULL_RETURN(safeAreaManager, false);
207     if (pipeline->UsingCaretAvoidMode()) {
208         scrollableRect.SetTop(scrollableRect.Top() - safeAreaManager->GetKeyboardOffset());
209     }
210 
211     auto caretRect = textBase->GetCaretRect() + frameNode->GetPositionToWindowWithTransform();
212     auto diffTop = caretRect.Top() - scrollableRect.Top();
213     // caret height larger scroll's content region
214     if (isShowKeyboard && diffTop <= 0 && LessNotEqual(bottomInset.start,
215         (caretRect.Bottom() + RESERVE_BOTTOM_HEIGHT.ConvertToPx()))) {
216         return false;
217     }
218 
219     // caret above scroll's content region
220     if (diffTop < 0) {
221         TAG_LOGI(ACE_KEYBOARD, "scrollRect:%{public}s caretRect:%{public}s totalOffset()=%{public}f diffTop=%{public}f",
222             scrollableRect.ToString().c_str(), caretRect.ToString().c_str(), scrollPattern->GetTotalOffset(), diffTop);
223         scrollPattern->ScrollTo(scrollPattern->GetTotalOffset() + diffTop);
224         return true;
225     }
226 
227     // caret inner scroll's content region
228     if (isShowKeyboard && LessNotEqual((caretRect.Bottom() + RESERVE_BOTTOM_HEIGHT.ConvertToPx()), bottomInset.start)) {
229         return false;
230     }
231 
232     // caret below safeArea
233     float diffBot = 0.0f;
234 
235     auto scrollBottom = isShowKeyboard && GreatOrEqual(scrollableRect.Bottom(), bottomInset.start) ?
236         bottomInset.start : scrollableRect.Bottom();
237     diffBot = scrollBottom - caretRect.Bottom() - RESERVE_BOTTOM_HEIGHT.ConvertToPx();
238     CHECK_NULL_RETURN(diffBot < 0, false);
239     TAG_LOGI(ACE_KEYBOARD, "scrollRect:%{public}s caretRect:%{public}s totalOffset()=%{public}f diffBot=%{public}f",
240         scrollableRect.ToString().c_str(), caretRect.ToString().c_str(), scrollPattern->GetTotalOffset(), diffBot);
241     scrollPattern->ScrollTo(scrollPattern->GetTotalOffset() - diffBot);
242     return true;
243 }
244 
ScrollTextFieldToSafeArea()245 bool TextFieldManagerNG::ScrollTextFieldToSafeArea()
246 {
247     auto pipeline = PipelineContext::GetCurrentContext();
248     CHECK_NULL_RETURN(pipeline, false);
249     auto keyboardInset = pipeline->GetSafeAreaManager()->GetKeyboardInset();
250     bool isShowKeyboard = keyboardInset.IsValid();
251     if (isShowKeyboard) {
252         auto bottomInset = pipeline->GetSafeArea().bottom_.Combine(keyboardInset);
253         CHECK_NULL_RETURN(bottomInset.IsValid(), false);
254         return ScrollToSafeAreaHelper(bottomInset, isShowKeyboard);
255     } else if (pipeline->GetSafeAreaManager()->KeyboardSafeAreaEnabled()) {
256         // hide keyboard only scroll when keyboard avoid mode is resize
257         return ScrollToSafeAreaHelper({0, 0}, isShowKeyboard);
258     }
259     return false;
260 }
261 
SetHeight(float height)262 void TextFieldManagerNG::SetHeight(float height)
263 {
264     height_ = height + RESERVE_BOTTOM_HEIGHT.ConvertToPx();
265 }
266 
UpdateScrollableParentViewPort(const RefPtr<FrameNode> & node)267 void TextFieldManagerNG::UpdateScrollableParentViewPort(const RefPtr<FrameNode>& node)
268 {
269     CHECK_NULL_VOID(node);
270     auto scrollableNode = FindScrollableOfFocusedTextField(node);
271     CHECK_NULL_VOID(scrollableNode);
272     auto scrollPattern = scrollableNode->GetPattern<ScrollablePattern>();
273     CHECK_NULL_VOID(scrollPattern);
274     if (scrollPattern->GetAxis() == Axis::HORIZONTAL) {
275         return;
276     }
277     auto scrollableRect = scrollableNode->GetTransformRectRelativeToWindow();
278     scrollableNode->SetViewPort(scrollableRect);
279 }
280 
AvoidKeyBoardInNavigation()281 void TextFieldManagerNG::AvoidKeyBoardInNavigation()
282 {
283     auto node = onFocusTextField_.Upgrade();
284     auto pipeline = PipelineContext::GetCurrentContext();
285     CHECK_NULL_VOID(pipeline);
286     auto manager = pipeline->GetSafeAreaManager();
287     auto avoidKeyboardOffset =  manager ? manager->GetKeyboardOffset() : 0.0f;
288     if (!node) {
289         auto navNode = weakNavNode_.Upgrade();
290         CHECK_NULL_VOID(navNode);
291         SetNavContentAvoidKeyboardOffset(navNode, avoidKeyboardOffset);
292         return;
293     }
294     auto frameNode = node->GetHost();
295     CHECK_NULL_VOID(frameNode);
296     auto preNavNode = weakNavNode_.Upgrade();
297     if (preNavNode) {
298         SetNavContentAvoidKeyboardOffset(preNavNode, 0.0f);
299     }
300     auto navNode = FindNavNode(frameNode);
301     CHECK_NULL_VOID(navNode);
302     weakNavNode_ = navNode;
303     SetNavContentAvoidKeyboardOffset(navNode, avoidKeyboardOffset);
304 }
305 
AvoidKeyboardInSheet(const RefPtr<FrameNode> & textField)306 void TextFieldManagerNG::AvoidKeyboardInSheet(const RefPtr<FrameNode>& textField)
307 {
308     CHECK_NULL_VOID(textField);
309     auto parent = textField->GetAncestorNodeOfFrame();
310     bool findSheet = false;
311     while (parent) {
312         if (parent->GetHostTag() == V2::SHEET_PAGE_TAG) {
313             findSheet = true;
314             break;
315         }
316         parent = parent->GetAncestorNodeOfFrame();
317     }
318     CHECK_NULL_VOID(parent);
319     auto sheetNodePattern = parent->GetPattern<SheetPresentationPattern>();
320     CHECK_NULL_VOID(sheetNodePattern);
321     TAG_LOGI(ACE_KEYBOARD, "Force AvoidKeyboard in sheet");
322     sheetNodePattern->AvoidSafeArea(true);
323 }
324 
FindNavNode(const RefPtr<FrameNode> & textField)325 RefPtr<FrameNode> TextFieldManagerNG::FindNavNode(const RefPtr<FrameNode>& textField)
326 {
327     CHECK_NULL_RETURN(textField, nullptr);
328     auto parent = textField->GetAncestorNodeOfFrame();
329     RefPtr<FrameNode> ret = nullptr;
330     while (parent) {
331         // when the sheet showed in navdestination, sheet replaced navdestination to do avoid keyboard.
332         if (parent->GetHostTag() == V2::SHEET_WRAPPER_TAG) {
333             auto sheetNode = parent->GetChildAtIndex(0);
334             CHECK_NULL_RETURN(sheetNode, nullptr);
335             return AceType::DynamicCast<FrameNode>(sheetNode);
336         }
337         if (parent->GetHostTag() == V2::NAVDESTINATION_VIEW_ETS_TAG ||
338             parent->GetHostTag() == V2::NAVBAR_ETS_TAG) {
339                 ret = parent;
340                 break;
341             }
342         parent = parent->GetAncestorNodeOfFrame();
343     }
344     CHECK_NULL_RETURN(ret, nullptr);
345 
346     // return navdestination or navBar if the closest ancestor navigation can expandKeyboard
347     // if can't, recursively find the ancestor navigation can expandKeyboard.
348     auto navigationNode = ret->GetAncestorNodeOfFrame();
349     while (navigationNode) {
350         if (navigationNode->GetHostTag() == V2::NAVIGATION_VIEW_ETS_TAG) {
351             break;
352         }
353         navigationNode = navigationNode->GetAncestorNodeOfFrame();
354     }
355     CHECK_NULL_RETURN(navigationNode, nullptr);
356     auto layoutProperty = navigationNode->GetLayoutProperty<NavigationLayoutProperty>();
357     CHECK_NULL_RETURN(layoutProperty, nullptr);
358     auto& opts = layoutProperty->GetSafeAreaExpandOpts();
359 
360     // if the extended keyboard area is set for the navigation, top navdestination or navbar need to avoid keyboard,
361     // otherwise don't aovid, following parent navigation.
362     bool isExpandKeyboard = opts && (opts->type & SAFE_AREA_TYPE_KEYBOARD) && (opts->edges & SAFE_AREA_EDGE_BOTTOM);
363     if (isExpandKeyboard) {
364         return ret;
365     }
366     auto mayAvoidNavContentNode = FindNavNode(navigationNode);
367     if (mayAvoidNavContentNode) {
368         return mayAvoidNavContentNode;
369     }
370     SetNavContentAvoidKeyboardOffset(ret, 0.0f);
371     return nullptr;
372 }
373 
SetNavContentAvoidKeyboardOffset(RefPtr<FrameNode> navNode,float avoidKeyboardOffset)374 void TextFieldManagerNG::SetNavContentAvoidKeyboardOffset(RefPtr<FrameNode> navNode, float avoidKeyboardOffset)
375 {
376     auto navDestinationNode = AceType::DynamicCast<NavDestinationGroupNode>(navNode);
377     if (navDestinationNode) {
378         TAG_LOGI(ACE_KEYBOARD, "navNode id:%{public}d, avoidKeyboardOffset:%{public}f", navNode->GetId(),
379             avoidKeyboardOffset);
380         auto pattern = navDestinationNode->GetPattern<NavDestinationPattern>();
381         if (pattern) {
382             avoidKeyboardOffset = pattern->NeedIgnoreKeyboard() ? 0.0f : avoidKeyboardOffset;
383             pattern->SetAvoidKeyboardOffset(avoidKeyboardOffset);
384         }
385     }
386     auto navBarNode = AceType::DynamicCast<NavBarNode>(navNode);
387     if (navBarNode) {
388         auto pattern = navBarNode->GetPattern<NavBarPattern>();
389         if (pattern) {
390             pattern->SetAvoidKeyboardOffset(avoidKeyboardOffset);
391         }
392     }
393     navNode->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
394 }
395 
AddTextFieldInfo(const TextFieldInfo & textFieldInfo)396 void TextFieldManagerNG::AddTextFieldInfo(const TextFieldInfo& textFieldInfo)
397 {
398     if (textFieldInfo.nodeId == -1 || textFieldInfo.autoFillContainerNodeId == -1) {
399         return;
400     }
401 
402     auto containerNodeIter = textFieldInfoMap_.find(textFieldInfo.autoFillContainerNodeId);
403     if (containerNodeIter != textFieldInfoMap_.end()) {
404         auto& innerTextFieldMap = containerNodeIter->second;
405         innerTextFieldMap[textFieldInfo.nodeId] = textFieldInfo;
406     } else {
407         std::unordered_map<int32_t, TextFieldInfo> innerTextFieldInfoMap;
408         innerTextFieldInfoMap[textFieldInfo.nodeId] = textFieldInfo;
409         textFieldInfoMap_[textFieldInfo.autoFillContainerNodeId] = innerTextFieldInfoMap;
410     }
411 }
412 
RemoveTextFieldInfo(const int32_t & autoFillContainerNodeId,const int32_t & nodeId)413 void TextFieldManagerNG::RemoveTextFieldInfo(const int32_t& autoFillContainerNodeId, const int32_t& nodeId)
414 {
415     auto containerNodeIter = textFieldInfoMap_.find(autoFillContainerNodeId);
416     if (containerNodeIter != textFieldInfoMap_.end()) {
417         auto& innerTextFieldInfoMap = containerNodeIter->second;
418         auto textFieldNodeIter = innerTextFieldInfoMap.find(nodeId);
419         if (textFieldNodeIter != innerTextFieldInfoMap.end()) {
420             innerTextFieldInfoMap.erase(textFieldNodeIter);
421         }
422     }
423 }
424 
UpdateTextFieldInfo(const TextFieldInfo & textFieldInfo)425 void TextFieldManagerNG::UpdateTextFieldInfo(const TextFieldInfo& textFieldInfo)
426 {
427     if (textFieldInfo.nodeId == -1 || textFieldInfo.autoFillContainerNodeId == -1) {
428         return;
429     }
430     auto containerNodeIter = textFieldInfoMap_.find(textFieldInfo.autoFillContainerNodeId);
431     if (containerNodeIter != textFieldInfoMap_.end()) {
432         auto& innerTextFieldInfoMap = containerNodeIter->second;
433         auto textFieldNodeIter = innerTextFieldInfoMap.find(textFieldInfo.nodeId);
434         if (textFieldNodeIter != innerTextFieldInfoMap.end()) {
435             innerTextFieldInfoMap.erase(textFieldNodeIter);
436         }
437         innerTextFieldInfoMap[textFieldInfo.nodeId] = textFieldInfo;
438     } else {
439         AddTextFieldInfo(textFieldInfo);
440     }
441 }
442 
HasAutoFillPasswordNodeInContainer(const int32_t & autoFillContainerNodeId,const int32_t & nodeId)443 bool TextFieldManagerNG::HasAutoFillPasswordNodeInContainer(
444     const int32_t& autoFillContainerNodeId, const int32_t& nodeId)
445 {
446     auto containerNodeIter = textFieldInfoMap_.find(autoFillContainerNodeId);
447     if (containerNodeIter == textFieldInfoMap_.end()) {
448         return false;
449     }
450 
451     auto& innerTextFieldInfoMap = containerNodeIter->second;
452     auto textFieldNodeIter = innerTextFieldInfoMap.find(nodeId);
453     if (textFieldNodeIter == innerTextFieldInfoMap.end()) {
454         return false;
455     }
456 
457     for (const auto& textField : innerTextFieldInfoMap) {
458         auto textFieldId = textField.first;
459         auto textFieldInfo = textField.second;
460         if (textFieldId == nodeId) {
461             continue;
462         }
463 
464         auto isPasswordType = IsAutoFillPasswordType(textFieldInfo);
465         if (isPasswordType && textFieldInfo.enableAutoFill) {
466             return true;
467         }
468     }
469 
470     return false;
471 }
472 
IsAutoFillPasswordType(const TextFieldInfo & textFieldInfo)473 bool TextFieldManagerNG::IsAutoFillPasswordType(const TextFieldInfo& textFieldInfo)
474 {
475     return textFieldInfo.inputType == TextInputType::VISIBLE_PASSWORD ||
476            textFieldInfo.inputType == TextInputType::NEW_PASSWORD ||
477            textFieldInfo.inputType == TextInputType::NUMBER_PASSWORD ||
478            textFieldInfo.contentType == TextContentType::VISIBLE_PASSWORD ||
479            textFieldInfo.contentType == TextContentType::NEW_PASSWORD;
480 }
481 
~TextFieldManagerNG()482 TextFieldManagerNG::~TextFieldManagerNG()
483 {
484     textFieldInfoMap_.clear();
485 }
486 } // namespace OHOS::Ace::NG
487