• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "frameworks/bridge/declarative_frontend/jsview/js_side_bar.h"
17 
18 #include "base/geometry/dimension.h"
19 #include "base/image/pixel_map.h"
20 #include "base/log/ace_scoring_log.h"
21 #include "base/log/log.h"
22 #include "bridge/declarative_frontend/engine/js_ref_ptr.h"
23 #include "bridge/declarative_frontend/engine/js_types.h"
24 #include "bridge/declarative_frontend/jsview/js_utils.h"
25 #include "core/components_ng/base/view_stack_processor.h"
26 #include "core/components_ng/pattern/side_bar/side_bar_container_model_ng.h"
27 #include "frameworks/bridge/declarative_frontend/jsview/js_view_common_def.h"
28 #include "frameworks/bridge/declarative_frontend/jsview/models/side_bar_container_model_impl.h"
29 
30 namespace OHOS::Ace {
31 std::unique_ptr<SideBarContainerModel> SideBarContainerModel::instance_ = nullptr;
32 std::mutex SideBarContainerModel::mutex_;
33 
GetInstance()34 SideBarContainerModel* SideBarContainerModel::GetInstance()
35 {
36     if (!instance_) {
37         std::lock_guard<std::mutex> lock(mutex_);
38         if (!instance_) {
39 #ifdef NG_BUILD
40             instance_.reset(new NG::SideBarContainerModelNG());
41 #else
42             if (Container::IsCurrentUseNewPipeline()) {
43                 instance_.reset(new NG::SideBarContainerModelNG());
44             } else {
45                 instance_.reset(new Framework::SideBarContainerModelImpl());
46             }
47 #endif
48         }
49     }
50     return instance_.get();
51 }
52 } // namespace OHOS::Ace
53 
54 namespace OHOS::Ace::Framework {
55 namespace {
56 constexpr Dimension DEFAULT_CONTROL_BUTTON_WIDTH = 32.0_vp;
57 constexpr Dimension DEFAULT_CONTROL_BUTTON_HEIGHT = 32.0_vp;
58 constexpr Dimension DEFAULT_CONTROL_BUTTON_TOP = 48.0_vp;
59 constexpr Dimension DEFAULT_DIVIDER_STROKE_WIDTH = 1.0_vp;
60 constexpr Dimension DEFAULT_DIVIDER_START_MARGIN = 0.0_vp;
61 constexpr Dimension DEFAULT_DIVIDER_END_MARGIN = 0.0_vp;
62 static Dimension DEFAULT_SIDE_BAR_WIDTH = 200.0_vp;
63 static Dimension DEFAULT_MIN_SIDE_BAR_WIDTH = 200.0_vp;
64 constexpr Dimension DEFAULT_MAX_SIDE_BAR_WIDTH = 280.0_vp;
65 constexpr Color DEFAULT_DIVIDER_COLOR = Color(0x08000000);
66 
ParseAndSetWidth(const JSCallbackInfo & info,WidthType widthType)67 void ParseAndSetWidth(const JSCallbackInfo& info, WidthType widthType)
68 {
69     if (info.Length() < 1) {
70         return;
71     }
72 
73     CalcDimension value;
74     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
75         DEFAULT_SIDE_BAR_WIDTH = 240.0_vp;
76         DEFAULT_MIN_SIDE_BAR_WIDTH = 240.0_vp;
77     }
78 
79     auto isValid = Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)
80                        ? JSViewAbstract::ParseJsDimensionVpNG(info[0], value)
81                        : JSViewAbstract::ParseJsDimensionVp(info[0], value);
82     if (!isValid) {
83         switch (widthType) {
84             case WidthType::SIDEBAR_WIDTH:
85                 value = DEFAULT_SIDE_BAR_WIDTH;
86                 break;
87             case WidthType::MIN_SIDEBAR_WIDTH:
88                 value = DEFAULT_MIN_SIDE_BAR_WIDTH;
89                 break;
90             case WidthType::MAX_SIDEBAR_WIDTH:
91                 value = DEFAULT_MAX_SIDE_BAR_WIDTH;
92                 break;
93             default:
94                 break;
95         }
96     }
97     SideBarContainerModel::GetInstance()->ParseAndSetWidth(widthType, value);
98 }
99 } // namespace
100 
Create(const JSCallbackInfo & info)101 void JSSideBar::Create(const JSCallbackInfo& info)
102 {
103     SideBarContainerModel::GetInstance()->Create();
104     SideBarContainerType style = SideBarContainerType::EMBED;
105     if (!info[0]->IsNull()) {
106         if (info[0]->IsBoolean()) {
107             style = static_cast<SideBarContainerType>(info[0]->ToBoolean());
108         } else if (info[0]->IsNumber()) {
109             style = static_cast<SideBarContainerType>(info[0]->ToNumber<int>());
110         } else {
111             return;
112         }
113     }
114     SideBarContainerModel::GetInstance()->SetSideBarContainerType(style);
115 }
116 
SetShowControlButton(const JSCallbackInfo & info)117 void JSSideBar::SetShowControlButton(const JSCallbackInfo& info)
118 {
119     if (info.Length() < 1) {
120         return;
121     }
122     if (info[0]->IsNull() || info[0]->IsUndefined()) {
123         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
124             // showControlButton set default true when input illegal value
125             SideBarContainerModel::GetInstance()->SetShowControlButton(true);
126         }
127         return;
128     }
129     if (info[0]->IsBoolean()) {
130         SideBarContainerModel::GetInstance()->SetShowControlButton(info[0]->ToBoolean());
131     }
132 }
133 
JsSideBarPosition(const JSCallbackInfo & info)134 void JSSideBar::JsSideBarPosition(const JSCallbackInfo& info)
135 {
136     if (info.Length() < 1) {
137         return;
138     }
139     if (info[0]->IsNull() || info[0]->IsUndefined()) {
140         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
141             // sideBarPosition set default START when input illegal value
142             SideBarContainerModel::GetInstance()->SetSideBarPosition(SideBarPosition::START);
143         }
144         return;
145     }
146     if (info[0]->IsNumber() && info[0]->ToNumber<int32_t>() >= 0 && info[0]->ToNumber<int32_t>() <= 1) {
147         SideBarContainerModel::GetInstance()->SetSideBarPosition(
148             static_cast<SideBarPosition>(info[0]->ToNumber<int32_t>()));
149     }
150 }
151 
JSBind(BindingTarget globalObj)152 void JSSideBar::JSBind(BindingTarget globalObj)
153 {
154     JSClass<JSSideBar>::Declare("SideBarContainer");
155     MethodOptions opt = MethodOptions::NONE;
156     JSClass<JSSideBar>::StaticMethod("create", &JSSideBar::Create, opt);
157     JSClass<JSSideBar>::StaticMethod("showSideBar", &JSSideBar::JsShowSideBar);
158     JSClass<JSSideBar>::StaticMethod("controlButton", &JSSideBar::JsControlButton);
159     JSClass<JSSideBar>::StaticMethod("showControlButton", &JSSideBar::SetShowControlButton);
160     JSClass<JSSideBar>::StaticMethod("onChange", &JSSideBar::OnChange);
161     JSClass<JSSideBar>::StaticMethod("sideBarWidth", &JSSideBar::JsSideBarWidth);
162     JSClass<JSSideBar>::StaticMethod("minSideBarWidth", &JSSideBar::JsMinSideBarWidth);
163     JSClass<JSSideBar>::StaticMethod("maxSideBarWidth", &JSSideBar::JsMaxSideBarWidth);
164     JSClass<JSSideBar>::StaticMethod("autoHide", &JSSideBar::JsAutoHide);
165     JSClass<JSSideBar>::StaticMethod("sideBarPosition", &JSSideBar::JsSideBarPosition);
166     JSClass<JSSideBar>::StaticMethod("divider", &JSSideBar::JsDivider);
167     JSClass<JSSideBar>::StaticMethod("minContentWidth", &JSSideBar::JsMinContentWidth);
168     JSClass<JSSideBar>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
169     JSClass<JSSideBar>::StaticMethod("width", SetWidth);
170     JSClass<JSSideBar>::StaticMethod("height", SetHeight);
171     JSClass<JSSideBar>::StaticMethod("size", SetSize);
172     JSClass<JSSideBar>::StaticMethod("width", &JSStack::SetWidth);
173     JSClass<JSSideBar>::StaticMethod("height", &JSStack::SetHeight);
174     JSClass<JSSideBar>::StaticMethod("size", &JSStack::SetSize);
175     JSClass<JSSideBar>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
176     JSClass<JSSideBar>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
177     JSClass<JSSideBar>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
178     JSClass<JSSideBar>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
179     JSClass<JSSideBar>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
180     JSClass<JSSideBar>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
181     JSClass<JSSideBar>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
182     JSClass<JSSideBar>::InheritAndBind<JSContainerBase>(globalObj);
183 }
184 
OnChange(const JSCallbackInfo & info)185 void JSSideBar::OnChange(const JSCallbackInfo& info)
186 {
187     if (info.Length() < 1 || !info[0]->IsFunction()) {
188         return;
189     }
190 
191     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
192     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
193     auto onChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](bool isShow) {
194         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
195         ACE_SCORING_EVENT("SideBarContainer.onChange");
196         PipelineContext::SetCallBackNode(node);
197         auto newJSVal = JSRef<JSVal>::Make(ToJSValue(isShow));
198         func->ExecuteJS(1, &newJSVal);
199     };
200     SideBarContainerModel::GetInstance()->SetOnChange(std::move(onChange));
201     info.ReturnSelf();
202 }
203 
ParseSideBarWidthObject(const JSCallbackInfo & info,JSRef<JSVal> arrowFunc,bool isNumber)204 void ParseSideBarWidthObject(const JSCallbackInfo& info, JSRef<JSVal> arrowFunc, bool isNumber)
205 {
206     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(arrowFunc));
207     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
208     auto onChangeEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
209                         node = targetNode, useNumber = isNumber](const Dimension& sideBarWidth) {
210         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
211         ACE_SCORING_EVENT("SideBarContainer.onSideBarWidthChangeEvent");
212         PipelineContext::SetCallBackNode(node);
213         auto newJSVal = useNumber ? JSRef<JSVal>::Make(ToJSValue(sideBarWidth.ConvertToVp())) :
214             JSRef<JSVal>::Make(ToJSValue(sideBarWidth.ToString()));
215         func->ExecuteJS(1, &newJSVal);
216     };
217     SideBarContainerModel::GetInstance()->SetOnSideBarWidthChangeEvent(std::move(onChangeEvent));
218 }
219 
JsSideBarWidth(const JSCallbackInfo & info)220 void JSSideBar::JsSideBarWidth(const JSCallbackInfo& info)
221 {
222     if (info[0]->IsObject()) {
223         JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
224         CalcDimension value;
225         auto sideBarWidthValue = callbackObj->GetProperty("value");
226         auto sideBarWidthCallbackValue = callbackObj->GetProperty("$value");
227         auto isValid = JSViewAbstract::ParseJsDimensionVpNG(sideBarWidthValue, value);
228         bool isNumber = sideBarWidthValue->IsNumber();
229         if (isValid && sideBarWidthCallbackValue->IsFunction()) {
230             SideBarContainerModel::GetInstance()->ParseAndSetWidth(WidthType::SIDEBAR_WIDTH, value, true);
231             ParseSideBarWidthObject(info, sideBarWidthCallbackValue, isNumber);
232             return;
233         }
234     }
235     ParseAndSetWidth(info, WidthType::SIDEBAR_WIDTH);
236 }
237 
JsMaxSideBarWidth(const JSCallbackInfo & info)238 void JSSideBar::JsMaxSideBarWidth(const JSCallbackInfo& info)
239 {
240     ParseAndSetWidth(info, WidthType::MAX_SIDEBAR_WIDTH);
241 }
242 
JsMinSideBarWidth(const JSCallbackInfo & info)243 void JSSideBar::JsMinSideBarWidth(const JSCallbackInfo& info)
244 {
245     ParseAndSetWidth(info, WidthType::MIN_SIDEBAR_WIDTH);
246 }
247 
ParseShowSideBarObject(const JSCallbackInfo & args,const JSRef<JSVal> & changeEventVal)248 void ParseShowSideBarObject(const JSCallbackInfo& args, const JSRef<JSVal>& changeEventVal)
249 {
250     CHECK_NULL_VOID(changeEventVal->IsFunction());
251 
252     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
253     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
254     auto onChangeEvent = [execCtx = args.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
255                              bool isShow) {
256         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
257         ACE_SCORING_EVENT("SideBarContainer.onChangeEvent");
258         PipelineContext::SetCallBackNode(node);
259         auto newJSVal = JSRef<JSVal>::Make(ToJSValue(isShow));
260         func->ExecuteJS(1, &newJSVal);
261     };
262     SideBarContainerModel::GetInstance()->SetOnChangeEvent(std::move(onChangeEvent));
263 }
264 
JsShowSideBar(const JSCallbackInfo & info)265 void JSSideBar::JsShowSideBar(const JSCallbackInfo& info)
266 {
267     if (info.Length() < 1 || info.Length() > 2) {
268         return;
269     }
270 
271     bool isShow = true;
272     if (info.Length() > 0 && info[0]->IsBoolean()) {
273         isShow = info[0]->ToBoolean();
274     }
275 
276     SideBarContainerModel::GetInstance()->SetShowSideBar(isShow);
277     if (info.Length() > 1 && info[1]->IsFunction()) {
278         ParseShowSideBarObject(info, info[1]);
279     }
280 }
281 
SetControlButtonIcon(SideBarControlButtonType iconType,JSRef<JSVal> icon)282 void JSSideBar::SetControlButtonIcon(SideBarControlButtonType iconType, JSRef<JSVal> icon)
283 {
284     if (icon->IsUndefined() || icon->IsNull()) {
285         return;
286     }
287     std::string iconPath;
288     auto isStrType = ParseJsMedia(icon, iconPath);
289     RefPtr<PixelMap> pixMap = nullptr;
290 #if defined(PIXEL_MAP_SUPPORTED)
291     if (!isStrType) {
292         pixMap = CreatePixelMapFromNapiValue(icon);
293     }
294 #endif
295     if (isStrType || pixMap != nullptr) {
296         switch (iconType) {
297             case SideBarControlButtonType::SHOWN:
298                 SideBarContainerModel::GetInstance()->SetControlButtonShowIconInfo(iconPath, !isStrType, pixMap);
299                 break;
300             case SideBarControlButtonType::HIDDEN:
301                 SideBarContainerModel::GetInstance()->SetControlButtonHiddenIconInfo(iconPath, !isStrType, pixMap);
302                 break;
303             case SideBarControlButtonType::SWITCHING:
304                 SideBarContainerModel::GetInstance()->SetControlButtonSwitchingIconInfo(iconPath, !isStrType, pixMap);
305                 break;
306             default:
307                 break;
308         }
309     }
310 }
311 
JsControlButton(const JSCallbackInfo & info)312 void JSSideBar::JsControlButton(const JSCallbackInfo& info)
313 {
314     if (info.Length() < 1) {
315         return;
316     }
317     if (info[0]->IsNull() || info[0]->IsUndefined()) {
318         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
319             // controlButton icon set default style and position when input illegal value
320             SideBarContainerModel::GetInstance()->ResetControlButton();
321         }
322         return;
323     }
324     if (info[0]->IsObject()) {
325         JSRef<JSObject> value = JSRef<JSObject>::Cast(info[0]);
326         if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TEN)) {
327             ParseControlButtonOG(value);
328         } else {
329             ParseControlButtonNG(value);
330         }
331 
332         JSRef<JSVal> icons = value->GetProperty("icons");
333         if (icons->IsNull() || icons->IsUndefined()) {
334             if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
335                 // controlButton icon set default style when input illegal value
336                 SideBarContainerModel::GetInstance()->ResetControlButtonIconInfo();
337             }
338             return;
339         }
340         if (icons->IsObject()) {
341             JSRef<JSObject> iconsVal = JSRef<JSObject>::Cast(icons);
342             JSRef<JSVal> showIcon = iconsVal->GetProperty("shown");
343             JSRef<JSVal> switchingIcon = iconsVal->GetProperty("switching");
344             JSRef<JSVal> hiddenIcon = iconsVal->GetProperty("hidden");
345             SetControlButtonIcon(SideBarControlButtonType::SHOWN, showIcon);
346             SetControlButtonIcon(SideBarControlButtonType::HIDDEN, hiddenIcon);
347             SetControlButtonIcon(SideBarControlButtonType::SWITCHING, switchingIcon);
348         }
349     }
350 }
351 
JsDivider(const JSCallbackInfo & info)352 void JSSideBar::JsDivider(const JSCallbackInfo& info)
353 {
354     if (info.Length() < 1) {
355         return;
356     }
357     if (info[0]->IsNull() || info[0]->IsUndefined()) {
358         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
359             // sideBar divider set default width when input illegal value
360             SideBarContainerModel::GetInstance()->SetDividerStrokeWidth(DEFAULT_DIVIDER_STROKE_WIDTH);
361         } else if (info[0]->IsNull()) {
362             SideBarContainerModel::GetInstance()->SetDividerStrokeWidth(0.0_vp);
363         }
364         return;
365     }
366     if (info[0]->IsObject()) {
367         JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
368 
369         Dimension strokeWidth = DEFAULT_DIVIDER_STROKE_WIDTH;
370         if (!ConvertFromJSValueNG(obj->GetProperty("strokeWidth"), strokeWidth) || (strokeWidth.Value() < 0.0f)) {
371             strokeWidth = DEFAULT_DIVIDER_STROKE_WIDTH;
372         }
373         SideBarContainerModel::GetInstance()->SetDividerStrokeWidth(strokeWidth);
374 
375         Color color = DEFAULT_DIVIDER_COLOR;
376         if (!ConvertFromJSValue(obj->GetProperty("color"), color)) {
377             color = DEFAULT_DIVIDER_COLOR;
378         }
379         SideBarContainerModel::GetInstance()->SetDividerColor(color);
380 
381         Dimension startMargin = DEFAULT_DIVIDER_START_MARGIN;
382         if (!ConvertFromJSValueNG(obj->GetProperty("startMargin"), startMargin) || (startMargin.Value() < 0.0f)) {
383             startMargin = DEFAULT_DIVIDER_START_MARGIN;
384         }
385         SideBarContainerModel::GetInstance()->SetDividerStartMargin(startMargin);
386 
387         Dimension endMargin = DEFAULT_DIVIDER_END_MARGIN;
388         if (!ConvertFromJSValueNG(obj->GetProperty("endMargin"), endMargin) || (endMargin.Value() < 0.0f)) {
389             endMargin = DEFAULT_DIVIDER_END_MARGIN;
390         }
391         SideBarContainerModel::GetInstance()->SetDividerEndMargin(endMargin);
392     }
393 }
394 
JsMinContentWidth(const JSCallbackInfo & info)395 void JSSideBar::JsMinContentWidth(const JSCallbackInfo& info)
396 {
397     if (info.Length() < 1) {
398         return;
399     }
400     if (info[0]->IsNull()) {
401         SideBarContainerModel::GetInstance()->SetMinContentWidth(-1.0_vp);
402         return;
403     }
404     CalcDimension minContentWidth;
405     if (!JSViewAbstract::ParseJsDimensionVp(info[0], minContentWidth)) {
406         SideBarContainerModel::GetInstance()->SetMinContentWidth(-1.0_vp);
407         return;
408     }
409     SideBarContainerModel::GetInstance()->SetMinContentWidth(minContentWidth);
410 }
411 
JsAutoHide(bool autoHide)412 void JSSideBar::JsAutoHide(bool autoHide)
413 {
414     SideBarContainerModel::GetInstance()->SetAutoHide(autoHide);
415 }
416 
ParseControlButtonOG(JSRef<JSObject> value)417 void JSSideBar::ParseControlButtonOG(JSRef<JSObject> value)
418 {
419     JSRef<JSVal> width = value->GetProperty("width");
420     JSRef<JSVal> height = value->GetProperty("height");
421     JSRef<JSVal> left = value->GetProperty("left");
422     JSRef<JSVal> top = value->GetProperty("top");
423 
424     if (!width->IsNull() && width->IsNumber()) {
425         auto controlButtonWidth = CalcDimension(width->ToNumber<double>(), DimensionUnit::VP);
426         if (LessNotEqual(controlButtonWidth.Value(), 0.0)) {
427             controlButtonWidth = DEFAULT_CONTROL_BUTTON_WIDTH;
428         }
429         SideBarContainerModel::GetInstance()->SetControlButtonWidth(controlButtonWidth);
430     }
431 
432     if (!height->IsNull() && height->IsNumber()) {
433         auto controlButtonHeight = CalcDimension(height->ToNumber<double>(), DimensionUnit::VP);
434         if (LessNotEqual(controlButtonHeight.Value(), 0.0)) {
435             controlButtonHeight = DEFAULT_CONTROL_BUTTON_HEIGHT;
436         }
437         SideBarContainerModel::GetInstance()->SetControlButtonHeight(controlButtonHeight);
438     }
439 
440     if (!left->IsNull() && left->IsNumber()) {
441         SideBarContainerModel::GetInstance()->SetControlButtonLeft(
442             Dimension(left->ToNumber<double>(), DimensionUnit::VP));
443     }
444 
445     if (!top->IsNull() && top->IsNumber()) {
446         SideBarContainerModel::GetInstance()->SetControlButtonTop(
447             Dimension(top->ToNumber<double>(), DimensionUnit::VP));
448     }
449 }
450 
ParseControlButtonNG(JSRef<JSObject> value)451 void JSSideBar::ParseControlButtonNG(JSRef<JSObject> value)
452 {
453     JSRef<JSVal> width = value->GetProperty("width");
454     JSRef<JSVal> height = value->GetProperty("height");
455     JSRef<JSVal> left = value->GetProperty("left");
456     JSRef<JSVal> top = value->GetProperty("top");
457 
458     auto controlButtonWidth = DEFAULT_CONTROL_BUTTON_WIDTH;
459     if (width->IsNumber() && GreatOrEqual(width->ToNumber<double>(), 0.0)) {
460         controlButtonWidth = CalcDimension(width->ToNumber<double>(), DimensionUnit::VP);
461     }
462     SideBarContainerModel::GetInstance()->SetControlButtonWidth(controlButtonWidth);
463 
464     auto controlButtonHeight = DEFAULT_CONTROL_BUTTON_HEIGHT;
465     if (height->IsNumber() && GreatOrEqual(height->ToNumber<double>(), 0.0)) {
466         controlButtonHeight = CalcDimension(height->ToNumber<double>(), DimensionUnit::VP);
467     }
468     SideBarContainerModel::GetInstance()->SetControlButtonHeight(controlButtonHeight);
469 
470     if (left->IsNumber() && GreatOrEqual(left->ToNumber<double>(), 0.0)) {
471         auto controlButtonLeft = CalcDimension(left->ToNumber<double>(), DimensionUnit::VP);
472         SideBarContainerModel::GetInstance()->SetControlButtonLeft(controlButtonLeft);
473     } else {
474         SideBarContainerModel::GetInstance()->ResetControlButtonLeft();
475     }
476 
477     auto controlButtonTop = DEFAULT_CONTROL_BUTTON_TOP;
478     if (top->IsNumber() && GreatOrEqual(top->ToNumber<double>(), 0.0)) {
479         controlButtonTop = CalcDimension(top->ToNumber<double>(), DimensionUnit::VP);
480     }
481     SideBarContainerModel::GetInstance()->SetControlButtonTop(controlButtonTop);
482 }
483 
484 } // namespace OHOS::Ace::Framework
485