1 /*
2 * Copyright (c) 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_menu_item.h"
17
18 #include "base/log/ace_scoring_log.h"
19 #include "core/components_ng/base/view_stack_processor.h"
20 #include "core/components_ng/pattern/menu/menu_item/menu_item_view.h"
21
22 namespace OHOS::Ace::Framework {
Create(const JSCallbackInfo & info)23 void JSMenuItem::Create(const JSCallbackInfo& info)
24 {
25 if (info.Length() < 1 || (!info[0]->IsObject() && !info[0]->IsFunction())) {
26 LOGW("JSMenuItem The arg is wrong");
27 return;
28 }
29 if (Container::IsCurrentUseNewPipeline()) {
30 // custom menu item
31 if (info[0]->IsFunction()) {
32 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(info[0]));
33 CHECK_NULL_VOID(builderFunc);
34
35 NG::ScopedViewStackProcessor builderViewStackProcessor;
36 builderFunc->Execute();
37 auto customNode = NG::ViewStackProcessor::GetInstance()->Finish();
38 CHECK_NULL_VOID(customNode);
39 } else {
40 auto menuItemObj = JSRef<JSObject>::Cast(info[0]);
41
42 std::string startIconPath;
43 std::string contentStr;
44 std::string endIconPath;
45 std::string labelStr;
46 NG::MenuItemProperties menuItemProps;
47
48 auto startIcon = menuItemObj->GetProperty("startIcon");
49 auto content = menuItemObj->GetProperty("content");
50 auto endIcon = menuItemObj->GetProperty("endIcon");
51 auto label = menuItemObj->GetProperty("labelInfo");
52
53 if (ParseJsMedia(startIcon, startIconPath)) {
54 menuItemProps.startIcon = startIconPath;
55 } else {
56 LOGI("startIcon is null");
57 }
58
59 if (!ParseJsString(content, contentStr)) {
60 LOGI("content is null");
61 }
62 menuItemProps.content = contentStr;
63
64 if (ParseJsMedia(endIcon, endIconPath)) {
65 menuItemProps.endIcon = endIconPath;
66 } else {
67 LOGI("endIcon is null");
68 }
69
70 if (ParseJsString(label, labelStr)) {
71 menuItemProps.labelInfo = labelStr;
72 } else {
73 LOGI("labelInfo is null");
74 }
75
76 auto builder = menuItemObj->GetProperty("builder");
77 if (!builder.IsEmpty() && builder->IsFunction()) {
78 auto subBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
79 CHECK_NULL_VOID(subBuilderFunc);
80 auto subBuildFunc = [execCtx = info.GetExecutionContext(), func = std::move(subBuilderFunc)]() {
81 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
82 ACE_SCORING_EVENT("MenuItem SubBuilder");
83 func->ExecuteJS();
84 };
85 menuItemProps.buildFunc = std::move(subBuildFunc);
86 }
87 NG::MenuItemView::Create(menuItemProps);
88 }
89 return;
90 }
91 }
92
JSBind(BindingTarget globalObj)93 void JSMenuItem::JSBind(BindingTarget globalObj)
94 {
95 JSClass<JSMenuItem>::Declare("MenuItem");
96 MethodOptions opt = MethodOptions::NONE;
97 JSClass<JSMenuItem>::StaticMethod("create", &JSMenuItem::Create, opt);
98
99 JSClass<JSMenuItem>::StaticMethod("selected", &JSMenuItem::IsSelected, opt);
100 JSClass<JSMenuItem>::StaticMethod("selectIcon", &JSMenuItem::SelectIcon, opt);
101 JSClass<JSMenuItem>::StaticMethod("onChange", &JSMenuItem::OnChange, opt);
102 JSClass<JSMenuItem>::Inherit<JSViewAbstract>();
103 JSClass<JSMenuItem>::Bind(globalObj);
104 }
105
IsSelected(bool isSelected)106 void JSMenuItem::IsSelected(bool isSelected)
107 {
108 if (Container::IsCurrentUseNewPipeline()) {
109 NG::MenuItemView::SetSelected(isSelected);
110 }
111 }
112
SelectIcon(bool isShow)113 void JSMenuItem::SelectIcon(bool isShow)
114 {
115 if (Container::IsCurrentUseNewPipeline()) {
116 NG::MenuItemView::SetSelectIcon(isShow);
117 }
118 }
119
OnChange(const JSCallbackInfo & info)120 void JSMenuItem::OnChange(const JSCallbackInfo& info)
121 {
122 if (Container::IsCurrentUseNewPipeline()) {
123 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
124 auto onChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](bool selected) {
125 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
126 ACE_SCORING_EVENT("MenuItem.onChange");
127 JSRef<JSVal> params[1];
128 params[0] = JSRef<JSVal>::Make(ToJSValue(selected));
129 func->ExecuteJS(1, params);
130 };
131 NG::MenuItemView::SetOnChange(std::move(onChange));
132 }
133 info.ReturnSelf();
134 }
135 } // namespace OHOS::Ace::Framework
136