• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "frameworks/bridge/declarative_frontend/jsview/js_save_button.h"
17 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
18 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
19 #endif
20 
21 #include "bridge/common/utils/utils.h"
22 #include "bridge/declarative_frontend/engine/functions/js_common_utils.h"
23 #include "bridge/declarative_frontend/jsview/js_utils.h"
24 #include "core/common/container.h"
25 #include "core/components/common/properties/text_style.h"
26 #include "core/components_ng/base/view_abstract_model.h"
27 #include "core/components_ng/pattern/security_component/save_button/save_button_model_ng.h"
28 #include "core/components_ng/pattern/security_component/security_component_model_ng.h"
29 #include "core/components_ng/pattern/security_component/security_component_theme.h"
30 
31 using OHOS::Ace::NG::SaveButtonModelNG;
32 using OHOS::Ace::NG::SecurityComponentModelNG;
33 using OHOS::Ace::NG::SecurityComponentTheme;
34 
35 namespace OHOS::Ace::Framework {
36 using namespace OHOS::Ace::Framework::CommonUtils;
37 
ParseComponentStyle(const JSCallbackInfo & info,SaveButtonSaveDescription & text,SaveButtonIconStyle & icon,int32_t & bg)38 bool JSSaveButton::ParseComponentStyle(const JSCallbackInfo& info,
39     SaveButtonSaveDescription& text, SaveButtonIconStyle& icon, int32_t& bg)
40 {
41     if ((info.Length() < 1) || (!info[0]->IsObject())) {
42         return false;
43     }
44 
45     auto paramObject = JSRef<JSObject>::Cast(info[0]);
46     auto value = paramObject->GetProperty("text");
47     if (value->IsNumber()) {
48         text = static_cast<SaveButtonSaveDescription>(value->ToNumber<int32_t>());
49         if ((text < SaveButtonSaveDescription::DOWNLOAD) ||
50             (text > SaveButtonSaveDescription::MAX_LABEL_TYPE)) {
51             return false;
52         }
53     } else {
54         text = SaveButtonSaveDescription::TEXT_NULL;
55     }
56 
57     value = paramObject->GetProperty("icon");
58     if (value->IsNumber()) {
59         icon = static_cast<SaveButtonIconStyle>(value->ToNumber<int32_t>());
60         if ((icon < SaveButtonIconStyle::ICON_FULL_FILLED) ||
61             (icon > SaveButtonIconStyle::ICON_PICTURE)) {
62             return false;
63         }
64     } else {
65         icon = SaveButtonIconStyle::ICON_NULL;
66     }
67 
68     if ((text == SaveButtonSaveDescription::TEXT_NULL) &&
69         (icon == SaveButtonIconStyle::ICON_NULL)) {
70         return false;
71     }
72 
73     value = paramObject->GetProperty("buttonType");
74     if (value->IsNumber()) {
75         bg = value->ToNumber<int32_t>();
76         if ((bg != static_cast<int32_t>(ButtonType::NORMAL)) &&
77             (bg != static_cast<int32_t>(ButtonType::CIRCLE)) &&
78             (bg != static_cast<int32_t>(ButtonType::CAPSULE)) &&
79             (bg != static_cast<int32_t>(ButtonType::ROUNDED_RECTANGLE))) {
80             return false;
81         }
82     } else {
83         bg = static_cast<int32_t>(ButtonType::CAPSULE);
84     }
85     return true;
86 }
87 
Create(const JSCallbackInfo & info)88 void JSSaveButton::Create(const JSCallbackInfo& info)
89 {
90     SaveButtonSaveDescription textDesc;
91     SaveButtonIconStyle iconType;
92     int32_t backgroundType = 0;
93     if (!ParseComponentStyle(info, textDesc, iconType, backgroundType)) {
94         SaveButtonModelNG::GetInstance()->Create(
95             static_cast<int32_t>(SaveButtonSaveDescription::DOWNLOAD),
96             static_cast<int32_t>(SaveButtonIconStyle::ICON_FULL_FILLED),
97             static_cast<int32_t>(ButtonType::CAPSULE), false);
98     } else {
99         SaveButtonModelNG::GetInstance()->Create(static_cast<int32_t>(textDesc),
100             static_cast<int32_t>(iconType), backgroundType, false);
101     }
102 }
103 
Execute(GestureEvent & info)104 void JsSaveButtonClickFunction::Execute(GestureEvent& info)
105 {
106     JSRef<JSObject> clickEventParam = JSRef<JSObject>::New();
107     Offset globalOffset = info.GetGlobalLocation();
108     Offset localOffset = info.GetLocalLocation();
109     Offset globalDisplayOffset = info.GetGlobalDisplayLocation();
110     clickEventParam->SetProperty<double>("screenX", PipelineBase::Px2VpWithCurrentDensity(globalOffset.GetX()));
111     clickEventParam->SetProperty<double>("screenY", PipelineBase::Px2VpWithCurrentDensity(globalOffset.GetY()));
112     clickEventParam->SetProperty<double>("x", PipelineBase::Px2VpWithCurrentDensity(localOffset.GetX()));
113     clickEventParam->SetProperty<double>("y", PipelineBase::Px2VpWithCurrentDensity(localOffset.GetY()));
114     clickEventParam->SetProperty<double>(
115         "globalDisplayX", PipelineBase::Px2VpWithCurrentDensity(globalDisplayOffset.GetX()));
116     clickEventParam->SetProperty<double>(
117         "globalDisplayY", PipelineBase::Px2VpWithCurrentDensity(globalDisplayOffset.GetY()));
118     clickEventParam->SetProperty<double>("timestamp",
119         static_cast<double>(info.GetTimeStamp().time_since_epoch().count()));
120     clickEventParam->SetProperty<double>("source", static_cast<int32_t>(info.GetSourceDevice()));
121     clickEventParam->SetProperty<double>("pressure", info.GetForce());
122     clickEventParam->SetProperty<double>("tiltX", info.GetTiltX().value_or(0.0f));
123     clickEventParam->SetProperty<double>("tiltY", info.GetTiltY().value_or(0.0f));
124     clickEventParam->SetProperty<double>("sourceTool", static_cast<int32_t>(info.GetSourceTool()));
125     auto target = CreateEventTargetObject(info);
126     clickEventParam->SetPropertyObject("target", target);
127     clickEventParam->SetProperty<int32_t>("targetDisplayId", info.GetTargetDisplayId());
128 
129     int32_t res = static_cast<int32_t>(SecurityComponentHandleResult::CLICK_GRANT_FAILED);
130     JSRef<JSObject> errorMessage = JSRef<JSObject>::New();
131 #ifdef SECURITY_COMPONENT_ENABLE
132     auto secEventValue = info.GetSecCompHandleEvent();
133     if (secEventValue != nullptr) {
134         res = secEventValue->GetInt("handleRes", res);
135         int32_t code = static_cast<int32_t>(SecurityComponentErrorCode::SUCCESS);
136         std::string message;
137         if (res == static_cast<int32_t>(SecurityComponentHandleResult::DROP_CLICK)) {
138             return;
139         }
140         code = secEventValue->GetInt("code", code);
141         errorMessage->SetProperty<int32_t>("code", code);
142         message = secEventValue->GetString("message", message);
143         errorMessage->SetProperty<std::string>("message", message);
144     }
145 #endif
146     JSRef<JSVal> errorParam = JSRef<JSVal>::Make(ToJSValue(res));
147     JSRef<JSVal> params[] = { clickEventParam, errorParam, errorMessage };
148     JsFunction::ExecuteJS(3, params); // 3 means three params.
149 }
150 
JsOnClick(const JSCallbackInfo & info)151 void JSSaveButton::JsOnClick(const JSCallbackInfo& info)
152 {
153     if ((info.Length() < 1) || (!info[0]->IsFunction())) {
154         return;
155     }
156     auto jsOnClickFunc = AceType::MakeRefPtr<JsSaveButtonClickFunction>(JSRef<JSFunc>::Cast(info[0]));
157     auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
158     auto onTap = [execCtx = info.GetExecutionContext(), func = jsOnClickFunc, node = frameNode](GestureEvent& info) {
159         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
160         ACE_SCORING_EVENT("onClick");
161         func->Execute(info);
162 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
163         JSInteractableView::ReportClickEvent(node);
164 #endif
165     };
166 
167     double distanceThreshold = std::numeric_limits<double>::infinity();
168     if (info.Length() > 1 && info[1]->IsNumber()) {
169         distanceThreshold = info[1]->ToNumber<double>();
170         distanceThreshold = Dimension(distanceThreshold, DimensionUnit::VP).ConvertToPx();
171     }
172     NG::ViewAbstract::SetOnClick(std::move(onTap), distanceThreshold);
173 }
174 
SetIcon(const JSCallbackInfo & info)175 void JSSaveButton::SetIcon(const JSCallbackInfo& info)
176 {
177     if (info.Length() < 1) {
178         return;
179     }
180     std::string bundleName;
181     std::string moduleName;
182     std::string src;
183     auto imageInfo = info[0];
184     int32_t resId = 0;
185     bool srcValid = ParseJsMediaWithBundleName(imageInfo, src, bundleName, moduleName, resId);
186     if (srcValid && (ImageSourceInfo::ResolveURIType(src) == SrcType::RESOURCE)) {
187         ImageSourceInfo image(std::make_shared<std::string>(src), bundleName, moduleName);
188         SecurityComponentModelNG::SetIcon(image);
189     }
190 }
191 
SetText(const JSCallbackInfo & info)192 void JSSaveButton::SetText(const JSCallbackInfo& info)
193 {
194     std::string label;
195     if (info.Length() < 1) {
196         return;
197     }
198     bool parseSuccess = ParseJsString(info[0], label);
199     if (parseSuccess) {
200         if ((info[0]->IsObject() && JSRef<JSObject>::Cast(info[0])->HasProperty("id")) || (info[0]->IsString())) {
201             SecurityComponentModelNG::SetText(label);
202         }
203     }
204 }
205 
SetIconBorderRadius(const JSCallbackInfo & info)206 void JSSaveButton::SetIconBorderRadius(const JSCallbackInfo& info)
207 {
208     if (info.Length() < 1) {
209         return;
210     }
211     if (info[0]->IsObject()) {
212         std::optional<CalcDimension> topLeft;
213         std::optional<CalcDimension> topRight;
214         std::optional<CalcDimension> bottomLeft;
215         std::optional<CalcDimension> bottomRight;
216         JSRef<JSObject> paddingObj = JSRef<JSObject>::Cast(info[0]);
217 
218         CalcDimension topLeftDimen;
219         if (ParseJsDimensionVp(paddingObj->GetProperty("topLeft"), topLeftDimen)) {
220             topLeft = topLeftDimen;
221         }
222         CalcDimension topRightDimen;
223         if (ParseJsDimensionVp(paddingObj->GetProperty("topRight"), topRightDimen)) {
224             topRight = topRightDimen;
225         }
226         CalcDimension bottomLeftDimen;
227         if (ParseJsDimensionVp(paddingObj->GetProperty("bottomLeft"), bottomLeftDimen)) {
228             bottomLeft = bottomLeftDimen;
229         }
230         CalcDimension bottomRightDimen;
231         if (ParseJsDimensionVp(paddingObj->GetProperty("bottomRight"), bottomRightDimen)) {
232             bottomRight = bottomRightDimen;
233         }
234 
235         if (topLeft.has_value() || topRight.has_value() || bottomLeft.has_value() || bottomRight.has_value()) {
236             SecurityComponentModelNG::SetIconBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
237             return;
238         }
239     }
240     auto theme = GetTheme<SecurityComponentTheme>();
241     CHECK_NULL_VOID(theme);
242 
243     CalcDimension value;
244     if (!ParseJsDimensionVp(info[0], value)) {
245         SecurityComponentModelNG::SetIconBorderRadius(theme->GetBorderRadius());
246     } else {
247         SecurityComponentModelNG::SetIconBorderRadius(value);
248     }
249 }
250 
SetStateEffect(const JSCallbackInfo & info)251 void JSSaveButton::SetStateEffect(const JSCallbackInfo& info)
252 {
253     if ((info.Length() < 1) || (!info[0]->IsBoolean())) {
254         return;
255     }
256     bool stateEffect = info[0]->ToBoolean();
257     SecurityComponentModelNG::SetStateEffect(stateEffect);
258 }
259 
SetTipPosition(const JSCallbackInfo & info)260 void JSSaveButton::SetTipPosition(const JSCallbackInfo& info)
261 {
262     if ((info.Length() < 1) || (!info[0]->IsNumber())) {
263         SecurityComponentModelNG::SetTipPosition(TipPosition::ABOVE_BOTTOM);
264         return;
265     }
266     int32_t value = info[0]->ToNumber<int32_t>();
267     if ((value < static_cast<int32_t>(TipPosition::ABOVE_BOTTOM)) ||
268         (value > static_cast<int32_t>(TipPosition::BELOW_TOP))) {
269         SecurityComponentModelNG::SetTipPosition(TipPosition::ABOVE_BOTTOM);
270         return;
271     }
272     SecurityComponentModelNG::SetTipPosition(static_cast<TipPosition>(value));
273 }
274 
JSBind(BindingTarget globalObj)275 void JSSaveButton::JSBind(BindingTarget globalObj)
276 {
277     JSClass<JSSaveButton>::Declare("SaveButton");
278     MethodOptions opt = MethodOptions::NONE;
279     JSClass<JSSaveButton>::StaticMethod("create", &JSSaveButton::Create, opt);
280     JSClass<JSSaveButton>::StaticMethod("setIcon", &JSSaveButton::SetIcon);
281     JSClass<JSSaveButton>::StaticMethod("setText", &JSSaveButton::SetText);
282     JSClass<JSSaveButton>::StaticMethod("iconSize", &JSSecButtonBase::SetIconSize);
283     JSClass<JSSaveButton>::StaticMethod("iconBorderRadius", &JSSaveButton::SetIconBorderRadius);
284     JSClass<JSSaveButton>::StaticMethod("layoutDirection", &JSSecButtonBase::SetLayoutDirection);
285     JSClass<JSSaveButton>::StaticMethod("fontSize", &JSSecButtonBase::SetFontSize);
286     JSClass<JSSaveButton>::StaticMethod("fontStyle", &JSSecButtonBase::SetFontStyle);
287     JSClass<JSSaveButton>::StaticMethod("iconColor", &JSSecButtonBase::SetIconColor);
288     JSClass<JSSaveButton>::StaticMethod("fontWeight", &JSSecButtonBase::SetFontWeight);
289     JSClass<JSSaveButton>::StaticMethod("fontFamily", &JSSecButtonBase::SetFontFamily);
290     JSClass<JSSaveButton>::StaticMethod("fontColor", &JSSecButtonBase::SetFontColor);
291     JSClass<JSSaveButton>::StaticMethod("backgroundColor", &JSSecButtonBase::SetBackgroundColor);
292     JSClass<JSSaveButton>::StaticMethod("borderStyle", &JSSecButtonBase::SetBackgroundBorderStyle);
293     JSClass<JSSaveButton>::StaticMethod("borderWidth", &JSSecButtonBase::SetBackgroundBorderWidth);
294     JSClass<JSSaveButton>::StaticMethod("borderColor", &JSSecButtonBase::SetBackgroundBorderColor);
295     JSClass<JSSaveButton>::StaticMethod("borderRadius", &JSSecButtonBase::SetBackgroundBorderRadius);
296     JSClass<JSSaveButton>::StaticMethod("padding", &JSSecButtonBase::SetBackgroundPadding);
297     JSClass<JSSaveButton>::StaticMethod("textIconSpace", &JSSecButtonBase::SetTextIconSpace);
298     JSClass<JSSaveButton>::StaticMethod("align", &JSSecButtonBase::SetAlign);
299     JSClass<JSSaveButton>::StaticMethod("onClick", &JSSaveButton::JsOnClick);
300     JSClass<JSSaveButton>::StaticMethod("stateEffect", &JSSaveButton::SetStateEffect);
301     JSClass<JSSaveButton>::StaticMethod("tipPosition", &JSSaveButton::SetTipPosition);
302     JSClass<JSSaveButton>::StaticMethod("key", &JSViewAbstract::JsKey);
303     JSClass<JSSaveButton>::StaticMethod("position", &JSViewAbstract::JsPosition);
304     JSClass<JSSaveButton>::StaticMethod("markAnchor", &JSViewAbstract::JsMarkAnchor);
305     JSClass<JSSaveButton>::StaticMethod("offset", &JSViewAbstract::JsOffset);
306     JSClass<JSSaveButton>::StaticMethod("pop", &JSViewAbstract::Pop, opt);
307     JSClass<JSSaveButton>::StaticMethod("width", &JSViewAbstract::JsWidth);
308     JSClass<JSSaveButton>::StaticMethod("height", &JSViewAbstract::JsHeight);
309     JSClass<JSSaveButton>::StaticMethod("size", &JSViewAbstract::JsSize);
310     JSClass<JSSaveButton>::StaticMethod("constraintSize", &JSViewAbstract::JsConstraintSize);
311     JSClass<JSSaveButton>::StaticMethod("debugLine", &JSViewAbstract::JsDebugLine);
312     JSClass<JSSaveButton>::StaticMethod("alignRules", &JSViewAbstract::JsAlignRules);
313     JSClass<JSSaveButton>::StaticMethod("id", &JSViewAbstract::JsId);
314     JSClass<JSSaveButton>::StaticMethod("chainMode", &JSViewAbstract::JsChainMode);
315     JSClass<JSSaveButton>::StaticMethod("maxFontScale", &JSSecButtonBase::SetMaxFontScale);
316     JSClass<JSSaveButton>::StaticMethod("minFontScale", &JSSecButtonBase::SetMinFontScale);
317     JSClass<JSSaveButton>::StaticMethod("maxLines", &JSSecButtonBase::SetMaxLines);
318     JSClass<JSSaveButton>::StaticMethod("maxFontSize", &JSSecButtonBase::SetMaxFontSize);
319     JSClass<JSSaveButton>::StaticMethod("minFontSize", &JSSecButtonBase::SetMinFontSize);
320     JSClass<JSSaveButton>::StaticMethod("heightAdaptivePolicy", &JSSecButtonBase::SetHeightAdaptivePolicy);
321     JSClass<JSSaveButton>::StaticMethod("enabled", &JSViewAbstract::JsEnabled);
322     JSClass<JSSaveButton>::Bind<>(globalObj);
323 }
324 } // namespace OHOS::Ace::Framework
325