1 /*
2 * Copyright (c) 2024 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 "base/utils/utils.h"
17 #include "base/utils/string_utils.h"
18 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
19
20 #include "base/log/ace_scoring_log.h"
21 #include "bridge/declarative_frontend/engine/functions/js_click_function.h"
22 #include "bridge/declarative_frontend/engine/jsi/js_ui_index.h"
23 #include "bridge/declarative_frontend/jsview/js_view_context.h"
24 #include "bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h"
25 #include "core/components/popup/popup_theme.h"
26 #include "core/components_ng/base/view_abstract_model_ng.h"
27 #include "core/components_ng/base/view_stack_model.h"
28
29 #include "bridge/declarative_frontend/jsview/js_popups.h"
30
31 namespace OHOS::Ace::Framework {
32 namespace {
33 constexpr int32_t PARAMETER_LENGTH_ZERO = 0;
34 constexpr int32_t PARAMETER_LENGTH_FIRST = 1;
35 constexpr int32_t PARAMETER_LENGTH_SECOND = 2;
36 constexpr int32_t PARAMETER_LENGTH_THIRD = 3;
37 constexpr int NUM_ZERO = 0;
38 constexpr int NUM_FIRST = 1;
39 constexpr int NUM_SECOND = 2;
40 constexpr int32_t TRANSITION_NUM_ZERO = 0;
41 constexpr int32_t TRANSITION_NUM_TWO = 2;
42 constexpr uint32_t ON_WILL_DISMISS_FIELD_COUNT = 2;
43 const std::vector<FontStyle> FONT_STYLES = { FontStyle::NORMAL, FontStyle::ITALIC };
44 constexpr Dimension ARROW_ZERO_PERCENT_VALUE = 0.0_pct;
45 constexpr Dimension ARROW_HALF_PERCENT_VALUE = 0.5_pct;
46 constexpr Dimension ARROW_ONE_HUNDRED_PERCENT_VALUE = 1.0_pct;
47 const std::string SHEET_HEIGHT_MEDIUM = "medium";
48 const std::string SHEET_HEIGHT_LARGE = "large";
49 const std::string SHEET_HEIGHT_AUTO = "auto";
50 const std::string SHEET_HEIGHT_FITCONTENT = "fit_content";
51 constexpr int HAPTIC_FEEDBACK_MODE_ENABLED = 1;
52 constexpr int HAPTIC_FEEDBACK_MODE_AUTO = 2;
53 const std::vector<HoverModeAreaType> HOVER_MODE_AREA_TYPE = { HoverModeAreaType::TOP_SCREEN,
54 HoverModeAreaType::BOTTOM_SCREEN };
55 }
56
57 using DoubleBindCallback = std::function<void(const std::string&)>;
58
59 #ifndef WEARABLE_PRODUCT
ParseDoubleBindCallback(const JSCallbackInfo & info,const JSRef<JSObject> & callbackObj,const char * arrowFuncName)60 DoubleBindCallback JSViewPopups::ParseDoubleBindCallback(const JSCallbackInfo& info, const JSRef<JSObject>& callbackObj,
61 const char* arrowFuncName)
62 {
63 JSRef<JSVal> arrowFunc = callbackObj->GetProperty(arrowFuncName);
64 if (!arrowFunc->IsFunction()) {
65 return {};
66 }
67 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(arrowFunc));
68 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
69 auto callback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
70 const std::string& param) {
71 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
72 if (param != "true" && param != "false") {
73 return;
74 }
75 PipelineContext::SetCallBackNode(node);
76 bool newValue = StringToBool(param);
77 JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(newValue));
78 func->ExecuteJS(1, &newJSVal);
79 };
80 return callback;
81 }
82
SetPopupMessageOptions(const JSRef<JSObject> messageOptionsObj,const RefPtr<PopupParam> & popupParam)83 void SetPopupMessageOptions(const JSRef<JSObject> messageOptionsObj, const RefPtr<PopupParam>& popupParam)
84 {
85 auto colorValue = messageOptionsObj->GetProperty("textColor");
86 Color textColor;
87 if (JSViewAbstract::ParseJsColor(colorValue, textColor)) {
88 if (popupParam) {
89 popupParam->SetTextColor(textColor);
90 }
91 }
92
93 auto font = messageOptionsObj->GetProperty("font");
94 if (!font->IsNull() && font->IsObject()) {
95 JSRef<JSObject> fontObj = JSRef<JSObject>::Cast(font);
96 auto fontSizeValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::SIZE));
97 CalcDimension fontSize;
98 if (JSViewAbstract::ParseJsDimensionFp(fontSizeValue, fontSize)) {
99 if (popupParam && fontSize.IsValid()) {
100 popupParam->SetFontSize(fontSize);
101 }
102 }
103 auto fontWeightValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::WEIGHT));
104 if (fontWeightValue->IsString()) {
105 if (popupParam) {
106 popupParam->SetFontWeight(ConvertStrToFontWeight(fontWeightValue->ToString()));
107 }
108 }
109 auto fontStyleValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::STYLE));
110 if (fontStyleValue->IsNumber()) {
111 int32_t value = fontStyleValue->ToNumber<int32_t>();
112 if (value < 0 || value >= static_cast<int32_t>(FONT_STYLES.size())) {
113 return;
114 }
115 if (popupParam) {
116 popupParam->SetFontStyle(FONT_STYLES[value]);
117 }
118 }
119 }
120 }
121
SetPlacementOnTopVal(const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)122 void SetPlacementOnTopVal(const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
123 {
124 JSRef<JSVal> placementOnTopVal = popupObj->GetProperty("placementOnTop");
125 if (placementOnTopVal->IsBoolean() && popupParam) {
126 popupParam->SetPlacement(placementOnTopVal->ToBoolean() ? Placement::TOP : Placement::BOTTOM);
127 }
128 }
129
IsPopupCreated()130 bool IsPopupCreated()
131 {
132 auto targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
133 CHECK_NULL_RETURN(targetNode, false);
134 auto targetId = targetNode->GetId();
135 auto container = Container::Current();
136 CHECK_NULL_RETURN(container, false);
137 auto pipelineContext = container->GetPipelineContext();
138 CHECK_NULL_RETURN(pipelineContext, false);
139 auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
140 CHECK_NULL_RETURN(context, false);
141 auto overlayManager = context->GetOverlayManager();
142 CHECK_NULL_RETURN(overlayManager, false);
143 auto popupInfo = overlayManager->GetPopupInfo(targetId);
144 if (popupInfo.popupId == -1 || !popupInfo.popupNode) {
145 return false;
146 }
147 return true;
148 }
149
GetPopupDefaultShadowStyle()150 ShadowStyle GetPopupDefaultShadowStyle()
151 {
152 auto shadowStyle = ShadowStyle::OuterDefaultMD;
153 auto container = Container::Current();
154 CHECK_NULL_RETURN(container, shadowStyle);
155 auto pipelineContext = container->GetPipelineContext();
156 CHECK_NULL_RETURN(pipelineContext, shadowStyle);
157 auto popupTheme = pipelineContext->GetTheme<PopupTheme>();
158 CHECK_NULL_RETURN(popupTheme, shadowStyle);
159 return popupTheme->GetPopupShadowStyle();
160 }
161
GetBlurStyleFromTheme(const RefPtr<PopupParam> & popupParam)162 static void GetBlurStyleFromTheme(const RefPtr<PopupParam>& popupParam)
163 {
164 CHECK_NULL_VOID(popupParam);
165 auto pipelineContext = PipelineContext::GetCurrentContext();
166 CHECK_NULL_VOID(pipelineContext);
167 auto theme = pipelineContext->GetTheme<PopupTheme>();
168 CHECK_NULL_VOID(theme);
169 auto blurStyle = static_cast<BlurStyle>(theme->GetPopupBackgroundBlurStyle());
170 popupParam->SetBlurStyle(blurStyle);
171 }
172
ParsePopupCommonParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam,const RefPtr<NG::FrameNode> popupTargetNode=nullptr)173 void ParsePopupCommonParam(const JSCallbackInfo& info, const JSRef<JSObject>& popupObj,
174 const RefPtr<PopupParam>& popupParam, const RefPtr<NG::FrameNode> popupTargetNode = nullptr)
175 {
176 auto arrowOffset = popupObj->GetProperty("arrowOffset");
177 CalcDimension offset;
178 if (JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset)) {
179 if (popupParam) {
180 popupParam->SetArrowOffset(offset);
181 }
182 }
183
184 auto arrowPointPosition = popupObj->GetProperty("arrowPointPosition");
185 if (arrowPointPosition->IsString()) {
186 char* pEnd = nullptr;
187 auto arrowString = arrowPointPosition->ToString();
188 std::strtod(arrowString.c_str(), &pEnd);
189 if (pEnd != nullptr) {
190 if (std::strcmp(pEnd, "Start") == 0) {
191 offset = ARROW_ZERO_PERCENT_VALUE;
192 }
193 if (std::strcmp(pEnd, "Center") == 0) {
194 offset = ARROW_HALF_PERCENT_VALUE;
195 }
196 if (std::strcmp(pEnd, "End") == 0) {
197 offset = ARROW_ONE_HUNDRED_PERCENT_VALUE;
198 }
199 if (popupParam) {
200 popupParam->SetArrowOffset(offset);
201 }
202 }
203 }
204
205 auto targetSpace = popupObj->GetProperty("targetSpace");
206 if (!targetSpace->IsNull()) {
207 CalcDimension space;
208 if (JSViewAbstract::ParseJsDimensionVp(targetSpace, space)) {
209 if (popupParam) {
210 popupParam->SetTargetSpace(space);
211 }
212 }
213 }
214
215 JSRef<JSVal> showInSubWindowValue = popupObj->GetProperty("showInSubWindow");
216 if (showInSubWindowValue->IsBoolean()) {
217 bool showInSubBoolean = showInSubWindowValue->ToBoolean();
218 #if defined(PREVIEW)
219 if (showInSubBoolean) {
220 LOGI("[Engine Log] Unable to use the SubWindow in the Previewer. Use normal type instead.");
221 showInSubBoolean = false;
222 }
223 #endif
224 if (popupParam) {
225 popupParam->SetShowInSubWindow(showInSubBoolean);
226 }
227 }
228
229 auto placementValue = popupObj->GetProperty("placement");
230 if (placementValue->IsNumber()) {
231 auto placement = placementValue->ToNumber<int32_t>();
232 if (placement >= 0 && placement < static_cast<int32_t>(Placement::NONE)) {
233 popupParam->SetPlacement(static_cast<Placement>(placement));
234 }
235 } else {
236 SetPlacementOnTopVal(popupObj, popupParam);
237 }
238
239 auto enableArrowValue = popupObj->GetProperty("enableArrow");
240 if (enableArrowValue->IsBoolean()) {
241 popupParam->SetEnableArrow(enableArrowValue->ToBoolean());
242 }
243
244 auto enableHoverModeValue = popupObj->GetProperty("enableHoverMode");
245 if (enableHoverModeValue->IsBoolean()) {
246 popupParam->SetEnableHoverMode(enableHoverModeValue->ToBoolean());
247 }
248
249 auto followTransformOfTargetValue = popupObj->GetProperty("followTransformOfTarget");
250 if (followTransformOfTargetValue->IsBoolean()) {
251 popupParam->SetFollowTransformOfTarget(followTransformOfTargetValue->ToBoolean());
252 }
253
254 JSRef<JSVal> maskValue = popupObj->GetProperty("mask");
255 if (maskValue->IsBoolean()) {
256 if (popupParam) {
257 popupParam->SetBlockEvent(maskValue->ToBoolean());
258 }
259 }
260 if (maskValue->IsObject()) {
261 auto maskObj = JSRef<JSObject>::Cast(maskValue);
262 auto colorValue = maskObj->GetProperty("color");
263 Color maskColor;
264 if (JSViewAbstract::ParseJsColor(colorValue, maskColor)) {
265 popupParam->SetMaskColor(maskColor);
266 }
267 }
268
269 JSRef<JSVal> onStateChangeVal = popupObj->GetProperty("onStateChange");
270 if (onStateChangeVal->IsFunction()) {
271 std::vector<std::string> keys = { "isVisible" };
272 RefPtr<JsFunction> jsFunc =
273 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onStateChangeVal));
274 WeakPtr<NG::FrameNode> targetNode = nullptr;
275 if (popupTargetNode) {
276 targetNode = AceType::WeakClaim(AceType::RawPtr(popupTargetNode));
277 } else {
278 targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
279 }
280 if (popupParam) {
281 auto onStateChangeCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), keys,
282 node = targetNode](const std::string& param) {
283 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
284 ACE_SCORING_EVENT("Popup.onStateChange");
285 PipelineContext::SetCallBackNode(node);
286 func->Execute(keys, param);
287 };
288 popupParam->SetOnStateChange(onStateChangeCallback);
289 }
290 }
291
292 auto offsetVal = popupObj->GetProperty("offset");
293 if (offsetVal->IsObject()) {
294 auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
295 auto xVal = offsetObj->GetProperty("x");
296 auto yVal = offsetObj->GetProperty("y");
297 Offset popupOffset;
298 CalcDimension dx;
299 CalcDimension dy;
300 if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
301 popupOffset.SetX(dx.ConvertToPx());
302 }
303 if (JSViewAbstract::ParseJsDimensionVp(yVal, dy)) {
304 popupOffset.SetY(dy.ConvertToPx());
305 }
306 if (popupParam) {
307 popupParam->SetTargetOffset(popupOffset);
308 }
309 }
310
311 Color backgroundColor;
312 auto popupColorVal = popupObj->GetProperty("popupColor");
313 if (JSViewAbstract::ParseJsColor(popupColorVal, backgroundColor)) {
314 popupParam->SetBackgroundColor(backgroundColor);
315 }
316
317 auto autoCancelVal = popupObj->GetProperty("autoCancel");
318 if (autoCancelVal->IsBoolean()) {
319 popupParam->SetHasAction(!autoCancelVal->ToBoolean());
320 }
321
322 auto childWidthVal = popupObj->GetProperty("width");
323 if (!childWidthVal->IsNull()) {
324 CalcDimension width;
325 if (JSViewAbstract::ParseJsDimensionVp(childWidthVal, width)) {
326 if (width.Value() > 0) {
327 popupParam->SetChildWidth(width);
328 }
329 }
330 }
331
332 auto arrowWidthVal = popupObj->GetProperty("arrowWidth");
333 if (!arrowWidthVal->IsNull()) {
334 bool setError = true;
335 CalcDimension arrowWidth;
336 if (JSViewAbstract::ParseJsDimensionVp(arrowWidthVal, arrowWidth)) {
337 if (arrowWidth.Value() > 0 && arrowWidth.Unit() != DimensionUnit::PERCENT) {
338 popupParam->SetArrowWidth(arrowWidth);
339 setError = false;
340 }
341 }
342 popupParam->SetErrorArrowWidth(setError);
343 }
344
345 auto arrowHeightVal = popupObj->GetProperty("arrowHeight");
346 if (!arrowHeightVal->IsNull()) {
347 bool setError = true;
348 CalcDimension arrowHeight;
349 if (JSViewAbstract::ParseJsDimensionVp(arrowHeightVal, arrowHeight)) {
350 if (arrowHeight.Value() > 0 && arrowHeight.Unit() != DimensionUnit::PERCENT) {
351 popupParam->SetArrowHeight(arrowHeight);
352 setError = false;
353 }
354 }
355 popupParam->SetErrorArrowHeight(setError);
356 }
357
358 auto radiusVal = popupObj->GetProperty("radius");
359 if (!radiusVal->IsNull()) {
360 bool setError = true;
361 CalcDimension radius;
362 if (JSViewAbstract::ParseJsDimensionVp(radiusVal, radius)) {
363 if (radius.Value() >= 0) {
364 popupParam->SetRadius(radius);
365 setError = false;
366 }
367 }
368 popupParam->SetErrorRadius(setError);
369 }
370
371 auto defaultShadowStyle = GetPopupDefaultShadowStyle();
372 Shadow shadow;
373 auto shadowVal = popupObj->GetProperty("shadow");
374 if (shadowVal->IsObject() || shadowVal->IsNumber()) {
375 auto ret = JSViewAbstract::ParseShadowProps(shadowVal, shadow);
376 if (!ret) {
377 if (!(popupParam->GetIsPartialUpdate().has_value() && popupParam->GetIsPartialUpdate().value())) {
378 JSViewAbstract::GetShadowFromTheme(defaultShadowStyle, shadow);
379 popupParam->SetShadow(shadow);
380 }
381 } else {
382 popupParam->SetShadow(shadow);
383 }
384 } else {
385 if (!(popupParam->GetIsPartialUpdate().has_value() && popupParam->GetIsPartialUpdate().value())) {
386 JSViewAbstract::GetShadowFromTheme(defaultShadowStyle, shadow);
387 popupParam->SetShadow(shadow);
388 }
389 }
390
391 auto blurStyleValue = popupObj->GetProperty("backgroundBlurStyle");
392 if (blurStyleValue->IsNumber()) {
393 auto blurStyle = blurStyleValue->ToNumber<int32_t>();
394 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
395 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
396 popupParam->SetBlurStyle(static_cast<BlurStyle>(blurStyle));
397 } else {
398 if (!(popupParam->GetIsPartialUpdate().has_value() && popupParam->GetIsPartialUpdate().value())) {
399 GetBlurStyleFromTheme(popupParam);
400 }
401 }
402 } else {
403 if (!(popupParam->GetIsPartialUpdate().has_value() && popupParam->GetIsPartialUpdate().value())) {
404 GetBlurStyleFromTheme(popupParam);
405 }
406 }
407
408 auto popupTransition = popupObj->GetProperty("transition");
409 if (popupTransition->IsObject()) {
410 popupParam->SetHasTransition(true);
411 auto obj = JSRef<JSObject>::Cast(popupTransition);
412 if (popupTargetNode) {
413 auto effects = JSViewAbstract::ParseChainedTransition(obj, info.GetExecutionContext(), popupTargetNode);
414 popupParam->SetTransitionEffects(effects);
415 } else {
416 auto effects = JSViewAbstract::ParseChainedTransition(obj, info.GetExecutionContext());
417 popupParam->SetTransitionEffects(effects);
418 }
419 }
420 auto keyboardAvoidMode = popupObj->GetProperty("keyboardAvoidMode");
421 if (keyboardAvoidMode->IsNumber()) {
422 auto popupKeyboardAvoidMode = keyboardAvoidMode->ToNumber<int32_t>();
423 if (popupKeyboardAvoidMode >= static_cast<int>(PopupKeyboardAvoidMode::DEFAULT) &&
424 popupKeyboardAvoidMode <= static_cast<int>(PopupKeyboardAvoidMode::NONE)) {
425 popupParam->SetKeyBoardAvoidMode(static_cast<PopupKeyboardAvoidMode>(popupKeyboardAvoidMode));
426 }
427 }
428 }
429
ParsePopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)430 void ParsePopupParam(const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
431 {
432 ParsePopupCommonParam(info, popupObj, popupParam);
433 JSRef<JSVal> messageVal = popupObj->GetProperty("message");
434 if (popupParam) {
435 popupParam->SetMessage(messageVal->ToString());
436 }
437
438 auto messageOptions = popupObj->GetProperty("messageOptions");
439 JSRef<JSObject> messageOptionsObj;
440 if (!messageOptions->IsNull() && messageOptions->IsObject()) {
441 messageOptionsObj = JSRef<JSObject>::Cast(messageOptions);
442 SetPopupMessageOptions(messageOptionsObj, popupParam);
443 }
444
445 JSRef<JSVal> primaryButtonVal = popupObj->GetProperty("primaryButton");
446 if (primaryButtonVal->IsObject()) {
447 ButtonProperties properties;
448 JSRef<JSObject> obj = JSRef<JSObject>::Cast(primaryButtonVal);
449 JSRef<JSVal> value = obj->GetProperty("value");
450 if (value->IsString()) {
451 properties.value = value->ToString();
452 }
453
454 JSRef<JSVal> actionValue = obj->GetProperty("action");
455 if (actionValue->IsFunction()) {
456 auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionValue));
457 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
458 if (popupParam) {
459 auto clickCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc),
460 node = targetNode](GestureEvent& info) {
461 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
462 ACE_SCORING_EVENT("primaryButton.action");
463 PipelineContext::SetCallBackNode(node);
464 func->Execute(info);
465 };
466 properties.action = AceType::MakeRefPtr<NG::ClickEvent>(clickCallback);
467 }
468 }
469 properties.showButton = true;
470 if (popupParam) {
471 popupParam->SetPrimaryButtonProperties(properties);
472 }
473 }
474
475 JSRef<JSVal> secondaryButtonVal = popupObj->GetProperty("secondaryButton");
476 if (secondaryButtonVal->IsObject()) {
477 ButtonProperties properties;
478 JSRef<JSObject> obj = JSRef<JSObject>::Cast(secondaryButtonVal);
479 JSRef<JSVal> value = obj->GetProperty("value");
480 if (value->IsString()) {
481 properties.value = value->ToString();
482 }
483
484 JSRef<JSVal> actionValue = obj->GetProperty("action");
485 if (actionValue->IsFunction()) {
486 auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionValue));
487 auto targetNode =
488 AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
489 if (popupParam) {
490 auto clickCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc),
491 node = targetNode](GestureEvent& info) {
492 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
493 ACE_SCORING_EVENT("secondaryButton.action");
494 PipelineContext::SetCallBackNode(node);
495 func->Execute(info);
496 };
497 properties.action = AceType::MakeRefPtr<NG::ClickEvent>(clickCallback);
498 }
499 }
500 properties.showButton = true;
501 if (popupParam) {
502 popupParam->SetSecondaryButtonProperties(properties);
503 }
504 }
505 }
506
ParseCustomPopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)507 void ParseCustomPopupParam(
508 const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
509 {
510 auto builderValue = popupObj->GetProperty("builder");
511 if (!builderValue->IsObject()) {
512 return;
513 }
514 if (!builderValue->IsFunction()) {
515 JSRef<JSObject> builderObj;
516 builderObj = JSRef<JSObject>::Cast(builderValue);
517 auto builder = builderObj->GetProperty("builder");
518 if (!builder->IsFunction()) {
519 return;
520 }
521 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
522 if (!builderFunc) {
523 return;
524 }
525 }
526 if (popupParam) {
527 popupParam->SetUseCustomComponent(true);
528 }
529
530 auto focusableValue = popupObj->GetProperty("focusable");
531 if (focusableValue->IsBoolean()) {
532 popupParam->SetFocusable(focusableValue->ToBoolean());
533 }
534
535 ParsePopupCommonParam(info, popupObj, popupParam);
536 }
537
ParseTipsParam(const JSRef<JSObject> & tipsObj,const RefPtr<PopupParam> & tipsParam)538 void ParseTipsParam(const JSRef<JSObject>& tipsObj, const RefPtr<PopupParam>& tipsParam)
539 {
540 CHECK_NULL_VOID(tipsParam);
541 auto appearingTimeVal = tipsObj->GetProperty("appearingTime");
542 if (appearingTimeVal->IsNumber()) {
543 auto appearingTime = appearingTimeVal->ToNumber<int32_t>();
544 if (appearingTime >= 0) {
545 tipsParam->SetAppearingTime(appearingTime);
546 }
547 }
548
549 auto disappearingTimeVal = tipsObj->GetProperty("disappearingTime");
550 if (disappearingTimeVal->IsNumber()) {
551 auto disappearingTime = disappearingTimeVal->ToNumber<int32_t>();
552 if (disappearingTime >= 0) {
553 tipsParam->SetDisappearingTime(disappearingTime);
554 }
555 }
556
557 auto appearingTimeWithContinuousOperationVal = tipsObj->GetProperty("appearingTimeWithContinuousOperation");
558 if (appearingTimeWithContinuousOperationVal->IsNumber()) {
559 auto appearingTimeWithContinuousOperation = appearingTimeWithContinuousOperationVal->ToNumber<int32_t>();
560 if (appearingTimeWithContinuousOperation >= 0) {
561 tipsParam->SetAppearingTimeWithContinuousOperation(appearingTimeWithContinuousOperation);
562 }
563 }
564
565 auto disappearingTimeWithContinuousOperationVal = tipsObj->GetProperty("disappearingTimeWithContinuousOperation");
566 if (disappearingTimeWithContinuousOperationVal->IsNumber()) {
567 auto disappearingTimeWithContinuousOperation = disappearingTimeWithContinuousOperationVal->ToNumber<int32_t>();
568 if (disappearingTimeWithContinuousOperation >= 0) {
569 tipsParam->SetDisappearingTimeWithContinuousOperation(disappearingTimeWithContinuousOperation);
570 }
571 }
572
573 auto enableArrowValue = tipsObj->GetProperty("enableArrow");
574 if (enableArrowValue->IsBoolean()) {
575 tipsParam->SetEnableArrow(enableArrowValue->ToBoolean());
576 }
577 tipsParam->SetBlockEvent(false);
578 tipsParam->SetTipsFlag(true);
579 }
580
ParseTipsArrowPositionParam(const JSRef<JSObject> & tipsObj,const RefPtr<PopupParam> & tipsParam)581 void ParseTipsArrowPositionParam(const JSRef<JSObject>& tipsObj, const RefPtr<PopupParam>& tipsParam)
582 {
583 CalcDimension offset;
584 auto arrowPointPosition = tipsObj->GetProperty("arrowPointPosition");
585 if (arrowPointPosition->IsString()) {
586 char* pEnd = nullptr;
587 auto arrowString = arrowPointPosition->ToString();
588 std::strtod(arrowString.c_str(), &pEnd);
589 if (pEnd != nullptr) {
590 if (std::strcmp(pEnd, "Start") == 0) {
591 offset = ARROW_ZERO_PERCENT_VALUE;
592 }
593 if (std::strcmp(pEnd, "Center") == 0) {
594 offset = ARROW_HALF_PERCENT_VALUE;
595 }
596 if (std::strcmp(pEnd, "End") == 0) {
597 offset = ARROW_ONE_HUNDRED_PERCENT_VALUE;
598 }
599 if (tipsParam) {
600 tipsParam->SetArrowOffset(offset);
601 }
602 }
603 }
604 }
605
ParseTipsArrowSizeParam(const JSRef<JSObject> & tipsObj,const RefPtr<PopupParam> & tipsParam)606 void ParseTipsArrowSizeParam(const JSRef<JSObject>& tipsObj, const RefPtr<PopupParam>& tipsParam)
607 {
608 auto arrowWidthVal = tipsObj->GetProperty("arrowWidth");
609 if (!arrowWidthVal->IsNull()) {
610 bool setError = true;
611 CalcDimension arrowWidth;
612 if (JSViewAbstract::ParseJsDimensionVp(arrowWidthVal, arrowWidth)) {
613 if (arrowWidth.Value() > 0 && arrowWidth.Unit() != DimensionUnit::PERCENT) {
614 tipsParam->SetArrowWidth(arrowWidth);
615 setError = false;
616 }
617 }
618 tipsParam->SetErrorArrowWidth(setError);
619 }
620
621 auto arrowHeightVal = tipsObj->GetProperty("arrowHeight");
622 if (!arrowHeightVal->IsNull()) {
623 bool setError = true;
624 CalcDimension arrowHeight;
625 if (JSViewAbstract::ParseJsDimensionVp(arrowHeightVal, arrowHeight)) {
626 if (arrowHeight.Value() > 0 && arrowHeight.Unit() != DimensionUnit::PERCENT) {
627 tipsParam->SetArrowHeight(arrowHeight);
628 setError = false;
629 }
630 }
631 tipsParam->SetErrorArrowHeight(setError);
632 }
633 }
634 #endif
635
ParseBindContextMenuShow(const JSCallbackInfo & info,NG::MenuParam & menuParam)636 uint32_t ParseBindContextMenuShow(const JSCallbackInfo& info, NG::MenuParam& menuParam)
637 {
638 size_t builderIndex = 0;
639 if (info[0]->IsBoolean()) {
640 menuParam.isShow = info[0]->ToBoolean();
641 menuParam.contextMenuRegisterType = NG::ContextMenuRegisterType::CUSTOM_TYPE;
642 menuParam.placement = Placement::BOTTOM_LEFT;
643 builderIndex = 1;
644 } else if (info[0]->IsObject()) {
645 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
646 menuParam.onStateChange = JSViewPopups::ParseDoubleBindCallback(info, callbackObj, "$value");
647 auto isShowObj = callbackObj->GetProperty("value");
648 if (isShowObj->IsBoolean()) {
649 menuParam.isShow = isShowObj->ToBoolean();
650 menuParam.contextMenuRegisterType = NG::ContextMenuRegisterType::CUSTOM_TYPE;
651 menuParam.placement = Placement::BOTTOM_LEFT;
652 builderIndex = 1;
653 }
654 }
655 return builderIndex;
656 }
657
ParseOverlayCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & onAppear,std::function<void ()> & onDisappear,std::function<void ()> & onWillAppear,std::function<void ()> & onWillDisappear,std::function<void (const int32_t & info)> & onWillDismiss)658 void JSViewAbstract::ParseOverlayCallback(const JSRef<JSObject>& paramObj, std::function<void()>& onAppear,
659 std::function<void()>& onDisappear, std::function<void()>& onWillAppear, std::function<void()>& onWillDisappear,
660 std::function<void(const int32_t& info)>& onWillDismiss)
661 {
662 auto showCallback = paramObj->GetProperty("onAppear");
663 auto dismissCallback = paramObj->GetProperty("onDisappear");
664 auto willShowCallback = paramObj->GetProperty("onWillAppear");
665 auto willDismissCallback = paramObj->GetProperty("onWillDisappear");
666 auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
667 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
668 if (showCallback->IsFunction()) {
669 RefPtr<JsFunction> jsFunc =
670 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(showCallback));
671 onAppear = [func = std::move(jsFunc), node = frameNode]() {
672 PipelineContext::SetCallBackNode(node);
673 func->Execute();
674 };
675 }
676 if (dismissCallback->IsFunction()) {
677 RefPtr<JsFunction> jsFunc =
678 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(dismissCallback));
679 onDisappear = [func = std::move(jsFunc), node = frameNode]() {
680 PipelineContext::SetCallBackNode(node);
681 func->Execute();
682 };
683 }
684 if (willShowCallback->IsFunction()) {
685 RefPtr<JsFunction> jsFunc =
686 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(willShowCallback));
687 onWillAppear = [func = std::move(jsFunc)]() { func->Execute(); };
688 }
689 if (willDismissCallback->IsFunction()) {
690 RefPtr<JsFunction> jsFunc =
691 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(willDismissCallback));
692 onWillDisappear = [func = std::move(jsFunc)]() { func->Execute(); };
693 }
694 if (onWillDismissFunc->IsFunction()) {
695 RefPtr<JsFunction> jsFunc =
696 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
697 onWillDismiss = [func = std::move(jsFunc), node = frameNode](const int32_t& info) {
698 ACE_SCORING_EVENT("contentCover.dismiss");
699 PipelineContext::SetCallBackNode(node);
700 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
701 objectTemplate->SetInternalFieldCount(1);
702 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
703 dismissObj->SetPropertyObject(
704 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissContentCover));
705 dismissObj->SetProperty<int32_t>("reason", info);
706 JSRef<JSVal> newJSVal = dismissObj;
707 func->ExecuteJS(1, &newJSVal);
708 };
709 }
710 }
711
ParseBindOptionParam(const JSCallbackInfo & info,size_t optionIndex)712 std::vector<NG::OptionParam> JSViewPopups::ParseBindOptionParam(const JSCallbackInfo& info, size_t optionIndex)
713 {
714 JSRef<JSVal> arg = info[optionIndex];
715 if (!arg->IsArray()) {
716 return std::vector<NG::OptionParam>();
717 }
718 auto paramArray = JSRef<JSArray>::Cast(arg);
719 auto paramArrayLength = paramArray->Length();
720 std::vector<NG::OptionParam> params(paramArrayLength);
721 // parse paramArray
722 for (size_t i = 0; i < paramArrayLength; ++i) {
723 if (!paramArray->GetValueAt(i)->IsObject()) {
724 return std::vector<NG::OptionParam>();
725 }
726 auto indexObject = JSRef<JSObject>::Cast(paramArray->GetValueAt(i));
727 JSViewAbstract::ParseJsString(indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE)),
728 params[i].value);
729 auto actionFunc = indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ACTION));
730 if (!actionFunc->IsFunction()) {
731 return params;
732 }
733 auto action = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionFunc));
734 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
735 // set onClick function
736 params[i].action = [func = std::move(action), context = info.GetExecutionContext(), node = targetNode]() {
737 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(context);
738 ACE_SCORING_EVENT("menu.action");
739 PipelineContext::SetCallBackNode(node);
740 if (func) {
741 func->Execute();
742 }
743 };
744 std::string iconPath;
745 if (JSViewAbstract::ParseJsMedia(indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ICON)), iconPath)) {
746 params[i].icon = iconPath;
747 }
748 if (indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::SYMBOL_ICON))->IsObject()) {
749 std::function<void(WeakPtr<NG::FrameNode>)> symbolApply;
750 JSViewAbstract::SetSymbolOptionApply(info, symbolApply,
751 indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::SYMBOL_ICON)));
752 params[i].symbol = symbolApply;
753 }
754 auto enabled = indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ENABLED));
755 if (enabled->IsBoolean()) {
756 params[i].enabled = enabled->ToBoolean();
757 }
758 }
759 return params;
760 }
761
ParseMenuBorderRadius(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)762 void JSViewPopups::ParseMenuBorderRadius(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
763 {
764 auto borderRadiusValue = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BORDER_RADIUS));
765 NG::BorderRadiusProperty menuBorderRadius;
766 CalcDimension borderRadius;
767 if (JSViewAbstract::ParseJsDimensionVp(borderRadiusValue, borderRadius)) {
768 if (GreatOrEqual(borderRadius.Value(), 0.0f)) {
769 menuBorderRadius.SetRadius(borderRadius);
770 menuBorderRadius.multiValued = false;
771 menuParam.borderRadius = menuBorderRadius;
772 };
773 } else if (borderRadiusValue->IsObject()) {
774 JSRef<JSObject> object = JSRef<JSObject>::Cast(borderRadiusValue);
775 CalcDimension topLeft;
776 CalcDimension topRight;
777 CalcDimension bottomLeft;
778 CalcDimension bottomRight;
779 bool hasSetBorderRadius =
780 JSViewAbstract::ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight);
781 if (LessNotEqual(topLeft.Value(), 0.0f)) {
782 topLeft.Reset();
783 }
784 if (LessNotEqual(topRight.Value(), 0.0f)) {
785 topRight.Reset();
786 }
787 if (LessNotEqual(bottomLeft.Value(), 0.0f)) {
788 bottomLeft.Reset();
789 }
790 if (LessNotEqual(bottomRight.Value(), 0.0f)) {
791 bottomRight.Reset();
792 }
793 auto isRtl = hasSetBorderRadius && AceApplicationInfo::GetInstance().IsRightToLeft();
794 menuBorderRadius.radiusTopLeft = isRtl ? topRight : topLeft;
795 menuBorderRadius.radiusTopRight = isRtl ? topLeft : topRight;
796 menuBorderRadius.radiusBottomLeft = isRtl ? bottomRight : bottomLeft;
797 menuBorderRadius.radiusBottomRight = isRtl ? bottomLeft : bottomRight;
798 menuBorderRadius.multiValued = true;
799 menuParam.borderRadius = menuBorderRadius;
800 }
801 }
802
ParseMenuArrowParam(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)803 void JSViewPopups::ParseMenuArrowParam(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
804 {
805 auto enableArrowValue = menuOptions->GetProperty("enableArrow");
806 if (enableArrowValue->IsBoolean()) {
807 menuParam.enableArrow = enableArrowValue->ToBoolean();
808 }
809
810 auto arrowOffset = menuOptions->GetProperty("arrowOffset");
811 CalcDimension offset;
812 if (JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset)) {
813 menuParam.arrowOffset = offset;
814 }
815
816 // if enableArrow is true and placement not set, set placement default value to top.
817 if (menuParam.enableArrow.has_value() && !menuParam.placement.has_value() && menuParam.enableArrow.value()) {
818 menuParam.placement = Placement::TOP;
819 }
820 }
821
ParseLayoutRegionMargin(const JSRef<JSVal> & jsValue,std::optional<CalcDimension> & calcDimension)822 void JSViewPopups::ParseLayoutRegionMargin(const JSRef<JSVal>& jsValue, std::optional<CalcDimension>& calcDimension)
823 {
824 CalcDimension dimension;
825 if (!JSViewAbstract::ParseJsDimensionVpNG(jsValue, dimension, true)) {
826 return;
827 }
828
829 if (dimension.IsNonNegative() && dimension.CalcValue().find("calc") == std::string::npos) {
830 calcDimension = dimension;
831 }
832 }
833
ParseMenuLayoutRegionMarginParam(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)834 void JSViewPopups::ParseMenuLayoutRegionMarginParam(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
835 {
836 auto marginVal = menuOptions->GetProperty("layoutRegionMargin");
837 if (!marginVal->IsObject()) {
838 return;
839 }
840
841 CommonCalcDimension commonCalcDimension;
842 auto object = JSRef<JSObject>::Cast(marginVal);
843 JSViewPopups::ParseLayoutRegionMargin(object->GetProperty("top"), commonCalcDimension.top);
844 JSViewPopups::ParseLayoutRegionMargin(object->GetProperty("bottom"), commonCalcDimension.bottom);
845 JSViewPopups::ParseLayoutRegionMargin(object->GetProperty("left"), commonCalcDimension.left);
846 JSViewPopups::ParseLayoutRegionMargin(object->GetProperty("right"), commonCalcDimension.right);
847
848 if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() ||
849 commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) {
850 menuParam.layoutRegionMargin = JSViewAbstract::GetLocalizedPadding(
851 commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right);
852 }
853 }
854
ParseMenuBlurStyleOption(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)855 void JSViewPopups::ParseMenuBlurStyleOption(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
856 {
857 auto blurStyle = menuOptions->GetProperty("backgroundBlurStyleOptions");
858 if (blurStyle->IsObject()) {
859 if (!menuParam.blurStyleOption.has_value()) {
860 menuParam.blurStyleOption.emplace();
861 }
862 JSViewAbstract::ParseBlurStyleOption(blurStyle, menuParam.blurStyleOption.value());
863 }
864 }
865
ParseMenuEffectOption(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)866 void JSViewPopups::ParseMenuEffectOption(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
867 {
868 auto effectOption = menuOptions->GetProperty("backgroundEffect");
869 if (effectOption->IsObject()) {
870 if (!menuParam.effectOption.has_value()) {
871 menuParam.effectOption.emplace();
872 }
873 JSViewAbstract::ParseEffectOption(effectOption, menuParam.effectOption.value());
874 }
875 }
876
ParseMenuHapticFeedbackMode(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)877 void JSViewPopups::ParseMenuHapticFeedbackMode(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
878 {
879 auto hapticFeedbackMode = menuOptions->GetProperty("hapticFeedbackMode");
880 if (!hapticFeedbackMode->IsNumber()) {
881 return;
882 }
883 if (hapticFeedbackMode->ToNumber<int32_t>() == HAPTIC_FEEDBACK_MODE_ENABLED) {
884 menuParam.hapticFeedbackMode = HapticFeedbackMode::ENABLED;
885 } else if (hapticFeedbackMode->ToNumber<int32_t>() == HAPTIC_FEEDBACK_MODE_AUTO) {
886 menuParam.hapticFeedbackMode = HapticFeedbackMode::AUTO;
887 }
888 }
889
GetMenuShowInSubwindow(NG::MenuParam & menuParam)890 void JSViewPopups::GetMenuShowInSubwindow(NG::MenuParam& menuParam)
891 {
892 menuParam.isShowInSubWindow = false;
893 auto pipeline = PipelineBase::GetCurrentContext();
894 CHECK_NULL_VOID(pipeline);
895 auto theme = pipeline->GetTheme<SelectTheme>();
896 CHECK_NULL_VOID(theme);
897 menuParam.isShowInSubWindow = theme->GetExpandDisplay();
898 }
899
ParseMenuParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)900 void JSViewPopups::ParseMenuParam(
901 const JSCallbackInfo& info, const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
902 {
903 auto offsetVal = menuOptions->GetProperty("offset");
904 if (offsetVal->IsObject()) {
905 auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
906 JSRef<JSVal> xVal = offsetObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
907 JSRef<JSVal> yVal = offsetObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
908 CalcDimension dx;
909 CalcDimension dy;
910 if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
911 menuParam.positionOffset.SetX(dx.ConvertToPx());
912 }
913 if (JSViewAbstract::ParseJsDimensionVp(yVal, dy)) {
914 menuParam.positionOffset.SetY(dy.ConvertToPx());
915 }
916 }
917
918 auto placementValue = menuOptions->GetProperty("placement");
919 if (placementValue->IsNumber()) {
920 auto placement = placementValue->ToNumber<int32_t>();
921 if (placement >= 0 && placement < static_cast<int32_t>(Placement::NONE)) {
922 menuParam.placement = static_cast<Placement>(placement);
923 }
924 }
925
926 auto enableHoverModeValue = menuOptions->GetProperty("enableHoverMode");
927 if (enableHoverModeValue->IsBoolean()) {
928 menuParam.enableHoverMode = enableHoverModeValue->ToBoolean();
929 }
930
931 auto backgroundColorValue = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BACKGROUND_COLOR));
932 Color backgroundColor;
933 if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor)) {
934 menuParam.backgroundColor = backgroundColor;
935 }
936
937 auto backgroundBlurStyle = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BACKGROUND_BLUR_STYLE));
938 if (backgroundBlurStyle->IsNumber()) {
939 auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>();
940 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
941 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
942 menuParam.backgroundBlurStyle = blurStyle;
943 }
944 }
945 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
946 auto onAppearValue = menuOptions->GetProperty("onAppear");
947 if (onAppearValue->IsFunction()) {
948 RefPtr<JsFunction> jsOnAppearFunc =
949 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAppearValue));
950 auto onAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAppearFunc), node = frameNode]() {
951 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
952 ACE_SCORING_EVENT("onAppear");
953 PipelineContext::SetCallBackNode(node);
954 func->Execute();
955 };
956 menuParam.onAppear = std::move(onAppear);
957 }
958
959 auto onDisappearValue = menuOptions->GetProperty("onDisappear");
960 if (onDisappearValue->IsFunction()) {
961 RefPtr<JsFunction> jsOnDisAppearFunc =
962 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDisappearValue));
963 auto onDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDisAppearFunc),
964 node = frameNode]() {
965 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
966 ACE_SCORING_EVENT("onDisappear");
967 PipelineContext::SetCallBackNode(node);
968 func->Execute();
969 };
970 menuParam.onDisappear = std::move(onDisappear);
971 }
972 auto aboutToAppearValue = menuOptions->GetProperty("aboutToAppear");
973 if (aboutToAppearValue->IsFunction()) {
974 RefPtr<JsFunction> jsAboutToAppearFunc =
975 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(aboutToAppearValue));
976 auto aboutToAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToAppearFunc),
977 node = frameNode]() {
978 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
979 ACE_SCORING_EVENT("aboutToAppear");
980 PipelineContext::SetCallBackNode(node);
981 func->Execute();
982 };
983 menuParam.aboutToAppear = std::move(aboutToAppear);
984 }
985
986 auto aboutToDisAppearValue = menuOptions->GetProperty("aboutToDisappear");
987 if (aboutToDisAppearValue->IsFunction()) {
988 RefPtr<JsFunction> jsAboutToDisAppearFunc =
989 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(aboutToDisAppearValue));
990 auto aboutToDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToDisAppearFunc),
991 node = frameNode]() {
992 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
993 ACE_SCORING_EVENT("aboutToDisappear");
994 PipelineContext::SetCallBackNode(node);
995 func->Execute();
996 };
997 menuParam.aboutToDisappear = std::move(aboutToDisappear);
998 }
999
1000 auto menuTransition = menuOptions->GetProperty("transition");
1001 menuParam.hasTransitionEffect = false;
1002 if (menuTransition->IsObject()) {
1003 auto obj = JSRef<JSObject>::Cast(menuTransition);
1004 menuParam.hasTransitionEffect = true;
1005 menuParam.transition = JSViewAbstract::ParseChainedTransition(obj, info.GetExecutionContext());
1006 }
1007
1008 JSRef<JSVal> showInSubWindowValue = menuOptions->GetProperty("showInSubWindow");
1009 JSViewPopups::GetMenuShowInSubwindow(menuParam);
1010 if (menuParam.isShowInSubWindow) {
1011 if (showInSubWindowValue->IsBoolean()) {
1012 menuParam.isShowInSubWindow = showInSubWindowValue->ToBoolean();
1013 }
1014 }
1015 JSViewPopups::ParseMenuArrowParam(menuOptions, menuParam);
1016 JSViewPopups::ParseMenuBorderRadius(menuOptions, menuParam);
1017 JSViewPopups::ParseMenuLayoutRegionMarginParam(menuOptions, menuParam);
1018 JSViewPopups::ParseMenuBlurStyleOption(menuOptions, menuParam);
1019 JSViewPopups::ParseMenuEffectOption(menuOptions, menuParam);
1020 JSViewPopups::ParseMenuHapticFeedbackMode(menuOptions, menuParam);
1021 }
1022
ParseBindOptionParam(const JSCallbackInfo & info,NG::MenuParam & menuParam,size_t optionIndex)1023 void JSViewPopups::ParseBindOptionParam(const JSCallbackInfo& info, NG::MenuParam& menuParam, size_t optionIndex)
1024 {
1025 if (!info[optionIndex]->IsObject()) {
1026 return;
1027 }
1028 auto menuOptions = JSRef<JSObject>::Cast(info[optionIndex]);
1029 JSViewAbstract::ParseJsString(menuOptions->GetProperty("title"), menuParam.title);
1030 JSViewPopups::ParseMenuParam(info, menuOptions, menuParam);
1031 }
1032
ParseAnimationScaleArray(const JSRef<JSArray> & scaleArray,MenuPreviewAnimationOptions & options)1033 void ParseAnimationScaleArray(const JSRef<JSArray>& scaleArray, MenuPreviewAnimationOptions& options)
1034 {
1035 constexpr int scaleArraySize = 2;
1036 if (scaleArray->Length() == scaleArraySize) {
1037 auto scalePropertyFrom = scaleArray->GetValueAt(0);
1038 if (scalePropertyFrom->IsNumber()) {
1039 auto scaleFrom = scalePropertyFrom->ToNumber<float>();
1040 options.scaleFrom = LessOrEqual(scaleFrom, 0.0) ? -1.0f : scaleFrom;
1041 }
1042 auto scalePropertyTo = scaleArray->GetValueAt(1);
1043 if (scalePropertyTo->IsNumber()) {
1044 auto scaleTo = scalePropertyTo->ToNumber<float>();
1045 options.scaleTo = LessOrEqual(scaleTo, 0.0) ? -1.0f : scaleTo;
1046 }
1047 }
1048 }
1049
ParseContentPreviewAnimationOptionsParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuContentOptions,NG::MenuParam & menuParam)1050 void ParseContentPreviewAnimationOptionsParam(const JSCallbackInfo& info, const JSRef<JSObject>& menuContentOptions,
1051 NG::MenuParam& menuParam)
1052 {
1053 menuParam.previewAnimationOptions.scaleFrom = -1.0f;
1054 menuParam.previewAnimationOptions.scaleTo = -1.0f;
1055
1056 auto animationOptions = menuContentOptions->GetProperty("previewAnimationOptions");
1057 if (!animationOptions->IsEmpty() && animationOptions->IsObject()) {
1058 auto animationOptionsObj = JSRef<JSObject>::Cast(animationOptions);
1059 auto scaleProperty = animationOptionsObj->GetProperty("scale");
1060 if (!scaleProperty->IsEmpty() && scaleProperty->IsArray()) {
1061 JSRef<JSArray> scaleArray = JSRef<JSArray>::Cast(scaleProperty);
1062 ParseAnimationScaleArray(scaleArray, menuParam.previewAnimationOptions);
1063 }
1064 auto previewTransition = animationOptionsObj->GetProperty("transition");
1065 menuParam.hasPreviewTransitionEffect = false;
1066 if (previewTransition->IsObject()) {
1067 auto obj = JSRef<JSObject>::Cast(previewTransition);
1068 menuParam.hasPreviewTransitionEffect = true;
1069 menuParam.previewTransition = JSViewAbstract::ParseChainedTransition(obj, info.GetExecutionContext());
1070 }
1071 if (menuParam.previewMode != MenuPreviewMode::CUSTOM ||
1072 menuParam.hasPreviewTransitionEffect || menuParam.hasTransitionEffect ||
1073 menuParam.contextMenuRegisterType == NG::ContextMenuRegisterType::CUSTOM_TYPE) {
1074 return;
1075 }
1076 auto hoverScaleProperty = animationOptionsObj->GetProperty("hoverScale");
1077 menuParam.isShowHoverImage = false;
1078 menuParam.hoverImageAnimationOptions.scaleFrom = -1.0f;
1079 menuParam.hoverImageAnimationOptions.scaleTo = -1.0f;
1080 if (!hoverScaleProperty->IsEmpty() && hoverScaleProperty->IsArray()) {
1081 JSRef<JSArray> hoverScaleArray = JSRef<JSArray>::Cast(hoverScaleProperty);
1082 ParseAnimationScaleArray(hoverScaleArray, menuParam.hoverImageAnimationOptions);
1083 menuParam.isShowHoverImage = true;
1084 }
1085 }
1086 }
1087
ParsePreviewBorderRadiusParam(const JSRef<JSObject> & menuContentOptions,NG::MenuParam & menuParam)1088 void ParsePreviewBorderRadiusParam(const JSRef<JSObject>& menuContentOptions, NG::MenuParam& menuParam)
1089 {
1090 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_SIXTEEN)) {
1091 return;
1092 }
1093 auto previewBorderRadiusValue = menuContentOptions->GetProperty("previewBorderRadius");
1094 NG::BorderRadiusProperty previewBorderRadius;
1095 JSViewAbstract::ParseBorderRadius(previewBorderRadiusValue, previewBorderRadius);
1096 menuParam.previewBorderRadius = previewBorderRadius;
1097 }
1098
ParseBindContentOptionParam(const JSCallbackInfo & info,const JSRef<JSVal> & args,NG::MenuParam & menuParam,std::function<void ()> & previewBuildFunc)1099 void ParseBindContentOptionParam(const JSCallbackInfo& info, const JSRef<JSVal>& args, NG::MenuParam& menuParam,
1100 std::function<void()>& previewBuildFunc)
1101 {
1102 if (!args->IsObject()) {
1103 return;
1104 }
1105 auto menuContentOptions = JSRef<JSObject>::Cast(args);
1106 JSViewPopups::ParseMenuParam(info, menuContentOptions, menuParam);
1107 RefPtr<JsFunction> previewBuilderFunc;
1108 auto preview = menuContentOptions->GetProperty("preview");
1109 if (!preview->IsFunction() && !preview->IsNumber()) {
1110 return;
1111 }
1112
1113 if (preview->IsNumber()) {
1114 if (preview->ToNumber<int32_t>() == 1) {
1115 menuParam.previewMode = MenuPreviewMode::IMAGE;
1116 ParseContentPreviewAnimationOptionsParam(info, menuContentOptions, menuParam);
1117 ParsePreviewBorderRadiusParam(menuContentOptions, menuParam);
1118 }
1119 } else {
1120 previewBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(preview));
1121 CHECK_NULL_VOID(previewBuilderFunc);
1122 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1123 previewBuildFunc = [execCtx = info.GetExecutionContext(), func = std::move(previewBuilderFunc),
1124 node = frameNode]() {
1125 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1126 ACE_SCORING_EVENT("BuildContextMenuPreviwer");
1127 PipelineContext::SetCallBackNode(node);
1128 func->Execute();
1129 };
1130 menuParam.previewMode = MenuPreviewMode::CUSTOM;
1131 ParseContentPreviewAnimationOptionsParam(info, menuContentOptions, menuParam);
1132 ParsePreviewBorderRadiusParam(menuContentOptions, menuParam);
1133 }
1134 }
1135
1136 #ifndef WEARABLE_PRODUCT
JsBindPopup(const JSCallbackInfo & info)1137 void JSViewAbstract::JsBindPopup(const JSCallbackInfo& info)
1138 {
1139 if (info.Length() < PARAMETER_LENGTH_SECOND) {
1140 return;
1141 }
1142 if ((!info[NUM_ZERO]->IsBoolean() && !info[NUM_ZERO]->IsObject()) || !info[NUM_FIRST]->IsObject()) {
1143 return;
1144 }
1145 auto popupParam = AceType::MakeRefPtr<PopupParam>();
1146 // Set IsShow to popupParam
1147 if (info[NUM_ZERO]->IsBoolean()) {
1148 popupParam->SetIsShow(info[NUM_ZERO]->ToBoolean());
1149 } else {
1150 JSRef<JSObject> showObj = JSRef<JSObject>::Cast(info[NUM_ZERO]);
1151 auto callback = JSViewPopups::ParseDoubleBindCallback(info, showObj, "$value");
1152 popupParam->SetDoubleBindCallback(std::move(callback));
1153 popupParam->SetIsShow(showObj->GetProperty("value")->ToBoolean());
1154 }
1155 // Set popup to popupParam
1156 auto popupObj = JSRef<JSObject>::Cast(info[NUM_FIRST]);
1157 SetPopupDismiss(info, popupObj, popupParam);
1158 if (popupObj->GetProperty("message")->IsString()) {
1159 ParsePopupParam(info, popupObj, popupParam); // Parse PopupOptions param
1160 ViewAbstractModel::GetInstance()->BindPopup(popupParam, nullptr);
1161 } else if (!popupObj->GetProperty("builder").IsEmpty()) {
1162 ParseCustomPopupParam(info, popupObj, popupParam); // Parse CustomPopupOptions param
1163 auto builderValue = popupObj->GetProperty("builder");
1164 auto builder = builderValue;
1165 if (!builderValue->IsObject()) {
1166 return;
1167 }
1168 if (!builderValue->IsFunction()) {
1169 JSRef<JSObject> builderObj;
1170 builderObj = JSRef<JSObject>::Cast(builderValue);
1171 builder = builderObj->GetProperty("builder");
1172 if (!builder->IsFunction()) {
1173 return;
1174 }
1175 }
1176 if (popupParam->IsShow() && !IsPopupCreated()) {
1177 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1178 CHECK_NULL_VOID(builderFunc);
1179 ViewStackModel::GetInstance()->NewScope();
1180 builderFunc->Execute();
1181 auto customNode = ViewStackModel::GetInstance()->Finish();
1182 ViewAbstractModel::GetInstance()->BindPopup(popupParam, customNode);
1183 } else {
1184 ViewAbstractModel::GetInstance()->BindPopup(popupParam, nullptr);
1185 }
1186 } else {
1187 return;
1188 }
1189 }
1190
JsBindTips(const JSCallbackInfo & info)1191 void JSViewAbstract::JsBindTips(const JSCallbackInfo& info)
1192 {
1193 if (info.Length() < PARAMETER_LENGTH_SECOND || (!info[NUM_ZERO]->IsString() && !info[NUM_ZERO]->IsObject()) ||
1194 !info[NUM_FIRST]->IsObject()) {
1195 return;
1196 }
1197 auto tipsParam = AceType::MakeRefPtr<PopupParam>();
1198 CHECK_NULL_VOID(tipsParam);
1199 // Set message to tipsParam
1200 tipsParam->SetMessage(info[0]->ToString());
1201 // Set bindTipsOptions to tipsParam
1202 auto tipsObj = JSRef<JSObject>::Cast(info[1]);
1203 // Parse bindTipsOptions param
1204 ParseTipsParam(tipsObj, tipsParam);
1205 ParseTipsArrowPositionParam(tipsObj, tipsParam);
1206 ParseTipsArrowSizeParam(tipsObj, tipsParam);
1207 ViewAbstractModel::GetInstance()->BindTips(tipsParam);
1208 }
1209
SetPopupDismiss(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)1210 void JSViewAbstract::SetPopupDismiss(
1211 const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
1212 {
1213 auto onWillDismissFunc = popupObj->GetProperty("onWillDismiss");
1214 if (onWillDismissFunc->IsBoolean()) {
1215 bool onWillDismissBool = onWillDismissFunc->ToBoolean();
1216 popupParam->SetInteractiveDismiss(onWillDismissBool);
1217 popupParam->SetOnWillDismiss(nullptr);
1218 if (onWillDismissBool) {
1219 TAG_LOGI(AceLogTag::ACE_FORM, "popup register onWillDismiss");
1220 }
1221 } else if (onWillDismissFunc->IsFunction()) {
1222 auto onWillDismissCallback = ParsePopupCallback(info, popupObj);
1223 popupParam->SetOnWillDismiss(std::move(onWillDismissCallback));
1224 popupParam->SetInteractiveDismiss(true);
1225 if (onWillDismissCallback != nullptr) {
1226 TAG_LOGI(AceLogTag::ACE_FORM, "popup register onWillDismiss");
1227 }
1228 }
1229 }
1230
ParsePopupCallback(const JSCallbackInfo & info,const JSRef<JSObject> & paramObj)1231 PopupOnWillDismiss JSViewAbstract::ParsePopupCallback(const JSCallbackInfo& info, const JSRef<JSObject>& paramObj)
1232 {
1233 auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
1234 if (!onWillDismissFunc->IsFunction()) {
1235 return PopupOnWillDismiss();
1236 }
1237 RefPtr<JsFunction> jsFunc =
1238 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
1239 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1240 auto onWillDismiss = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
1241 node = frameNode](int32_t reason) {
1242 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1243 ACE_SCORING_EVENT("Bindpopup.dismiss");
1244 PipelineContext::SetCallBackNode(node);
1245
1246 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
1247 objectTemplate->SetInternalFieldCount(ON_WILL_DISMISS_FIELD_COUNT);
1248 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
1249 dismissObj->SetPropertyObject("dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissPopup));
1250 dismissObj->SetProperty<int32_t>("reason", reason);
1251 JSRef<JSVal> newJSVal = dismissObj;
1252 func->ExecuteJS(1, &newJSVal);
1253 };
1254 return onWillDismiss;
1255 }
1256
JsDismissPopup(panda::JsiRuntimeCallInfo * runtimeCallInfo)1257 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissPopup(panda::JsiRuntimeCallInfo* runtimeCallInfo)
1258 {
1259 ViewAbstractModel::GetInstance()->DismissPopup();
1260 return JSValueRef::Undefined(runtimeCallInfo->GetVM());
1261 }
1262
ParseContentPopupCommonParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)1263 void JSViewAbstract::ParseContentPopupCommonParam(
1264 const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
1265 {
1266 CHECK_EQUAL_VOID(popupObj->IsEmpty(), true);
1267 CHECK_NULL_VOID(popupParam);
1268 int32_t targetId = StringUtils::StringToInt(popupParam->GetTargetId(), -1);
1269 if (targetId < 0) {
1270 TAG_LOGE(AceLogTag::ACE_DIALOG, "The targetId is error.");
1271 return;
1272 }
1273 auto targetNode = ElementRegister::GetInstance()->GetSpecificItemById<NG::FrameNode>(targetId);
1274 if (!targetNode) {
1275 TAG_LOGE(AceLogTag::ACE_DIALOG, "The targetNode does not exist.");
1276 return;
1277 }
1278 SetPopupDismiss(info, popupObj, popupParam);
1279 ParsePopupCommonParam(info, popupObj, popupParam, targetNode);
1280 auto focusableValue = popupObj->GetProperty("focusable");
1281 if (focusableValue->IsBoolean()) {
1282 popupParam->SetFocusable(focusableValue->ToBoolean());
1283 }
1284 }
1285
OpenPopup(const RefPtr<PopupParam> & param,const RefPtr<NG::UINode> & customNode)1286 int32_t JSViewAbstract::OpenPopup(const RefPtr<PopupParam>& param, const RefPtr<NG::UINode>& customNode)
1287 {
1288 return ViewAbstractModel::GetInstance()->OpenPopup(param, customNode);
1289 }
1290
UpdatePopup(const RefPtr<PopupParam> & param,const RefPtr<NG::UINode> & customNode)1291 int32_t JSViewAbstract::UpdatePopup(const RefPtr<PopupParam>& param, const RefPtr<NG::UINode>& customNode)
1292 {
1293 return ViewAbstractModel::GetInstance()->UpdatePopup(param, customNode);
1294 }
1295
ClosePopup(const RefPtr<NG::UINode> & customNode)1296 int32_t JSViewAbstract::ClosePopup(const RefPtr<NG::UINode>& customNode)
1297 {
1298 return ViewAbstractModel::GetInstance()->ClosePopup(customNode);
1299 }
1300
GetPopupParam(RefPtr<PopupParam> & param,const RefPtr<NG::UINode> & customNode)1301 int32_t JSViewAbstract::GetPopupParam(RefPtr<PopupParam>& param, const RefPtr<NG::UINode>& customNode)
1302 {
1303 return ViewAbstractModel::GetInstance()->GetPopupParam(param, customNode);
1304 }
1305
JsBindContextMenu(const JSCallbackInfo & info)1306 void JSViewAbstract::JsBindContextMenu(const JSCallbackInfo& info)
1307 {
1308 NG::MenuParam menuParam;
1309 // Check the parameters
1310 if (info.Length() <= PARAMETER_LENGTH_ZERO) {
1311 return;
1312 }
1313 size_t builderIndex = ParseBindContextMenuShow(info, menuParam);
1314 if (!info[builderIndex]->IsObject()) {
1315 return;
1316 }
1317
1318 JSRef<JSObject> menuObj = JSRef<JSObject>::Cast(info[builderIndex]);
1319 auto builder = menuObj->GetProperty("builder");
1320 if (!builder->IsFunction()) {
1321 return;
1322 }
1323 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1324 CHECK_NULL_VOID(builderFunc);
1325
1326 ResponseType responseType = ResponseType::LONG_PRESS;
1327 if (!info[NUM_ZERO]->IsBoolean() && info.Length() >= PARAMETER_LENGTH_SECOND && info[NUM_FIRST]->IsNumber()) {
1328 auto response = info[NUM_FIRST]->ToNumber<int32_t>();
1329 responseType = static_cast<ResponseType>(response);
1330 }
1331 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1332 std::function<void()> buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
1333 node = frameNode]() {
1334 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1335 ACE_SCORING_EVENT("BuildContextMenu");
1336 PipelineContext::SetCallBackNode(node);
1337 func->Execute();
1338 };
1339
1340 menuParam.previewMode = MenuPreviewMode::NONE;
1341 std::function<void()> previewBuildFunc = nullptr;
1342 if (info.Length() >= PARAMETER_LENGTH_THIRD && info[NUM_SECOND]->IsObject()) {
1343 ParseBindContentOptionParam(info, info[NUM_SECOND], menuParam, previewBuildFunc);
1344 }
1345 if (responseType != ResponseType::LONG_PRESS) {
1346 menuParam.previewMode = MenuPreviewMode::NONE;
1347 menuParam.isShowHoverImage = false;
1348 menuParam.menuBindType = MenuBindingType::RIGHT_CLICK;
1349 }
1350 // arrow is disabled for contextMenu with preview
1351 if (menuParam.previewMode != MenuPreviewMode::NONE) {
1352 menuParam.enableArrow = false;
1353 }
1354 menuParam.type = NG::MenuType::CONTEXT_MENU;
1355 ViewAbstractModel::GetInstance()->BindContextMenu(responseType, buildFunc, menuParam, previewBuildFunc);
1356 ViewAbstractModel::GetInstance()->BindDragWithContextMenuParams(menuParam);
1357 }
1358 #endif
1359
JsBindContentCover(const JSCallbackInfo & info)1360 void JSViewAbstract::JsBindContentCover(const JSCallbackInfo& info)
1361 {
1362 // parse isShow
1363 DoubleBindCallback callback = nullptr;
1364 bool isShow = ParseSheetIsShow(info, "ContentCover", callback);
1365
1366 // parse builder
1367 if (!info[NUM_FIRST]->IsObject()) {
1368 return;
1369 }
1370 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[NUM_FIRST]);
1371 auto builder = obj->GetProperty("builder");
1372 if (!builder->IsFunction()) {
1373 return;
1374 }
1375 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1376 CHECK_NULL_VOID(builderFunc);
1377 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1378 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
1379 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1380 ACE_SCORING_EVENT("BindContentCover");
1381 PipelineContext::SetCallBackNode(node);
1382 func->Execute();
1383 };
1384
1385 // parse ModalTransition
1386 NG::ModalStyle modalStyle;
1387 modalStyle.modalTransition = NG::ModalTransition::DEFAULT;
1388 std::function<void()> onShowCallback;
1389 std::function<void()> onDismissCallback;
1390 std::function<void()> onWillShowCallback;
1391 std::function<void()> onWillDismissCallback;
1392 NG::ContentCoverParam contentCoverParam;
1393 std::function<void(const int32_t&)> onWillDismissFunc;
1394 if (info.Length() == PARAMETER_LENGTH_THIRD) {
1395 if (info[NUM_SECOND]->IsObject()) {
1396 ParseOverlayCallback(info[NUM_SECOND], onShowCallback, onDismissCallback, /* 2:args index */
1397 onWillShowCallback, onWillDismissCallback, onWillDismissFunc);
1398 ParseModalStyle(info[NUM_SECOND], modalStyle);
1399 contentCoverParam.onWillDismiss = std::move(onWillDismissFunc);
1400 ParseModalTransitonEffect(info[NUM_SECOND], contentCoverParam, /* 2:args index */
1401 info.GetExecutionContext());
1402 } else if (info[NUM_SECOND]->IsNumber()) {
1403 auto transitionNumber = info[NUM_SECOND]->ToNumber<int32_t>();
1404 if (transitionNumber >= TRANSITION_NUM_ZERO && transitionNumber <= TRANSITION_NUM_TWO) {
1405 modalStyle.modalTransition = static_cast<NG::ModalTransition>(transitionNumber);
1406 }
1407 }
1408 }
1409 ViewAbstractModel::GetInstance()->BindContentCover(isShow, std::move(callback), std::move(buildFunc), modalStyle,
1410 std::move(onShowCallback), std::move(onDismissCallback), std::move(onWillShowCallback),
1411 std::move(onWillDismissCallback), contentCoverParam);
1412 }
1413
ParseModalTransitonEffect(const JSRef<JSObject> & paramObj,NG::ContentCoverParam & contentCoverParam,const JSExecutionContext & context)1414 void JSViewAbstract::ParseModalTransitonEffect(
1415 const JSRef<JSObject>& paramObj, NG::ContentCoverParam& contentCoverParam, const JSExecutionContext& context)
1416 {
1417 auto transitionEffectValue = paramObj->GetProperty("transition");
1418 if (transitionEffectValue->IsObject()) {
1419 JSRef<JSObject> obj = JSRef<JSObject>::Cast(transitionEffectValue);
1420 contentCoverParam.transitionEffect = ParseChainedTransition(obj, context);
1421 }
1422 }
1423
ParseModalStyle(const JSRef<JSObject> & paramObj,NG::ModalStyle & modalStyle)1424 void JSViewAbstract::ParseModalStyle(const JSRef<JSObject>& paramObj, NG::ModalStyle& modalStyle)
1425 {
1426 auto modalTransition = paramObj->GetProperty("modalTransition");
1427 auto backgroundColor = paramObj->GetProperty("backgroundColor");
1428 if (modalTransition->IsNumber()) {
1429 auto transitionNumber = modalTransition->ToNumber<int32_t>();
1430 if (transitionNumber >= TRANSITION_NUM_ZERO && transitionNumber <= TRANSITION_NUM_TWO) {
1431 modalStyle.modalTransition = static_cast<NG::ModalTransition>(transitionNumber);
1432 }
1433 }
1434 Color color;
1435 if (ParseJsColor(backgroundColor, color)) {
1436 modalStyle.backgroundColor = color;
1437 }
1438 }
1439
ParseSheetIsShow(const JSCallbackInfo & info,const std::string & name,std::function<void (const std::string &)> & callback)1440 bool JSViewAbstract::ParseSheetIsShow(const JSCallbackInfo& info, const std::string& name,
1441 std::function<void(const std::string&)>& callback)
1442 {
1443 bool isShow = false;
1444 if (info[0]->IsBoolean()) {
1445 isShow = info[0]->ToBoolean();
1446 } else if (info[0]->IsObject()) {
1447 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
1448 auto isShowObj = callbackObj->GetProperty("value");
1449 isShow = isShowObj->IsBoolean() ? isShowObj->ToBoolean() : false;
1450 callback = JSViewPopups::ParseDoubleBindCallback(info, callbackObj, "changeEvent");
1451 if (!callback && Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
1452 TAG_LOGD(AceLogTag::ACE_SHEET, "Try %{public}s another parsing", name.c_str());
1453 callback = JSViewPopups::ParseDoubleBindCallback(info, callbackObj, "$value");
1454 }
1455 }
1456 TAG_LOGD(AceLogTag::ACE_SHEET, "%{public}s get isShow is: %{public}d", name.c_str(), isShow);
1457 return isShow;
1458 }
1459
JsBindSheet(const JSCallbackInfo & info)1460 void JSViewAbstract::JsBindSheet(const JSCallbackInfo& info)
1461 {
1462 // parse isShow and builder
1463 DoubleBindCallback callback = nullptr;
1464 bool isShow = ParseSheetIsShow(info, "Sheet", callback);
1465 if (!info[NUM_FIRST]->IsObject())
1466 return;
1467 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[NUM_FIRST]);
1468 auto builder = obj->GetProperty("builder");
1469 if (!builder->IsFunction())
1470 return;
1471 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1472 CHECK_NULL_VOID(builderFunc);
1473 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1474 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
1475 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1476 ACE_SCORING_EVENT("BindSheet");
1477 PipelineContext::SetCallBackNode(node);
1478 func->Execute();
1479 };
1480 // parse SheetStyle and callbacks
1481 NG::SheetStyle sheetStyle;
1482 sheetStyle.sheetHeight.sheetMode = NG::SheetMode::LARGE;
1483 sheetStyle.showDragBar = true;
1484 sheetStyle.showCloseIcon = true;
1485 sheetStyle.showInPage = false;
1486 std::function<void()> onAppearCallback;
1487 std::function<void()> onDisappearCallback;
1488 std::function<void()> onWillAppearCallback;
1489 std::function<void()> onWillDisappearCallback ;
1490 std::function<void()> shouldDismissFunc;
1491 std::function<void(const int32_t)> onWillDismissCallback;
1492 std::function<void(const float)> onHeightDidChangeCallback;
1493 std::function<void(const float)> onDetentsDidChangeCallback;
1494 std::function<void(const float)> onWidthDidChangeCallback;
1495 std::function<void(const float)> onTypeDidChangeCallback;
1496 std::function<void()> titleBuilderFunction;
1497 std::function<void()> sheetSpringBackFunc;
1498 if (info.Length() == PARAMETER_LENGTH_THIRD && info[NUM_SECOND]->IsObject()) {
1499 ParseSheetCallback(info[NUM_SECOND], onAppearCallback, onDisappearCallback, shouldDismissFunc,
1500 onWillDismissCallback, onWillAppearCallback, onWillDisappearCallback, onHeightDidChangeCallback,
1501 onDetentsDidChangeCallback, onWidthDidChangeCallback, onTypeDidChangeCallback, sheetSpringBackFunc);
1502 ParseSheetStyle(info[NUM_SECOND], sheetStyle);
1503 ParseSheetTitle(info[NUM_SECOND], sheetStyle, titleBuilderFunction);
1504 }
1505 ViewAbstractModel::GetInstance()->BindSheet(isShow, std::move(callback), std::move(buildFunc),
1506 std::move(titleBuilderFunction), sheetStyle, std::move(onAppearCallback), std::move(onDisappearCallback),
1507 std::move(shouldDismissFunc), std::move(onWillDismissCallback), std::move(onWillAppearCallback),
1508 std::move(onWillDisappearCallback), std::move(onHeightDidChangeCallback), std::move(onDetentsDidChangeCallback),
1509 std::move(onWidthDidChangeCallback), std::move(onTypeDidChangeCallback), std::move(sheetSpringBackFunc));
1510 }
1511
ParseSheetEffectEdge(const JSRef<JSObject> & paramObj)1512 NG::SheetEffectEdge JSViewAbstract::ParseSheetEffectEdge(const JSRef<JSObject>& paramObj)
1513 {
1514 auto sheetEffectEdge = static_cast<int32_t>(NG::SheetEffectEdge::ALL);
1515 JSRef<JSVal> effectEdgedParam = paramObj->GetProperty("effectEdge");
1516 if (effectEdgedParam->IsNull() || effectEdgedParam->IsUndefined() ||
1517 !JSViewAbstract::ParseJsInt32(effectEdgedParam, sheetEffectEdge) ||
1518 sheetEffectEdge < static_cast<int32_t>(NG::SheetEffectEdge::NONE) ||
1519 sheetEffectEdge > static_cast<int32_t>(NG::SheetEffectEdge::END)) {
1520 sheetEffectEdge = static_cast<int32_t>(NG::SheetEffectEdge::ALL);
1521 }
1522 return static_cast<NG::SheetEffectEdge>(sheetEffectEdge);
1523 }
1524
ParseSheetStyle(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle,bool isPartialUpdate)1525 void JSViewAbstract::ParseSheetStyle(
1526 const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle, bool isPartialUpdate)
1527 {
1528 auto height = paramObj->GetProperty("height");
1529 auto showDragBar = paramObj->GetProperty("dragBar");
1530 auto backgroundColor = paramObj->GetProperty("backgroundColor");
1531 auto maskColor = paramObj->GetProperty("maskColor");
1532 auto sheetDetents = paramObj->GetProperty("detents");
1533 auto backgroundBlurStyle = paramObj->GetProperty("blurStyle");
1534 auto showCloseIcon = paramObj->GetProperty("showClose");
1535 auto type = paramObj->GetProperty("preferType");
1536 auto interactive = paramObj->GetProperty("enableOutsideInteractive");
1537 auto showMode = paramObj->GetProperty("mode");
1538 auto offsetVal = paramObj->GetProperty("offset");
1539 auto scrollSizeMode = paramObj->GetProperty("scrollSizeMode");
1540 auto keyboardAvoidMode = paramObj->GetProperty("keyboardAvoidMode");
1541 auto uiContextObj = paramObj->GetProperty("uiContext");
1542 if (uiContextObj->IsObject()) {
1543 JSRef<JSObject> obj = JSRef<JSObject>::Cast(uiContextObj);
1544 auto prop = obj->GetProperty("instanceId_");
1545 if (prop->IsNumber()) {
1546 sheetStyle.instanceId = prop->ToNumber<int32_t>();
1547 }
1548 }
1549
1550 if (offsetVal->IsObject()) {
1551 auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
1552 auto xVal = offsetObj->GetProperty("x");
1553 auto yVal = offsetObj->GetProperty("y");
1554 NG::OffsetF bottomOffset;
1555 CalcDimension dx;
1556 CalcDimension dy;
1557 if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
1558 bottomOffset.SetX(dx.ConvertToPx());
1559 }
1560 if (JSViewAbstract::ParseJsDimensionVp(yVal, dy) && dy.IsNegative()) {
1561 bottomOffset.SetY(dy.ConvertToPx());
1562 }
1563 sheetStyle.bottomOffset = bottomOffset;
1564 }
1565
1566 NG::SheetLevel sheetLevel = NG::SheetLevel::OVERLAY;
1567 if (ParseSheetLevel(showMode, sheetLevel) || !isPartialUpdate) {
1568 sheetStyle.showInPage = (sheetLevel == NG::SheetLevel::EMBEDDED);
1569 }
1570
1571 std::vector<NG::SheetHeight> detents;
1572 if (ParseSheetDetents(sheetDetents, detents)) {
1573 sheetStyle.detents = detents;
1574 }
1575 BlurStyleOption styleOption;
1576 if (ParseSheetBackgroundBlurStyle(backgroundBlurStyle, styleOption)) {
1577 sheetStyle.backgroundBlurStyle = styleOption;
1578 }
1579 bool showClose = true;
1580 if (ParseJsBool(showCloseIcon, showClose)) {
1581 sheetStyle.showCloseIcon = showClose;
1582 } else if (!isPartialUpdate) {
1583 sheetStyle.showCloseIcon = true;
1584 }
1585
1586 bool isInteractive = false;
1587 if (ParseJsBool(interactive, isInteractive)) {
1588 sheetStyle.interactive = isInteractive;
1589 }
1590
1591 if (showDragBar->IsBoolean()) {
1592 sheetStyle.showDragBar = showDragBar->ToBoolean();
1593 } else if (isPartialUpdate) {
1594 sheetStyle.showDragBar.reset();
1595 } else {
1596 sheetStyle.showDragBar = true;
1597 }
1598
1599 if (type->IsNull() || type->IsUndefined()) {
1600 sheetStyle.sheetType.reset();
1601 } else {
1602 if (type->IsNumber()) {
1603 auto sheetType = type->ToNumber<int32_t>();
1604 if (sheetType >= static_cast<int>(NG::SheetType::SHEET_BOTTOM) &&
1605 sheetType <= static_cast<int>(NG::SheetType::SHEET_POPUP)) {
1606 sheetStyle.sheetType = static_cast<NG::SheetType>(sheetType);
1607 }
1608 }
1609 }
1610 if (scrollSizeMode->IsNull() || scrollSizeMode->IsUndefined()) {
1611 sheetStyle.scrollSizeMode.reset();
1612 } else if (scrollSizeMode->IsNumber()) {
1613 auto sheetScrollSizeMode = scrollSizeMode->ToNumber<int32_t>();
1614 if (sheetScrollSizeMode >= static_cast<int>(NG::ScrollSizeMode::FOLLOW_DETENT) &&
1615 sheetScrollSizeMode <= static_cast<int>(NG::ScrollSizeMode::CONTINUOUS)) {
1616 sheetStyle.scrollSizeMode = static_cast<NG::ScrollSizeMode>(sheetScrollSizeMode);
1617 }
1618 }
1619
1620 if (keyboardAvoidMode->IsNull() || keyboardAvoidMode->IsUndefined()) {
1621 sheetStyle.sheetKeyboardAvoidMode.reset();
1622 } else if (keyboardAvoidMode->IsNumber()) {
1623 auto sheetKeyboardAvoidMode = keyboardAvoidMode->ToNumber<int32_t>();
1624 if (sheetKeyboardAvoidMode >= static_cast<int>(NG::SheetKeyboardAvoidMode::NONE) &&
1625 sheetKeyboardAvoidMode <= static_cast<int>(NG::SheetKeyboardAvoidMode::TRANSLATE_AND_SCROLL)) {
1626 sheetStyle.sheetKeyboardAvoidMode = static_cast<NG::SheetKeyboardAvoidMode>(sheetKeyboardAvoidMode);
1627 }
1628 }
1629
1630 auto placement = paramObj->GetProperty("placement");
1631 sheetStyle.placement.reset();
1632 if (placement->IsNumber()) {
1633 auto placementValue = placement->ToNumber<int32_t>();
1634 if (placementValue >= static_cast<int>(Placement::LEFT) &&
1635 placementValue <= static_cast<int>(Placement::RIGHT_BOTTOM)) {
1636 sheetStyle.placement = static_cast<Placement>(placementValue);
1637 }
1638 }
1639
1640 auto placementOnTarget = paramObj->GetProperty("placementOnTarget");
1641 sheetStyle.placementOnTarget.reset();
1642 if (placementOnTarget->IsBoolean()) {
1643 sheetStyle.placementOnTarget = placementOnTarget->ToBoolean();
1644 }
1645
1646 Color color;
1647 if (ParseJsColor(backgroundColor, color)) {
1648 sheetStyle.backgroundColor = color;
1649 }
1650 // parse maskColor
1651 Color parseMaskColor;
1652 if (!maskColor->IsNull() && !maskColor->IsUndefined() && JSViewAbstract::ParseJsColor(maskColor, parseMaskColor)) {
1653 sheetStyle.maskColor = std::move(parseMaskColor);
1654 }
1655
1656 // Parse border width
1657 auto borderWidthValue = paramObj->GetProperty("borderWidth");
1658 NG::BorderWidthProperty borderWidth;
1659 if (ParseBorderWidthProps(borderWidthValue, borderWidth)) {
1660 sheetStyle.borderWidth = borderWidth;
1661 // Parse border color
1662 auto colorValue = paramObj->GetProperty("borderColor");
1663 NG::BorderColorProperty borderColor;
1664 if (ParseBorderColorProps(colorValue, borderColor)) {
1665 sheetStyle.borderColor = borderColor;
1666 } else {
1667 sheetStyle.borderColor =
1668 NG::BorderColorProperty({ Color::BLACK, Color::BLACK, Color::BLACK, Color::BLACK });
1669 }
1670 // Parse border style
1671 auto styleValue = paramObj->GetProperty("borderStyle");
1672 NG::BorderStyleProperty borderStyle;
1673 if (ParseBorderStyleProps(styleValue, borderStyle)) {
1674 sheetStyle.borderStyle = borderStyle;
1675 } else {
1676 sheetStyle.borderStyle = NG::BorderStyleProperty(
1677 { BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID });
1678 }
1679 }
1680 if (isPartialUpdate) {
1681 auto colorValue = paramObj->GetProperty("borderColor");
1682 NG::BorderColorProperty borderColor;
1683 if (ParseBorderColorProps(colorValue, borderColor)) {
1684 sheetStyle.borderColor = borderColor;
1685 } else {
1686 sheetStyle.borderColor.reset();
1687 }
1688 auto styleValue = paramObj->GetProperty("borderStyle");
1689 NG::BorderStyleProperty borderStyle;
1690 if (ParseBorderStyleProps(styleValue, borderStyle)) {
1691 sheetStyle.borderStyle = borderStyle;
1692 } else {
1693 sheetStyle.borderStyle.reset();
1694 }
1695 }
1696
1697 // Parse shadow
1698 Shadow shadow;
1699 auto shadowValue = paramObj->GetProperty("shadow");
1700 if ((shadowValue->IsObject() || shadowValue->IsNumber()) && ParseShadowProps(shadowValue, shadow)) {
1701 sheetStyle.shadow = shadow;
1702 }
1703
1704 //parse effectEdge
1705 sheetStyle.sheetEffectEdge = ParseSheetEffectEdge(paramObj);
1706
1707 // Parse hoverMode
1708 auto enableHoverModeValue = paramObj->GetProperty("enableHoverMode");
1709 if (enableHoverModeValue->IsBoolean()) {
1710 sheetStyle.enableHoverMode = enableHoverModeValue->ToBoolean();
1711 }
1712 auto hoverModeAreaValue = paramObj->GetProperty("hoverModeArea");
1713 if (hoverModeAreaValue->IsNumber()) {
1714 auto hoverModeArea = hoverModeAreaValue->ToNumber<int32_t>();
1715 if (hoverModeArea >= 0 && hoverModeArea < static_cast<int32_t>(HOVER_MODE_AREA_TYPE.size())) {
1716 sheetStyle.hoverModeArea = HOVER_MODE_AREA_TYPE[hoverModeArea];
1717 }
1718 }
1719
1720 auto widthValue = paramObj->GetProperty("width");
1721 CalcDimension width;
1722 if (ParseJsDimensionVpNG(widthValue, width, true)) {
1723 sheetStyle.width = width;
1724 }
1725
1726 auto radiusValue = paramObj->GetProperty("radius");
1727 JSViewAbstract::ParseBindSheetBorderRadius(radiusValue, sheetStyle);
1728
1729 ParseDetentSelection(paramObj, sheetStyle);
1730
1731 NG::SheetHeight sheetStruct;
1732 bool parseResult = ParseSheetHeight(height, sheetStruct, isPartialUpdate);
1733 if (!parseResult) {
1734 TAG_LOGD(AceLogTag::ACE_SHEET, "parse sheet height in unnormal condition");
1735 }
1736 sheetStyle.sheetHeight = sheetStruct;
1737
1738 ParseSheetSubWindowValue(paramObj, sheetStyle);
1739 }
1740
ParseSheetSubWindowValue(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle)1741 void JSViewAbstract::ParseSheetSubWindowValue(const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle)
1742 {
1743 // parse sheet showInSubWindow
1744 sheetStyle.showInSubWindow = false;
1745 if (sheetStyle.showInPage == NG::SheetLevel::EMBEDDED) {
1746 return;
1747 }
1748 auto showInSubWindowValue = paramObj->GetProperty("showInSubWindow");
1749 if (showInSubWindowValue->IsBoolean()) {
1750 #if defined(PREVIEW)
1751 LOGW("[Engine Log] Unable to use the SubWindow in the Previewer. Perform this operation on the "
1752 "emulator or a real device instead.");
1753 #else
1754 sheetStyle.showInSubWindow = showInSubWindowValue->ToBoolean();
1755 #endif
1756 }
1757 }
1758
ParseDetentSelection(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle)1759 void JSViewAbstract::ParseDetentSelection(const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle)
1760 {
1761 auto detentSelection = paramObj->GetProperty("detentSelection");
1762 NG::SheetHeight sheetStruct;
1763 bool parseResult = ParseSheetHeight(detentSelection, sheetStruct, true);
1764 if (!parseResult) {
1765 sheetStruct.height.reset();
1766 sheetStruct.sheetMode.reset();
1767 TAG_LOGD(AceLogTag::ACE_SHEET, "parse sheet detent selection in unnormal condition");
1768 }
1769 sheetStyle.detentSelection = sheetStruct;
1770 }
1771
ParseSheetDetents(const JSRef<JSVal> & args,std::vector<NG::SheetHeight> & sheetDetents)1772 bool JSViewAbstract::ParseSheetDetents(const JSRef<JSVal>& args, std::vector<NG::SheetHeight>& sheetDetents)
1773 {
1774 if (!args->IsArray()) {
1775 return false;
1776 }
1777 JSRef<JSArray> array = JSRef<JSArray>::Cast(args);
1778 NG::SheetHeight sheetDetent;
1779 for (size_t i = 0; i < array->Length(); i++) {
1780 bool parseResult = ParseSheetHeight(array->GetValueAt(i), sheetDetent, false);
1781 if (!parseResult) {
1782 TAG_LOGD(AceLogTag::ACE_SHEET, "parse sheet detent in unnormal condition");
1783 }
1784 if ((!sheetDetent.height.has_value()) && (!sheetDetent.sheetMode.has_value())) {
1785 continue;
1786 }
1787 sheetDetents.emplace_back(sheetDetent);
1788 sheetDetent.height.reset();
1789 sheetDetent.sheetMode.reset();
1790 }
1791 return true;
1792 }
1793
ParseSheetBackgroundBlurStyle(const JSRef<JSVal> & args,BlurStyleOption & blurStyleOptions)1794 bool JSViewAbstract::ParseSheetBackgroundBlurStyle(const JSRef<JSVal>& args, BlurStyleOption& blurStyleOptions)
1795 {
1796 if (args->IsNumber()) {
1797 auto sheetBlurStyle = args->ToNumber<int32_t>();
1798 if (sheetBlurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
1799 sheetBlurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
1800 blurStyleOptions.blurStyle = static_cast<BlurStyle>(sheetBlurStyle);
1801 } else {
1802 return false;
1803 }
1804 } else {
1805 return false;
1806 }
1807 return true;
1808 }
1809
ParseSheetLevel(const JSRef<JSVal> & args,NG::SheetLevel & sheetLevel)1810 bool JSViewAbstract::ParseSheetLevel(const JSRef<JSVal>& args, NG::SheetLevel& sheetLevel)
1811 {
1812 if (!args->IsNumber()) {
1813 return false;
1814 }
1815 auto sheetMode = args->ToNumber<int32_t>();
1816 if (sheetMode >= static_cast<int>(NG::SheetLevel::OVERLAY) &&
1817 sheetMode <= static_cast<int>(NG::SheetLevel::EMBEDDED)) {
1818 sheetLevel = static_cast<NG::SheetLevel>(sheetMode);
1819 return true;
1820 }
1821 return false;
1822 }
1823
ParseCallback(const JSRef<JSObject> & paramObj,std::function<void (const float)> & callbackDidChange,const char * prop)1824 void JSViewAbstract::ParseCallback(const JSRef<JSObject>& paramObj,
1825 std::function<void(const float)>& callbackDidChange, const char* prop)
1826 {
1827 auto callBack = paramObj->GetProperty(prop);
1828 if (callBack->IsFunction()) {
1829 RefPtr<JsFunction> jsFunc =
1830 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callBack));
1831 callbackDidChange = [func = std::move(jsFunc)](int32_t value) {
1832 JSRef<JSVal> param = JSRef<JSVal>::Make(ToJSValue(value));
1833 func->ExecuteJS(1, ¶m);
1834 };
1835 }
1836 }
1837
ParseLifeCycleCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & lifeCycleCallBack,const char * prop)1838 void JSViewAbstract::ParseLifeCycleCallback(const JSRef<JSObject>& paramObj,
1839 std::function<void()>& lifeCycleCallBack, const char* prop)
1840 {
1841 auto callback = paramObj->GetProperty(prop);
1842 if (callback->IsFunction()) {
1843 RefPtr<JsFunction> jsFunc =
1844 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
1845 lifeCycleCallBack = [func = std::move(jsFunc)]() { func->Execute(); };
1846 }
1847 }
1848
ParseSpringBackCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & sheetSpringBack,const char * prop)1849 void JSViewAbstract::ParseSpringBackCallback(const JSRef<JSObject>& paramObj,
1850 std::function<void()>& sheetSpringBack, const char* prop)
1851 {
1852 auto sheetSpringBackCallback = paramObj->GetProperty(prop);
1853 if (sheetSpringBackCallback->IsFunction()) {
1854 RefPtr<JsFunction> jsFunc =
1855 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(sheetSpringBackCallback));
1856 sheetSpringBack = [func = std::move(jsFunc)]() {
1857 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
1858 objectTemplate->SetInternalFieldCount(1);
1859 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
1860 dismissObj->SetPropertyObject(
1861 "springBack", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsSheetSpringBack));
1862 JSRef<JSVal> newJSVal = dismissObj;
1863 func->ExecuteJS(1, &newJSVal);
1864 };
1865 }
1866 }
1867
ParseSheetCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & onAppear,std::function<void ()> & onDisappear,std::function<void ()> & shouldDismiss,std::function<void (const int32_t info)> & onWillDismiss,std::function<void ()> & onWillAppear,std::function<void ()> & onWillDisappear,std::function<void (const float)> & onHeightDidChange,std::function<void (const float)> & onDetentsDidChange,std::function<void (const float)> & onWidthDidChange,std::function<void (const float)> & onTypeDidChange,std::function<void ()> & sheetSpringBack)1868 void JSViewAbstract::ParseSheetCallback(const JSRef<JSObject>& paramObj, std::function<void()>& onAppear,
1869 std::function<void()>& onDisappear, std::function<void()>& shouldDismiss,
1870 std::function<void(const int32_t info)>& onWillDismiss, std::function<void()>& onWillAppear,
1871 std::function<void()>& onWillDisappear, std::function<void(const float)>& onHeightDidChange,
1872 std::function<void(const float)>& onDetentsDidChange,
1873 std::function<void(const float)>& onWidthDidChange,
1874 std::function<void(const float)>& onTypeDidChange, std::function<void()>& sheetSpringBack)
1875 {
1876 auto shouldDismissFunc = paramObj->GetProperty("shouldDismiss");
1877 auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
1878 ParseLifeCycleCallback(paramObj, onAppear, "onAppear");
1879 ParseLifeCycleCallback(paramObj, onDisappear, "onDisappear");
1880 ParseLifeCycleCallback(paramObj, onWillAppear, "onWillAppear");
1881 ParseLifeCycleCallback(paramObj, onWillDisappear, "onWillDisappear");
1882 if (shouldDismissFunc->IsFunction()) {
1883 RefPtr<JsFunction> jsFunc =
1884 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(shouldDismissFunc));
1885 shouldDismiss = [func = std::move(jsFunc)]() {
1886 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
1887 objectTemplate->SetInternalFieldCount(1);
1888 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
1889 dismissObj->SetPropertyObject(
1890 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissSheet));
1891 JSRef<JSVal> newJSVal = dismissObj;
1892 func->ExecuteJS(1, &newJSVal);
1893 };
1894 }
1895 if (onWillDismissFunc->IsFunction()) {
1896 RefPtr<JsFunction> jsFunc =
1897 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
1898 onWillDismiss = [func = std::move(jsFunc)](const int32_t info) {
1899 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
1900 objectTemplate->SetInternalFieldCount(1);
1901 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
1902 dismissObj->SetPropertyObject(
1903 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissSheet));
1904 dismissObj->SetProperty<int32_t>("reason", info);
1905 JSRef<JSVal> newJSVal = dismissObj;
1906 func->ExecuteJS(1, &newJSVal);
1907 };
1908 }
1909 ParseSpringBackCallback(paramObj, sheetSpringBack, "onWillSpringBackWhenDismiss");
1910 ParseCallback(paramObj, onHeightDidChange, "onHeightDidChange");
1911 ParseCallback(paramObj, onDetentsDidChange, "onDetentsDidChange");
1912 ParseCallback(paramObj, onWidthDidChange, "onWidthDidChange");
1913 ParseCallback(paramObj, onTypeDidChange, "onTypeDidChange");
1914 }
1915
ParseSheetTitle(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle,std::function<void ()> & titleBuilderFunction)1916 void JSViewAbstract::ParseSheetTitle(
1917 const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle, std::function<void()>& titleBuilderFunction)
1918 {
1919 auto title = paramObj->GetProperty("title");
1920 std::string mainTitle;
1921 std::string subtitle;
1922 if (title->IsFunction()) {
1923 sheetStyle.isTitleBuilder = true;
1924 auto titleBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(title));
1925 CHECK_NULL_VOID(titleBuilderFunc);
1926 titleBuilderFunction = [func = std::move(titleBuilderFunc)]() {
1927 ACE_SCORING_EVENT("BindSheet");
1928 func->Execute();
1929 };
1930 } else if (title->IsObject()) {
1931 JSRef<JSObject> obj = JSRef<JSObject>::Cast(title);
1932 sheetStyle.isTitleBuilder = false;
1933 auto sheetTitle = obj->GetProperty("title");
1934 auto sheetSubtitle = obj->GetProperty("subtitle");
1935 if (ParseJsString(sheetTitle, mainTitle)) {
1936 sheetStyle.sheetTitle = mainTitle;
1937 }
1938 if (ParseJsString(sheetSubtitle, subtitle)) {
1939 sheetStyle.sheetSubtitle = subtitle;
1940 }
1941 }
1942 }
1943
JsDismissSheet(panda::JsiRuntimeCallInfo * runtimeCallInfo)1944 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissSheet(panda::JsiRuntimeCallInfo* runtimeCallInfo)
1945 {
1946 ViewAbstractModel::GetInstance()->DismissSheet();
1947 return JSValueRef::Undefined(runtimeCallInfo->GetVM());
1948 }
1949
JsDismissContentCover(panda::JsiRuntimeCallInfo * runtimeCallInfo)1950 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissContentCover(panda::JsiRuntimeCallInfo* runtimeCallInfo)
1951 {
1952 ViewAbstractModel::GetInstance()->DismissContentCover();
1953 return JSValueRef::Undefined(runtimeCallInfo->GetVM());
1954 }
1955
JsSheetSpringBack(panda::JsiRuntimeCallInfo * runtimeCallInfo)1956 panda::Local<panda::JSValueRef> JSViewAbstract::JsSheetSpringBack(panda::JsiRuntimeCallInfo* runtimeCallInfo)
1957 {
1958 ViewAbstractModel::GetInstance()->SheetSpringBack();
1959 return JSValueRef::Undefined(runtimeCallInfo->GetVM());
1960 }
1961
ParseSheetMode(const std::string heightStr,NG::SheetHeight & detent)1962 bool JSViewAbstract::ParseSheetMode(const std::string heightStr, NG::SheetHeight& detent)
1963 {
1964 if (heightStr == SHEET_HEIGHT_MEDIUM) {
1965 detent.sheetMode = NG::SheetMode::MEDIUM;
1966 return true;
1967 }
1968
1969 if (heightStr == SHEET_HEIGHT_LARGE) {
1970 detent.sheetMode = NG::SheetMode::LARGE;
1971 return true;
1972 }
1973 if (heightStr == SHEET_HEIGHT_FITCONTENT) {
1974 detent.sheetMode = NG::SheetMode::AUTO;
1975 return true;
1976 }
1977 return false;
1978 }
1979
ParseSheetHeight(const JSRef<JSVal> & args,NG::SheetHeight & detent,bool isReset)1980 bool JSViewAbstract::ParseSheetHeight(const JSRef<JSVal>& args, NG::SheetHeight& detent,
1981 bool isReset)
1982 {
1983 detent.height.reset();
1984 detent.sheetMode.reset();
1985 CalcDimension sheetHeight;
1986 if (args->IsString()) {
1987 std::string heightStr = args->ToString();
1988
1989 // Remove all " ".
1990 heightStr.erase(std::remove(heightStr.begin(), heightStr.end(), ' '), heightStr.end());
1991 std::transform(heightStr.begin(), heightStr.end(), heightStr.begin(), ::tolower);
1992 if (ParseSheetMode(heightStr, detent)) {
1993 return true;
1994 }
1995 if (heightStr.find("calc") != std::string::npos) {
1996 sheetHeight = CalcDimension(heightStr, DimensionUnit::CALC);
1997 } else {
1998 sheetHeight = StringUtils::StringToDimensionWithUnit(heightStr, DimensionUnit::VP, -1.0);
1999 }
2000 if (sheetHeight.Value() < 0) {
2001 detent.sheetMode = NG::SheetMode::LARGE;
2002 return false;
2003 }
2004 }
2005 if (!ParseJsDimensionVpNG(args, sheetHeight)) {
2006 if (!isReset) {
2007 detent.sheetMode = NG::SheetMode::LARGE;
2008 }
2009 return false;
2010 }
2011 detent.height = sheetHeight;
2012 return true;
2013 }
2014
JsBindMenu(const JSCallbackInfo & info)2015 void JSViewAbstract::JsBindMenu(const JSCallbackInfo& info)
2016 {
2017 NG::MenuParam menuParam;
2018 MenuDefaultParam(menuParam);
2019 size_t builderIndex = 0;
2020 JSViewPopups::GetMenuShowInSubwindow(menuParam);
2021 if (info.Length() > PARAMETER_LENGTH_FIRST) {
2022 auto jsVal = info[0];
2023 if (jsVal->IsBoolean()) {
2024 menuParam.isShow = jsVal->ToBoolean();
2025 menuParam.setShow = true;
2026 builderIndex = 1;
2027 if (info.Length() > PARAMETER_LENGTH_SECOND) {
2028 JSViewPopups::ParseBindOptionParam(info, menuParam, builderIndex + 1);
2029 }
2030 } else if (jsVal->IsUndefined()) {
2031 menuParam.setShow = true;
2032 menuParam.isShow = false;
2033 builderIndex = 1;
2034 if (info.Length() > PARAMETER_LENGTH_SECOND) {
2035 JSViewPopups::ParseBindOptionParam(info, menuParam, builderIndex + 1);
2036 }
2037 } else if (jsVal->IsObject()) {
2038 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(jsVal);
2039 menuParam.onStateChange = JSViewPopups::ParseDoubleBindCallback(info, callbackObj, "$value");
2040 auto isShowObj = callbackObj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
2041 if (isShowObj->IsBoolean()) {
2042 menuParam.isShow = isShowObj->ToBoolean();
2043 menuParam.setShow = true;
2044 builderIndex = 1;
2045 if (info.Length() > PARAMETER_LENGTH_SECOND) {
2046 JSViewPopups::ParseBindOptionParam(info, menuParam, builderIndex + 1);
2047 }
2048 } else {
2049 builderIndex = 0;
2050 JSViewPopups::ParseBindOptionParam(info, menuParam, builderIndex + 1);
2051 }
2052 }
2053 }
2054
2055 if (info[builderIndex]->IsArray()) {
2056 std::vector<NG::OptionParam> optionsParam = JSViewPopups::ParseBindOptionParam(info, builderIndex);
2057 ViewAbstractModel::GetInstance()->BindMenu(std::move(optionsParam), nullptr, menuParam);
2058 } else if (info[builderIndex]->IsObject()) {
2059 // CustomBuilder
2060 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[builderIndex]);
2061 auto builder = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUILDER));
2062 if (!builder->IsFunction()) {
2063 return;
2064 }
2065 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
2066
2067 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2068 CHECK_NULL_VOID(builderFunc);
2069 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
2070 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2071 ACE_SCORING_EVENT("BuildMenu");
2072 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2073 func->Execute();
2074 };
2075 ViewAbstractModel::GetInstance()->BindMenu({}, std::move(buildFunc), menuParam);
2076 }
2077 }
2078
MenuDefaultParam(NG::MenuParam & menuParam)2079 void JSViewAbstract::MenuDefaultParam(NG::MenuParam& menuParam)
2080 {
2081 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2082 menuParam.placement = Placement::BOTTOM_LEFT;
2083 }
2084 }
2085
ParseContentMenuCommonParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuObj,NG::MenuParam & menuParam)2086 void JSViewAbstract::ParseContentMenuCommonParam(
2087 const JSCallbackInfo& info, const JSRef<JSObject>& menuObj, NG::MenuParam& menuParam)
2088 {
2089 if (!menuParam.placement.has_value()) {
2090 MenuDefaultParam(menuParam);
2091 }
2092 CHECK_EQUAL_VOID(menuObj->IsEmpty(), true);
2093 JSViewPopups::ParseMenuParam(info, menuObj, menuParam);
2094 auto preview = menuObj->GetProperty("preview");
2095 if (preview->IsNumber()) {
2096 auto previewMode = preview->ToNumber<int32_t>();
2097 if (previewMode == static_cast<int32_t>(MenuPreviewMode::IMAGE)) {
2098 menuParam.previewMode = static_cast<MenuPreviewMode>(previewMode);
2099 ParseContentPreviewAnimationOptionsParam(info, menuObj, menuParam);
2100 }
2101 }
2102 }
2103
OpenMenu(NG::MenuParam & menuParam,const RefPtr<NG::UINode> & customNode,const int32_t & targetId)2104 int32_t JSViewAbstract::OpenMenu(
2105 NG::MenuParam& menuParam, const RefPtr<NG::UINode>& customNode, const int32_t& targetId)
2106 {
2107 return ViewAbstractModel::GetInstance()->OpenMenu(menuParam, customNode, targetId);
2108 }
2109
UpdateMenu(const NG::MenuParam & menuParam,const RefPtr<NG::UINode> & customNode)2110 int32_t JSViewAbstract::UpdateMenu(const NG::MenuParam& menuParam, const RefPtr<NG::UINode>& customNode)
2111 {
2112 return ViewAbstractModel::GetInstance()->UpdateMenu(menuParam, customNode);
2113 }
2114
CloseMenu(const RefPtr<NG::UINode> & customNode)2115 int32_t JSViewAbstract::CloseMenu(const RefPtr<NG::UINode>& customNode)
2116 {
2117 return ViewAbstractModel::GetInstance()->CloseMenu(customNode);
2118 }
2119
ParseDialogCallback(const JSRef<JSObject> & paramObj,std::function<void (const int32_t & info,const int32_t & instanceId)> & onWillDismiss)2120 void JSViewAbstract::ParseDialogCallback(const JSRef<JSObject>& paramObj,
2121 std::function<void(const int32_t& info, const int32_t& instanceId)>& onWillDismiss)
2122 {
2123 auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
2124 if (onWillDismissFunc->IsFunction()) {
2125 auto jsFunc =
2126 AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
2127 onWillDismiss = [func = std::move(jsFunc)](const int32_t& info, const int32_t& instanceId) {
2128 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
2129 objectTemplate->SetInternalFieldCount(ON_WILL_DISMISS_FIELD_COUNT);
2130 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
2131 dismissObj->SetPropertyObject(
2132 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissDialog));
2133 dismissObj->SetProperty<int32_t>("reason", info);
2134 JSRef<JSVal> newJSVal = dismissObj;
2135 func->ExecuteJS(1, &newJSVal);
2136 };
2137 }
2138 }
2139
JsDismissDialog(panda::JsiRuntimeCallInfo * runtimeCallInfo)2140 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissDialog(panda::JsiRuntimeCallInfo* runtimeCallInfo)
2141 {
2142 ViewAbstractModel::GetInstance()->DismissDialog();
2143 return JSValueRef::Undefined(runtimeCallInfo->GetVM());
2144 }
2145
AppearDialogEvent(const JSCallbackInfo & info,DialogProperties & dialogProperties)2146 void AppearDialogEvent(const JSCallbackInfo& info, DialogProperties& dialogProperties)
2147 {
2148 if (!info[0]->IsObject()) {
2149 return;
2150 }
2151 auto paramObject = JSRef<JSObject>::Cast(info[0]);
2152 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2153 auto onDidAppear = paramObject->GetProperty("onDidAppear");
2154 if (!onDidAppear->IsUndefined() && onDidAppear->IsFunction()) {
2155 auto jsFunc = AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidAppear));
2156 auto didAppearId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
2157 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2158 ACE_SCORING_EVENT("Popups.onDidAppear");
2159 PipelineContext::SetCallBackNode(node);
2160 func->Execute();
2161 };
2162 dialogProperties.onDidAppear = std::move(didAppearId);
2163 }
2164 auto onWillAppear = paramObject->GetProperty("onWillAppear");
2165 if (!onWillAppear->IsUndefined() && onWillAppear->IsFunction()) {
2166 auto jsFunc = AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillAppear));
2167 auto willAppearId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
2168 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2169 ACE_SCORING_EVENT("Popups.onWillAppear");
2170 PipelineContext::SetCallBackNode(node);
2171 func->Execute();
2172 };
2173 dialogProperties.onWillAppear = std::move(willAppearId);
2174 }
2175 }
2176
DisappearDialogEvent(const JSCallbackInfo & info,DialogProperties & dialogProperties)2177 void DisappearDialogEvent(const JSCallbackInfo& info, DialogProperties& dialogProperties)
2178 {
2179 if (!info[0]->IsObject()) {
2180 return;
2181 }
2182 auto paramObject = JSRef<JSObject>::Cast(info[0]);
2183 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2184 auto onDidDisappear = paramObject->GetProperty("onDidDisappear");
2185 if (!onDidDisappear->IsUndefined() && onDidDisappear->IsFunction()) {
2186 auto jsFunc = AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidDisappear));
2187 auto didDisappearId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
2188 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2189 ACE_SCORING_EVENT("Popups.onDidDisappear");
2190 PipelineContext::SetCallBackNode(node);
2191 func->Execute();
2192 };
2193 dialogProperties.onDidDisappear = std::move(didDisappearId);
2194 }
2195 auto onWillDisappear = paramObject->GetProperty("onWillDisappear");
2196 if (!onWillDisappear->IsUndefined() && onWillDisappear->IsFunction()) {
2197 auto jsFunc = AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDisappear));
2198 auto willDisappearId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
2199 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2200 ACE_SCORING_EVENT("Popups.onWillDisappear");
2201 PipelineContext::SetCallBackNode(node);
2202 func->Execute();
2203 };
2204 dialogProperties.onWillDisappear = std::move(willDisappearId);
2205 }
2206 }
2207
ParseAppearDialogCallback(const JSCallbackInfo & info,DialogProperties & dialogProperties)2208 void JSViewAbstract::ParseAppearDialogCallback(const JSCallbackInfo& info, DialogProperties& dialogProperties)
2209 {
2210 if (!info[0]->IsObject()) {
2211 return ;
2212 }
2213 AppearDialogEvent(info, dialogProperties);
2214 DisappearDialogEvent(info, dialogProperties);
2215 }
2216
SetDialogHoverModeProperties(const JSRef<JSObject> & obj,DialogProperties & properties)2217 void JSViewAbstract::SetDialogHoverModeProperties(const JSRef<JSObject>& obj, DialogProperties& properties)
2218 {
2219 auto enableHoverModeValue = obj->GetProperty("enableHoverMode");
2220 if (enableHoverModeValue->IsBoolean()) {
2221 properties.enableHoverMode = enableHoverModeValue->ToBoolean();
2222 }
2223
2224 // Parse hoverModeArea
2225 auto hoverModeAreaValue = obj->GetProperty("hoverModeArea");
2226 if (hoverModeAreaValue->IsNumber()) {
2227 auto hoverModeArea = hoverModeAreaValue->ToNumber<int32_t>();
2228 if (hoverModeArea >= 0 && hoverModeArea < static_cast<int32_t>(HOVER_MODE_AREA_TYPE.size())) {
2229 properties.hoverModeArea = HOVER_MODE_AREA_TYPE[hoverModeArea];
2230 }
2231 }
2232 }
2233
SetDialogBlurStyleOption(const JSRef<JSObject> & obj,DialogProperties & properties)2234 void JSViewAbstract::SetDialogBlurStyleOption(const JSRef<JSObject>& obj, DialogProperties& properties)
2235 {
2236 auto blurStyleValue = obj->GetProperty("backgroundBlurStyleOptions");
2237 if (blurStyleValue->IsObject()) {
2238 if (!properties.blurStyleOption.has_value()) {
2239 properties.blurStyleOption.emplace();
2240 }
2241 JSViewAbstract::ParseBlurStyleOption(blurStyleValue, properties.blurStyleOption.value());
2242 }
2243 }
2244
SetDialogEffectOption(const JSRef<JSObject> & obj,DialogProperties & properties)2245 void JSViewAbstract::SetDialogEffectOption(const JSRef<JSObject>& obj, DialogProperties& properties)
2246 {
2247 auto effectOptionValue = obj->GetProperty("backgroundEffect");
2248 if (effectOptionValue->IsObject()) {
2249 if (!properties.effectOption.has_value()) {
2250 properties.effectOption.emplace();
2251 }
2252 JSViewAbstract::ParseEffectOption(effectOptionValue, properties.effectOption.value());
2253 }
2254 }
2255 }