• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "bridge/declarative_frontend/jsview/js_badge.h"
17 
18 #include "base/geometry/dimension.h"
19 #include "base/log/ace_trace.h"
20 #include "base/utils/utils.h"
21 #include "bridge/declarative_frontend/ark_theme/theme_apply/js_theme.h"
22 #include "bridge/declarative_frontend/ark_theme/theme_apply/js_theme_utils.h"
23 #include "core/components/common/layout/grid_container_info.h"
24 #include "core/components_ng/pattern/badge/badge_model_ng.h"
25 #include "frameworks/bridge/declarative_frontend/jsview/models/badge_model_impl.h"
26 
27 namespace OHOS::Ace {
28 std::unique_ptr<BadgeModel> BadgeModel::instance_ = nullptr;
29 std::mutex BadgeModel::mutex_;
30 
GetInstance()31 BadgeModel* BadgeModel::GetInstance()
32 {
33     if (!instance_) {
34         std::lock_guard<std::mutex> lock(mutex_);
35         if (!instance_) {
36 #ifdef NG_BUILD
37             instance_.reset(new NG::BadgeModelNG());
38 #else
39             if (Container::IsCurrentUseNewPipeline()) {
40                 instance_.reset(new NG::BadgeModelNG());
41             } else {
42                 instance_.reset(new Framework::BadgeModelImpl());
43             }
44 #endif
45         }
46     }
47     return instance_.get();
48 }
49 } // namespace OHOS::Ace
50 
51 namespace OHOS::Ace::Framework {
Create(const JSCallbackInfo & info)52 void JSBadge::Create(const JSCallbackInfo& info)
53 {
54     if (!info[0]->IsObject()) {
55         return;
56     }
57 
58     auto frameNode = BadgeModel::GetInstance()->CreateBadgeFrameNode();
59     BadgeParameters badgeParameters = CreateBadgeParameters(info);
60     BadgeModel::GetInstance()->CreateByFrameNode(frameNode, badgeParameters);
61 }
62 
CreateBadgeParameters(const JSCallbackInfo & info)63 BadgeParameters JSBadge::CreateBadgeParameters(const JSCallbackInfo& info)
64 {
65     BadgeParameters badgeParameters;
66     if (!info[0]->IsObject()) {
67         return badgeParameters;
68     }
69 
70     auto themeColors = JSThemeUtils::GetThemeColors();
71 
72     auto badgeTheme = GetTheme<BadgeTheme>();
73     CHECK_NULL_RETURN(badgeTheme, BadgeParameters());
74     auto obj = JSRef<JSObject>::Cast(info[0]);
75     auto value = obj->GetProperty("value");
76     if (!value->IsNull() && value->IsString()) {
77         auto label = value->ToString();
78         badgeParameters.badgeValue = label;
79     } else if (!value->IsNull() && value->IsObject()) {
80         std::string valueResult;
81         if (SystemProperties::ConfigChangePerform()) {
82             RefPtr<ResourceObject> resObj;
83             ParseJsString(value, valueResult, resObj);
84             badgeParameters.resourceBadgeValueObject = resObj;
85             badgeParameters.badgeValue = valueResult;
86         } else {
87             ParseJsString(value, valueResult);
88             badgeParameters.badgeValue = valueResult;
89         }
90     }
91 
92     auto position = obj->GetProperty("position");
93     if (!position->IsNull() && position->IsNumber()) {
94         badgeParameters.isPositionXy = false;
95         badgeParameters.badgePosition = position->ToNumber<int32_t>();
96     } else if (!position->IsNull() && position->IsObject()) {
97         badgeParameters.isPositionXy = true;
98         auto postionValue = JSRef<JSObject>::Cast(position);
99         JSRef<JSVal> xVal = postionValue->GetProperty("x");
100         JSRef<JSVal> yVal = postionValue->GetProperty("y");
101         CalcDimension dimenX;
102         CalcDimension dimenY;
103         RefPtr<ResourceObject> resObjX;
104         RefPtr<ResourceObject> resObjY;
105         if (SystemProperties::ConfigChangePerform()) {
106             bool xState = ParseJsDimensionVp(xVal, dimenX, resObjX);
107             bool yState = ParseJsDimensionVp(yVal, dimenY, resObjY);
108             badgeParameters.resourceBadgePositionXObject = resObjX;
109             badgeParameters.resourceBadgePositionYObject = resObjY;
110             badgeParameters.badgePositionXByUser = true;
111             badgeParameters.badgePositionYByUser = true;
112             bool hasX = resObjX || xState;
113             bool hasY = resObjY || yState;
114             if (!(hasX || hasY)) {
115                 badgeParameters.badgePositionX = badgeTheme->GetBadgePositionX();
116                 badgeParameters.badgePositionY = badgeTheme->GetBadgePositionY();
117                 badgeParameters.resourceBadgePositionXObject = nullptr;
118                 badgeParameters.resourceBadgePositionYObject = nullptr;
119                 badgeParameters.badgePositionXByUser = false;
120                 badgeParameters.badgePositionYByUser = false;
121             } else {
122                 badgeParameters.badgePositionX = dimenX;
123                 badgeParameters.badgePositionY = dimenY;
124             }
125         } else {
126             bool xResult = ParseJsDimensionVp(xVal, dimenX);
127             bool yResult = ParseJsDimensionVp(yVal, dimenY);
128             if (!(xResult || yResult)) {
129                 badgeParameters.badgePositionX = badgeTheme->GetBadgePositionX();
130                 badgeParameters.badgePositionY = badgeTheme->GetBadgePositionY();
131             } else {
132                 badgeParameters.badgePositionX = dimenX;
133                 badgeParameters.badgePositionY = dimenY;
134             }
135         }
136     }
137 
138     auto style = obj->GetProperty("style");
139     if (!style->IsNull() && style->IsObject()) {
140         auto value = JSRef<JSObject>::Cast(style);
141         JSRef<JSVal> colorValue = value->GetProperty("color");
142         JSRef<JSVal> fontSizeValue = value->GetProperty("fontSize");
143         JSRef<JSVal> badgeSizeValue = value->GetProperty("badgeSize");
144         JSRef<JSVal> badgeColorValue = value->GetProperty("badgeColor");
145         JSRef<JSVal> borderColorValue = value->GetProperty("borderColor");
146         JSRef<JSVal> borderWidthValue = value->GetProperty("borderWidth");
147         JSRef<JSVal> fontWeightValue = value->GetProperty("fontWeight");
148 
149         bool isDefaultFontSize = true;
150         bool isDefaultBadgeSize = true;
151 
152         Color colorVal;
153         if (SystemProperties::ConfigChangePerform()) {
154             RefPtr<ResourceObject> resObj;
155             badgeParameters.badgeTextColorByUser = true;
156             bool state = ParseJsColor(colorValue, colorVal, resObj);
157             badgeParameters.resourceColorObject = resObj;
158             if (state) {
159                 badgeParameters.badgeTextColor = colorVal;
160             } else if (themeColors) {
161                 badgeParameters.badgeTextColor = themeColors->FontOnPrimary();
162                 badgeParameters.badgeTextColorByUser = false;
163             } else {
164                 badgeParameters.badgeTextColorByUser = false;
165             }
166         } else {
167             if (ParseJsColor(colorValue, colorVal)) {
168                 badgeParameters.badgeTextColor = colorVal;
169             } else if (themeColors) {
170                 badgeParameters.badgeTextColor = themeColors->FontOnPrimary();
171             }
172         }
173 
174         CalcDimension fontSize;
175         if (SystemProperties::ConfigChangePerform()) {
176             RefPtr<ResourceObject> resObj;
177             badgeParameters.badgeFontSizeByUser = true;
178             bool state = ParseJsDimensionNG(fontSizeValue, fontSize, DimensionUnit::FP, resObj);
179             badgeParameters.resourceFontSizeObject = resObj;
180             if (state && fontSize.IsNonNegative() && fontSize.Unit() != DimensionUnit::PERCENT) {
181                 badgeParameters.badgeFontSize = fontSize;
182                 isDefaultFontSize = false;
183             } else {
184                 badgeParameters.badgeFontSizeByUser = false;
185                 badgeParameters.badgeFontSize =
186                     !fontSizeValue->IsUndefined() ? badgeTheme->GetBadgeFontSize() : UNDEFINED_DIMENSION;
187             }
188         } else {
189             if (ParseJsDimensionNG(fontSizeValue, fontSize, DimensionUnit::FP) && fontSize.IsNonNegative() &&
190                 fontSize.Unit() != DimensionUnit::PERCENT) {
191                 badgeParameters.badgeFontSize = fontSize;
192                 isDefaultFontSize = false;
193             } else if (!fontSizeValue->IsUndefined()) {
194                 badgeParameters.badgeFontSize = badgeTheme->GetBadgeFontSize();
195             } else {
196                 badgeParameters.badgeFontSize = UNDEFINED_DIMENSION;
197             }
198         }
199 
200         CalcDimension badgeSize;
201         if (SystemProperties::ConfigChangePerform()) {
202             RefPtr<ResourceObject> resObj;
203             badgeParameters.badgeCircleSizeByUser = true;
204             bool state = ParseJsDimensionNG(badgeSizeValue, badgeSize, DimensionUnit::FP, resObj);
205             badgeParameters.resourceBadgeSizeObject = resObj;
206             if (state && badgeSize.IsNonNegative() && badgeSize.Unit() != DimensionUnit::PERCENT) {
207                 badgeParameters.badgeCircleSize = badgeSize;
208                 isDefaultBadgeSize = false;
209             } else {
210                 badgeParameters.badgeCircleSize = badgeTheme->GetBadgeCircleSize();
211                 badgeParameters.badgeCircleSizeByUser = false;
212             }
213         } else {
214             if (ParseJsDimensionNG(badgeSizeValue, badgeSize, DimensionUnit::FP) && badgeSize.IsNonNegative() &&
215                 badgeSize.Unit() != DimensionUnit::PERCENT) {
216                 badgeParameters.badgeCircleSize = badgeSize;
217                 isDefaultBadgeSize = false;
218             } else {
219                 badgeParameters.badgeCircleSize = badgeTheme->GetBadgeCircleSize();
220             }
221         }
222 
223         BadgeModel::GetInstance()->SetIsDefault(isDefaultFontSize, isDefaultBadgeSize);
224         Color color;
225         if (SystemProperties::ConfigChangePerform()) {
226             RefPtr<ResourceObject> badgeColorResObj;
227             badgeParameters.badgeColorByUser = false;
228             bool state = ParseJsColor(badgeColorValue, color, badgeColorResObj);
229             badgeParameters.resourceBadgeColorObject = badgeColorResObj;
230             if (state) {
231                 badgeParameters.badgeColor = color;
232                 badgeParameters.badgeColorByUser = true;
233             } else if (themeColors) {
234                 badgeParameters.badgeColor = themeColors->Warning();
235             }
236         } else {
237             if (ParseJsColor(badgeColorValue, color)) {
238                 badgeParameters.badgeColor = color;
239             } else if (themeColors) {
240                 badgeParameters.badgeColor = themeColors->Warning();
241             }
242         }
243         CalcDimension borderWidth;
244 
245         if (SystemProperties::ConfigChangePerform()) {
246             RefPtr<ResourceObject> resObj;
247             badgeParameters.badgeBorderWidthByUser = true;
248             bool state = ParseJsDimensionVp(borderWidthValue, borderWidth, resObj);
249             badgeParameters.resourceBorderWidthObject = resObj;
250             if (state && borderWidth.IsNonNegative() && borderWidth.Unit() != DimensionUnit::PERCENT) {
251                 badgeParameters.badgeBorderWidth = borderWidth;
252             } else {
253                 badgeParameters.badgeBorderWidth = badgeTheme->GetBadgeBorderWidth();
254                 badgeParameters.badgeBorderWidthByUser = false;
255             }
256         } else {
257             if (ParseJsDimensionVp(borderWidthValue, borderWidth) && borderWidth.IsNonNegative() &&
258                 borderWidth.Unit() != DimensionUnit::PERCENT) {
259                 badgeParameters.badgeBorderWidth = borderWidth;
260             } else {
261                 badgeParameters.badgeBorderWidth = badgeTheme->GetBadgeBorderWidth();
262             }
263         }
264         Color borderColor;
265         if (SystemProperties::ConfigChangePerform()) {
266             RefPtr<ResourceObject> borderColorResObj;
267             badgeParameters.badgeBorderColorByUser = false;
268             bool state = ParseJsColor(borderColorValue, borderColor, borderColorResObj);
269             badgeParameters.resourceBorderColorObject = borderColorResObj;
270             if (state) {
271                 badgeParameters.badgeBorderColor = borderColor;
272                 badgeParameters.badgeBorderColorByUser = true;
273             } else {
274                 badgeParameters.badgeBorderColor =
275                     themeColors ? themeColors->Warning() : badgeTheme->GetBadgeBorderColor();
276             }
277         } else {
278             if (ParseJsColor(borderColorValue, borderColor)) {
279                 badgeParameters.badgeBorderColor = borderColor;
280             } else {
281                 badgeParameters.badgeBorderColor =
282                     themeColors ? themeColors->Warning() : badgeTheme->GetBadgeBorderColor();
283             }
284         }
285 
286         std::string fontWeight;
287         if (fontWeightValue->IsNumber()) {
288             fontWeight = std::to_string(fontWeightValue->ToNumber<int32_t>());
289             badgeParameters.badgeFontWeight = ConvertStrToFontWeight(fontWeight);
290         } else if (SystemProperties::ConfigChangePerform()) {
291             RefPtr<ResourceObject> resObj;
292             ParseJsString(fontWeightValue, fontWeight, resObj);
293             badgeParameters.resourceFontWeightObject = resObj;
294             badgeParameters.badgeFontWeight = ConvertStrToFontWeight(fontWeight);
295         } else {
296             if (!ParseJsString(fontWeightValue, fontWeight)) {
297                 badgeParameters.badgeFontWeight = FontWeight::NORMAL;
298             }
299             badgeParameters.badgeFontWeight = ConvertStrToFontWeight(fontWeight);
300         }
301     }
302 
303     auto count = obj->GetProperty("count");
304     if (!count->IsNull() && count->IsNumber()) {
305         badgeParameters.badgeCount = count->ToNumber<int32_t>();
306     }
307     auto maxCount = obj->GetProperty("maxCount");
308     if (!maxCount->IsNull() && maxCount->IsNumber()) {
309         badgeParameters.badgeMaxCount = maxCount->ToNumber<int32_t>();
310     } else {
311         badgeParameters.badgeMaxCount = badgeTheme->GetMaxCount();
312     }
313 
314     return badgeParameters;
315 }
316 
JSBind(BindingTarget globalObj)317 void JSBadge::JSBind(BindingTarget globalObj)
318 {
319     JSClass<JSBadge>::Declare("Badge");
320 
321     MethodOptions opt = MethodOptions::NONE;
322     JSClass<JSBadge>::StaticMethod("create", &JSBadge::Create, opt);
323     JSClass<JSBadge>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
324     JSClass<JSBadge>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
325     JSClass<JSBadge>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
326     JSClass<JSBadge>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
327     JSClass<JSBadge>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
328 
329     JSClass<JSBadge>::InheritAndBind<JSContainerBase>(globalObj);
330 }
331 } // namespace OHOS::Ace::Framework
332