• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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/declaration/input/input_declaration.h"
17 
18 #include "base/utils/string_utils.h"
19 #include "core/components/declaration/common/declaration_constants.h"
20 #include "core/components/declaration/textfield/textfield_declaration.h"
21 #include "frameworks/bridge/common/utils/utils.h"
22 #include "frameworks/core/components/text_field/textfield_theme.h"
23 
24 namespace OHOS::Ace {
25 namespace {
26 
27 // input type
28 constexpr char INPUT_TYPE_BUTTON[] = "button";
29 constexpr char INPUT_TYPE_CHECKBOX[] = "checkbox";
30 constexpr char INPUT_TYPE_RADIO[] = "radio";
31 constexpr char INPUT_TYPE_TEXT[] = "text";
32 constexpr char INPUT_TYPE_EMAIL[] = "email";
33 constexpr char INPUT_TYPE_DATE[] = "date";
34 constexpr char INPUT_TYPE_TIME[] = "time";
35 constexpr char INPUT_TYPE_NUMBER[] = "number";
36 constexpr char INPUT_TYPE_PASSWORD[] = "password";
37 
38 std::set<std::string> g_textCategory;
39 
40 // If type is changed between g_textCategory, there is no need to recreate components.
ShouldCreateNewComponent(const std::string & oldType,const std::string & newType)41 bool ShouldCreateNewComponent(const std::string& oldType, const std::string& newType)
42 {
43     if (g_textCategory.empty()) {
44         g_textCategory = std::set<std::string>({ INPUT_TYPE_TEXT, INPUT_TYPE_EMAIL, INPUT_TYPE_DATE, INPUT_TYPE_TIME,
45             INPUT_TYPE_NUMBER, INPUT_TYPE_PASSWORD });
46     }
47     return g_textCategory.find(oldType) == g_textCategory.end() || g_textCategory.find(newType) == g_textCategory.end();
48 }
49 
50 } // namespace
51 
52 using namespace Framework;
53 
InitSpecialized()54 void InputDeclaration::InitSpecialized()
55 {
56     AddSpecializedAttribute(DeclarationConstants::DEFAULT_INPUT_ATTR);
57 }
58 
InitializeStyle()59 void InputDeclaration::InitializeStyle()
60 {
61     if (specializedDeclaration_) {
62         specializedDeclaration_->InitializeStyle();
63     }
64 }
65 
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)66 bool InputDeclaration::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
67 {
68     static const std::set<std::string> inputCategory { INPUT_TYPE_BUTTON, INPUT_TYPE_CHECKBOX, INPUT_TYPE_RADIO,
69         INPUT_TYPE_TEXT, INPUT_TYPE_EMAIL, INPUT_TYPE_DATE, INPUT_TYPE_TIME, INPUT_TYPE_NUMBER, INPUT_TYPE_PASSWORD };
70     if (attr.first == DOM_INPUT_TYPE) {
71         auto& specializedAttr = MaybeResetAttribute<InputAttribute>(AttributeTag::SPECIALIZED_ATTR);
72         if (specializedAttr.IsValid()) {
73             std::string typeName = attr.second;
74             if (typeName.empty() || inputCategory.find(typeName) == inputCategory.end()) {
75                 typeName = INPUT_TYPE_TEXT;
76             }
77             specializedAttr.type.second = ShouldCreateNewComponent(specializedAttr.type.first, typeName);
78             specializedAttr.type.first = typeName;
79         }
80         return true;
81     }
82     inputAttrs_[attr.first] = attr.second;
83     return false;
84 }
85 
SetSpecializedStyle(const std::pair<std::string,std::string> & style)86 bool InputDeclaration::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
87 {
88     inputStyles_[style.first] = style.second;
89     return false;
90 }
91 
SetSpecializedEvent(int32_t pageId,const std::string & eventId,const std::string & event)92 bool InputDeclaration::SetSpecializedEvent(int32_t pageId, const std::string& eventId, const std::string& event)
93 {
94     inputEvents_[event] = eventId;
95     pageId_ = pageId;
96     return false;
97 }
98 
CallSpecializedMethod(const std::string & method,const std::string & args)99 void InputDeclaration::CallSpecializedMethod(const std::string& method, const std::string& args)
100 {
101     if (g_textCategory.find(GetType()) != g_textCategory.end()) {
102         auto declaration = AceType::DynamicCast<TextFieldDeclaration>(specializedDeclaration_);
103         if (declaration) {
104             declaration->CallSpecializedMethod(method, args);
105         }
106     }
107 }
108 
OnRequestFocus(bool shouldFocus)109 void InputDeclaration::OnRequestFocus(bool shouldFocus)
110 {
111     if (g_textCategory.find(GetType()) != g_textCategory.end()) {
112         auto declaration = AceType::DynamicCast<TextFieldDeclaration>(specializedDeclaration_);
113         if (declaration) {
114             declaration->OnRequestFocus(shouldFocus);
115         }
116     }
117 }
118 
PrepareSpecializedDeclaration()119 void InputDeclaration::PrepareSpecializedDeclaration()
120 {
121     CreateSpecializedDeclaration();
122     auto declaration = AceType::DynamicCast<TextFieldDeclaration>(specializedDeclaration_);
123     if (declaration) {
124         for (const auto& attr : inputAttrs_) {
125             declaration->SetSpecializedAttr(attr);
126         }
127         for (const auto& style : inputStyles_) {
128             declaration->SetSpecializedStyle(style);
129         }
130         for (const auto& event : inputEvents_) {
131             declaration->SetSpecializedEvent(pageId_, event.second, event.first);
132         }
133     }
134 
135     PrepareTextField();
136 }
137 
CreateSpecializedDeclaration()138 void InputDeclaration::CreateSpecializedDeclaration()
139 {
140     std::pair<std::string, bool> type = { INPUT_TYPE_TEXT, true };
141     auto& specializedAttr = static_cast<InputAttribute&>(GetAttribute(AttributeTag::SPECIALIZED_ATTR));
142     if (specializedAttr.IsValid()) {
143         type = specializedAttr.type;
144         if (!type.second) {
145             LOGD("type of input is not changed.");
146             return;
147         }
148         specializedAttr.type.second = true;
149     }
150 
151     if (specializedAttr.type.first == INPUT_TYPE_BUTTON) {
152     } else if (specializedAttr.type.first == INPUT_TYPE_CHECKBOX) {
153     } else if (specializedAttr.type.first == INPUT_TYPE_RADIO) {
154     } else {
155         specializedDeclaration_ = AceType::MakeRefPtr<TextFieldDeclaration>();
156     }
157     if (specializedDeclaration_) {
158         specializedDeclaration_->BindPipelineContext(pipelineContext_);
159         specializedDeclaration_->Init();
160         specializedDeclaration_->InitializeStyle();
161     }
162 }
163 
PrepareTextField()164 void InputDeclaration::PrepareTextField()
165 {
166     auto textFieldDeclaration = AceType::DynamicCast<TextFieldDeclaration>(specializedDeclaration_);
167     if (!textFieldDeclaration) {
168         return;
169     }
170 
171     // Init disable style.
172     if (!textFieldDeclaration->IsEnabled()) {
173         auto theme = GetTheme<TextFieldTheme>();
174         textFieldDeclaration->SetTextColor(theme->GetDisableTextColor());
175         textFieldDeclaration->SetPlaceholderColor(theme->GetDisableTextColor());
176     }
177 
178     // Set height with height of box.
179     auto& sizeStyle = static_cast<CommonSizeStyle&>(GetStyle(StyleTag::COMMON_SIZE_STYLE));
180     if (sizeStyle.IsValid() && GreatOrEqual(sizeStyle.height.Value(), 0.0)) {
181         textFieldDeclaration->SetHeight(sizeStyle.height);
182     }
183 }
184 
185 } // namespace OHOS::Ace
186