1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
17
18 #include <algorithm>
19 #include <regex>
20 #include <vector>
21
22 #include "base/json/json_util.h"
23 #include "bridge/common/utils/utils.h"
24 #include "bridge/declarative_frontend/engine/functions/js_drag_function.h"
25 #include "bridge/declarative_frontend/engine/functions/js_focus_function.h"
26 #include "bridge/declarative_frontend/engine/functions/js_function.h"
27 #include "bridge/declarative_frontend/engine/functions/js_on_area_change_function.h"
28 #include "bridge/declarative_frontend/jsview/js_utils.h"
29 #include "core/components_v2/extensions/events/on_area_change_extension.h"
30 #ifdef USE_V8_ENGINE
31 #include "bridge/declarative_frontend/engine/v8/functions/v8_function.h"
32 #endif
33 #include "bridge/declarative_frontend/jsview/js_grid_container.h"
34 #include "bridge/declarative_frontend/jsview/js_view_register.h"
35 #include "bridge/declarative_frontend/view_stack_processor.h"
36 #include "core/common/ace_application_info.h"
37 #include "core/components/box/box_component_helper.h"
38 #include "core/components/common/layout/align_declaration.h"
39 #include "core/components/common/properties/motion_path_option.h"
40 #include "core/components/menu/menu_component.h"
41 #include "core/components/option/option_component.h"
42 #include "core/gestures/long_press_gesture.h"
43 #include "frameworks/base/memory/referenced.h"
44 #include "frameworks/bridge/declarative_frontend/engine/functions/js_click_function.h"
45 #include "frameworks/bridge/declarative_frontend/jsview/js_shape_abstract.h"
46 #include "frameworks/core/components/text/text_component.h"
47
48 namespace OHOS::Ace::Framework {
49 namespace {
50
51 constexpr uint32_t DEFAULT_DURATION = 1000; // ms
52 constexpr uint32_t COLOR_ALPHA_OFFSET = 24;
53 constexpr uint32_t COLOR_ALPHA_VALUE = 0xFF000000;
54 constexpr int32_t MAX_ALIGN_VALUE = 8;
55 constexpr int32_t DEFAULT_LONG_PRESS_FINGER = 1;
56 constexpr int32_t DEFAULT_LONG_PRESS_DURATION = 500;
57 const std::regex RESOURCE_APP_STRING_PLACEHOLDER(R"(\%((\d+)(\$)){0,1}([dsf]))", std::regex::icase);
58 constexpr double FULL_DIMENSION = 100.0;
59 constexpr double HALF_DIMENSION = 50.0;
60
CheckJSCallbackInfo(const std::string & callerName,const JSCallbackInfo & info,std::vector<JSCallbackInfoType> & infoTypes)61 bool CheckJSCallbackInfo(const std::string& callerName, const JSCallbackInfo& info,
62 std::vector<JSCallbackInfoType>& infoTypes)
63 {
64 if (info.Length() < 1) {
65 LOGE("%{public}s: The arg is supposed to have at least one argument", callerName.c_str());
66 return false;
67 }
68 bool typeVerified = false;
69 std::string unrecognizedType;
70 for (const auto& infoType : infoTypes) {
71 switch (infoType) {
72 case JSCallbackInfoType::STRING:
73 if (info[0]->IsString()) {
74 typeVerified = true;
75 } else {
76 unrecognizedType += "string|";
77 }
78 break;
79 case JSCallbackInfoType::NUMBER:
80 if (info[0]->IsNumber()) {
81 typeVerified = true;
82 } else {
83 unrecognizedType += "number|";
84 }
85 break;
86 case JSCallbackInfoType::OBJECT:
87 if (info[0]->IsObject()) {
88 typeVerified = true;
89 } else {
90 unrecognizedType += "object|";
91 }
92 break;
93 case JSCallbackInfoType::FUNCTION:
94 if (info[0]->IsFunction()) {
95 typeVerified = true;
96 } else {
97 unrecognizedType += "Function|";
98 }
99 break;
100 default:
101 break;
102 }
103 }
104 if (!typeVerified) {
105 LOGE("%{public}s: info[0] is not a [%{public}s]",
106 callerName.c_str(), unrecognizedType.substr(0, unrecognizedType.size()-1).c_str());
107 }
108 return typeVerified || infoTypes.size() == 0;
109 }
110
ParseJsScale(std::unique_ptr<JsonValue> & argsPtrItem,float & scaleX,float & scaleY,float & scaleZ,Dimension & centerX,Dimension & centerY)111 void ParseJsScale(std::unique_ptr<JsonValue>& argsPtrItem, float& scaleX, float& scaleY, float& scaleZ,
112 Dimension& centerX, Dimension& centerY)
113 {
114 double xVal = 1.0;
115 double yVal = 1.0;
116 double zVal = 1.0;
117 JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("x"), xVal);
118 JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("y"), yVal);
119 JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("z"), zVal);
120 scaleX = static_cast<float>(xVal);
121 scaleY = static_cast<float>(yVal);
122 scaleZ = static_cast<float>(zVal);
123 // if specify centerX
124 Dimension length;
125 if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("centerX"), length)) {
126 centerX = length;
127 }
128 // if specify centerY
129 if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("centerY"), length)) {
130 centerY = length;
131 }
132 }
133
ParseJsTranslate(std::unique_ptr<JsonValue> & argsPtrItem,Dimension & translateX,Dimension & translateY,Dimension & translateZ)134 void ParseJsTranslate(
135 std::unique_ptr<JsonValue>& argsPtrItem, Dimension& translateX, Dimension& translateY, Dimension& translateZ)
136 {
137 Dimension length;
138 if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("x"), length)) {
139 translateX = length;
140 }
141 if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("y"), length)) {
142 translateY = length;
143 }
144 if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("z"), length)) {
145 translateZ = length;
146 }
147 }
148
ParseJsRotate(std::unique_ptr<JsonValue> & argsPtrItem,float & dx,float & dy,float & dz,Dimension & centerX,Dimension & centerY,std::optional<float> & angle)149 void ParseJsRotate(std::unique_ptr<JsonValue>& argsPtrItem, float& dx, float& dy, float& dz, Dimension& centerX,
150 Dimension& centerY, std::optional<float>& angle)
151 {
152 // default: dx, dy, dz (0.0, 0.0, 0.0)
153 double dxVal = 0.0;
154 double dyVal = 0.0;
155 double dzVal = 0.0;
156 JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("x"), dxVal);
157 JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("y"), dyVal);
158 JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("z"), dzVal);
159 dx = static_cast<float>(dxVal);
160 dy = static_cast<float>(dyVal);
161 dz = static_cast<float>(dzVal);
162 // if specify centerX
163 Dimension length;
164 if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("centerX"), length)) {
165 centerX = length;
166 }
167 // if specify centerY
168 if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("centerY"), length)) {
169 centerY = length;
170 }
171 // if specify angle
172 JSViewAbstract::GetAngle("angle", argsPtrItem, angle);
173 }
174
SetDefaultTransition(TransitionType transitionType)175 void SetDefaultTransition(TransitionType transitionType)
176 {
177 auto display = ViewStackProcessor::GetInstance()->GetDisplayComponent();
178 if (!display) {
179 LOGE("display component is null.");
180 return;
181 }
182 LOGI("JsTransition with default");
183 display->SetTransition(transitionType, 0.0);
184 }
185
ParseAndSetOpacityTransition(const std::unique_ptr<JsonValue> & transitionArgs,TransitionType transitionType)186 bool ParseAndSetOpacityTransition(const std::unique_ptr<JsonValue>& transitionArgs, TransitionType transitionType)
187 {
188 if (transitionArgs->Contains("opacity")) {
189 double opacity = 0.0;
190 JSViewAbstract::ParseJsonDouble(transitionArgs->GetValue("opacity"), opacity);
191 auto display = ViewStackProcessor::GetInstance()->GetDisplayComponent();
192 if (!display) {
193 LOGE("display component is null.");
194 return true;
195 }
196 LOGI("JsTransition with type: %{public}d, opacity: %{public}.2f", transitionType, opacity);
197 display->SetTransition(transitionType, opacity);
198 return true;
199 }
200 return false;
201 }
202
ParseAndSetRotateTransition(const std::unique_ptr<JsonValue> & transitionArgs,TransitionType transitionType)203 bool ParseAndSetRotateTransition(const std::unique_ptr<JsonValue>& transitionArgs, TransitionType transitionType)
204 {
205 if (transitionArgs->Contains("rotate")) {
206 auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
207 if (!transform) {
208 LOGE("transform component is null.");
209 return true;
210 }
211 auto rotateArgs = transitionArgs->GetObject("rotate");
212 // default: dx, dy, dz (0.0, 0.0, 0.0)
213 float dx = 0.0f;
214 float dy = 0.0f;
215 float dz = 0.0f;
216 // default centerX, centerY 50% 50%;
217 Dimension centerX = 0.5_pct;
218 Dimension centerY = 0.5_pct;
219 std::optional<float> angle;
220 ParseJsRotate(rotateArgs, dx, dy, dz, centerX, centerY, angle);
221 if (angle) {
222 transform->SetRotateTransition(transitionType, dx, dy, dz, angle.value());
223 transform->SetOriginDimension(DimensionOffset(centerX, centerY));
224 LOGI("JsTransition with type: %{public}d. rotate: [%.2f, %.2f, %.2f] [%.2f, %.2f] %.2f", transitionType, dx,
225 dy, dz, centerX.Value(), centerY.Value(), angle.value());
226 }
227 return true;
228 }
229 return false;
230 }
231
ParseAndSetScaleTransition(const std::unique_ptr<JsonValue> & transitionArgs,TransitionType transitionType)232 bool ParseAndSetScaleTransition(const std::unique_ptr<JsonValue>& transitionArgs, TransitionType transitionType)
233 {
234 if (transitionArgs->Contains("scale")) {
235 auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
236 if (!transform) {
237 LOGE("transform component is null.");
238 return true;
239 }
240 auto scaleArgs = transitionArgs->GetObject("scale");
241 // default: x, y, z (1.0, 1.0, 1.0)
242 auto scaleX = 1.0f;
243 auto scaleY = 1.0f;
244 auto scaleZ = 1.0f;
245 // default centerX, centerY 50% 50%;
246 Dimension centerX = 0.5_pct;
247 Dimension centerY = 0.5_pct;
248 ParseJsScale(scaleArgs, scaleX, scaleY, scaleZ, centerX, centerY);
249 transform->SetScaleTransition(transitionType, scaleX, scaleY, scaleZ);
250 transform->SetOriginDimension(DimensionOffset(centerX, centerY));
251 LOGI("JsTransition with type: %{public}d. scale: [%.2f, %.2f, %.2f] [%.2f, %.2f]", transitionType, scaleX,
252 scaleY, scaleZ, centerX.Value(), centerY.Value());
253 return true;
254 }
255 return false;
256 }
257
ParseAndSetTranslateTransition(const std::unique_ptr<JsonValue> & transitionArgs,TransitionType transitionType)258 bool ParseAndSetTranslateTransition(const std::unique_ptr<JsonValue>& transitionArgs, TransitionType transitionType)
259 {
260 if (transitionArgs->Contains("translate")) {
261 auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
262 if (!transform) {
263 LOGE("transform component is null.");
264 return true;
265 }
266 auto translateArgs = transitionArgs->GetObject("translate");
267 // default: x, y, z (0.0, 0.0, 0.0)
268 auto translateX = Dimension(0.0);
269 auto translateY = Dimension(0.0);
270 auto translateZ = Dimension(0.0);
271 ParseJsTranslate(translateArgs, translateX, translateY, translateZ);
272 transform->SetTranslateTransition(transitionType, translateX, translateY, translateZ);
273 LOGI("JsTransition with type: %{public}d. translate: [%.2f, %.2f, %.2f]", transitionType, translateX.Value(),
274 translateY.Value(), translateZ.Value());
275 return true;
276 }
277 return false;
278 }
279
ParseMotionPath(const std::unique_ptr<JsonValue> & argsPtrItem,MotionPathOption & option)280 bool ParseMotionPath(const std::unique_ptr<JsonValue>& argsPtrItem, MotionPathOption& option)
281 {
282 if (argsPtrItem && !argsPtrItem->IsNull()) {
283 auto path = argsPtrItem->GetString("path", "");
284 if (!path.empty()) {
285 option.SetPath(path);
286 double from = 0.0;
287 double to = 1.0;
288 JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("from"), from);
289 JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("to"), to);
290 option.SetBegin(static_cast<float>(from));
291 option.SetEnd(static_cast<float>(to));
292 option.SetRotate(argsPtrItem->GetBool("rotatable", false));
293 return true;
294 }
295 }
296 return false;
297 }
298
SetBgImgPosition(const DimensionUnit & typeX,const DimensionUnit & typeY,const double valueX,const double valueY,BackgroundImagePosition & bgImgPosition)299 void SetBgImgPosition(const DimensionUnit& typeX, const DimensionUnit& typeY,
300 const double valueX, const double valueY, BackgroundImagePosition& bgImgPosition)
301 {
302 AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
303 bgImgPosition.SetSizeX(AnimatableDimension(valueX, typeX, option));
304 bgImgPosition.SetSizeY(AnimatableDimension(valueY, typeY, option));
305 }
306
GetReplaceContentStr(int pos,const std::string & type,JSRef<JSArray> params,int32_t containCount)307 std::string GetReplaceContentStr(int pos, const std::string& type, JSRef<JSArray> params, int32_t containCount)
308 {
309 JSRef<JSVal> item = params->GetValueAt(pos + containCount);
310 if (type == "d") {
311 if (item->IsNumber()) {
312 return std::to_string(item->ToNumber<uint32_t>());
313 }
314 } else if (type == "s") {
315 if (item->IsString()) {
316 return item->ToString();
317 }
318 } else if (type == "f") {
319 if (item->IsNumber()) {
320 return std::to_string(item->ToNumber<float>());
321 }
322 }
323 return std::string();
324 }
325
ReplaceHolder(std::string & originStr,JSRef<JSArray> params,int32_t containCount)326 void ReplaceHolder(std::string& originStr, JSRef<JSArray> params, int32_t containCount)
327 {
328 auto size = static_cast<int32_t>(params->Length());
329 if (containCount == size) {
330 return;
331 }
332 std::string::const_iterator start = originStr.begin();
333 std::string::const_iterator end = originStr.end();
334 std::smatch matchs;
335 bool shortHolderType = false;
336 bool firstMatch = true;
337 int searchTime = 0;
338 while (std::regex_search(start, end, matchs, RESOURCE_APP_STRING_PLACEHOLDER)) {
339 std::string pos = matchs[2];
340 std::string type = matchs[4];
341 if (firstMatch) {
342 firstMatch = false;
343 shortHolderType = pos.length() == 0;
344 } else {
345 if (shortHolderType ^ (pos.length() == 0)) {
346 LOGE("wrong place holder,stop parse string");
347 return;
348 }
349 }
350
351 std::string replaceContentStr;
352 if (shortHolderType) {
353 replaceContentStr = GetReplaceContentStr(searchTime, type, params, containCount);
354 } else {
355 replaceContentStr = GetReplaceContentStr(StringToInt(pos) - 1, type, params, containCount);
356 }
357
358 originStr.replace(matchs[0].first - originStr.begin(), matchs[0].length(), replaceContentStr);
359 start = originStr.begin() + matchs.prefix().length() + replaceContentStr.length();
360 end = originStr.end();
361 searchTime++;
362 }
363 }
364
ParseLocationProps(const JSCallbackInfo & info,AnimatableDimension & x,AnimatableDimension & y)365 bool ParseLocationProps(const JSCallbackInfo& info, AnimatableDimension& x, AnimatableDimension& y)
366 {
367 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
368 if (!CheckJSCallbackInfo("ParseLocationProps", info, checkList)) {
369 return false;
370 }
371 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
372 JSRef<JSVal> xVal = sizeObj->GetProperty("x");
373 JSRef<JSVal> yVal = sizeObj->GetProperty("y");
374 bool hasX = JSViewAbstract::ParseJsAnimatableDimensionVp(xVal, x);
375 bool hasY = JSViewAbstract::ParseJsAnimatableDimensionVp(yVal, y);
376 return hasX || hasY;
377 }
378
379 #ifndef WEARABLE_PRODUCT
380 const std::vector<Placement> PLACEMENT = { Placement::LEFT, Placement::RIGHT, Placement::TOP, Placement::BOTTOM,
381 Placement::TOP_LEFT, Placement::TOP_RIGHT, Placement::BOTTOM_LEFT, Placement::BOTTOM_RIGHT };
382
ParseShowObject(const JSCallbackInfo & info,const JSRef<JSObject> & showObj,const RefPtr<PopupComponentV2> & popupComponent)383 void ParseShowObject(
384 const JSCallbackInfo& info, const JSRef<JSObject>& showObj, const RefPtr<PopupComponentV2>& popupComponent)
385 {
386 JSRef<JSVal> changeEventVal = showObj->GetProperty("changeEvent");
387 if (changeEventVal->IsFunction()) {
388 RefPtr<JsFunction> jsFunc =
389 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
390 auto eventMarker = EventMarker(
391 [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
392 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
393 ACE_SCORING_EVENT("Popup.onStateChange");
394
395 if (param != "true" && param != "false") {
396 LOGE("param is not equal true or fasle, invaild.");
397 return;
398 }
399
400 bool newValue = StringToBool(param);
401 JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(newValue));
402 func->ExecuteJS(1, &newJSVal);
403 });
404 popupComponent->SetChangeEvent(eventMarker);
405 }
406 }
407
ParsePopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupComponentV2> & popupComponent)408 void ParsePopupParam(
409 const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupComponentV2>& popupComponent)
410 {
411 JSRef<JSVal> messageVal = popupObj->GetProperty("message");
412 popupComponent->SetMessage(messageVal->ToString());
413
414 JSRef<JSVal> placementOnTopVal = popupObj->GetProperty("placementOnTop");
415 if (placementOnTopVal->IsBoolean()) {
416 popupComponent->SetPlacementOnTop(placementOnTopVal->ToBoolean());
417 }
418
419 JSRef<JSVal> onStateChangeVal = popupObj->GetProperty("onStateChange");
420 if (onStateChangeVal->IsFunction()) {
421 std::vector<std::string> keys = { "isVisible" };
422 RefPtr<JsFunction> jsFunc =
423 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onStateChangeVal));
424 auto eventMarker = EventMarker(
425 [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), keys](const std::string& param) {
426 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
427 ACE_SCORING_EVENT("Popup.onStateChange");
428 func->Execute(keys, param);
429 });
430 popupComponent->SetOnStateChange(eventMarker);
431 }
432
433 JSRef<JSVal> primaryButtonVal = popupObj->GetProperty("primaryButton");
434 if (primaryButtonVal->IsObject()) {
435 ButtonProperties properties;
436 JSRef<JSObject> obj = JSRef<JSObject>::Cast(primaryButtonVal);
437 JSRef<JSVal> value = obj->GetProperty("value");
438 if (value->IsString()) {
439 properties.value = value->ToString();
440 }
441
442 JSRef<JSVal> actionValue = obj->GetProperty("action");
443 if (actionValue->IsFunction()) {
444 auto actionFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(actionValue));
445 EventMarker actionId([execCtx = info.GetExecutionContext(), func = std::move(actionFunc)]() {
446 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
447 ACE_SCORING_EVENT("primaryButton.action");
448 func->Execute();
449 });
450 properties.actionId = actionId;
451 }
452 properties.showButton = true;
453 popupComponent->SetPrimaryButtonProperties(properties);
454 }
455
456 JSRef<JSVal> secondaryButtonVal = popupObj->GetProperty("secondaryButton");
457 if (secondaryButtonVal->IsObject()) {
458 ButtonProperties properties;
459 JSRef<JSObject> obj = JSRef<JSObject>::Cast(secondaryButtonVal);
460 JSRef<JSVal> value = obj->GetProperty("value");
461 if (value->IsString()) {
462 properties.value = value->ToString();
463 }
464
465 JSRef<JSVal> actionValue = obj->GetProperty("action");
466 if (actionValue->IsFunction()) {
467 auto actionFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(actionValue));
468 EventMarker actionId([execCtx = info.GetExecutionContext(), func = std::move(actionFunc)]() {
469 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
470 ACE_SCORING_EVENT("secondaryButton.action");
471 func->Execute();
472 });
473 properties.actionId = actionId;
474 }
475 properties.showButton = true;
476 popupComponent->SetSecondaryButtonProperties(properties);
477 }
478 }
479
ParseCustomPopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupComponentV2> & popupComponent)480 void ParseCustomPopupParam(
481 const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupComponentV2>& popupComponent)
482 {
483 RefPtr<Component> customComponent;
484 auto builderValue = popupObj->GetProperty("builder");
485 if (!builderValue->IsObject()) {
486 LOGE("builder param is not an object.");
487 return;
488 }
489
490 JSRef<JSObject> builderObj;
491 builderObj = JSRef<JSObject>::Cast(builderValue);
492 auto builder = builderObj->GetProperty("builder");
493 if (!builder->IsFunction()) {
494 LOGE("builder param is not a function.");
495 return;
496 }
497 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
498 if (!builderFunc) {
499 LOGE("builder function is null.");
500 return;
501 }
502 // use another VSP instance while executing the builder function
503 ScopedViewStackProcessor builderViewStackProcessor;
504 {
505 ACE_SCORING_EVENT("popup.builder");
506 builderFunc->Execute();
507 }
508 customComponent = ViewStackProcessor::GetInstance()->Finish();
509 popupComponent->SetCustomComponent(customComponent);
510
511 auto popupParam = popupComponent->GetPopupParam();
512 popupParam->SetUseCustomComponent(true);
513 auto placementValue = popupObj->GetProperty("placement");
514 if (placementValue->IsNumber()) {
515 auto placement = placementValue->ToNumber<int32_t>();
516 if (placement >= 0 && placement <= static_cast<int32_t>(PLACEMENT.size())) {
517 popupParam->SetPlacement(PLACEMENT[placement]);
518 }
519 }
520
521 auto maskColorValue = popupObj->GetProperty("maskColor");
522 Color maskColor;
523 if (JSViewAbstract::ParseJsColor(maskColorValue, maskColor)) {
524 popupParam->SetMaskColor(maskColor);
525 }
526
527 auto popupColorValue = popupObj->GetProperty("popupColor");
528 Color backgroundColor;
529 if (JSViewAbstract::ParseJsColor(popupColorValue, backgroundColor)) {
530 popupParam->SetBackgroundColor(backgroundColor);
531 }
532
533 auto enableArrowValue = popupObj->GetProperty("enableArrow");
534 if (enableArrowValue->IsBoolean()) {
535 popupParam->SetEnableArrow(enableArrowValue->ToBoolean());
536 }
537
538 auto autoCancelValue = popupObj->GetProperty("autoCancel");
539 if (autoCancelValue->IsBoolean()) {
540 popupParam->SetHasAction(!autoCancelValue->ToBoolean());
541 }
542
543 JSRef<JSVal> onStateChangeVal = popupObj->GetProperty("onStateChange");
544 if (onStateChangeVal->IsFunction()) {
545 std::vector<std::string> keys = { "isVisible" };
546 RefPtr<JsFunction> jsFunc =
547 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onStateChangeVal));
548 auto eventMarker = EventMarker(
549 [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), keys](const std::string& param) {
550 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
551 ACE_SCORING_EVENT("popup.onStateChange");
552 func->Execute(keys, param);
553 });
554 popupComponent->SetOnStateChange(eventMarker);
555 }
556 }
557 #endif
558
559 } // namespace
560
ColorAlphaAdapt(uint32_t origin)561 uint32_t ColorAlphaAdapt(uint32_t origin)
562 {
563 uint32_t result = origin;
564 if (origin >> COLOR_ALPHA_OFFSET == 0) {
565 result = origin | COLOR_ALPHA_VALUE;
566 }
567 return result;
568 }
569
JsScale(const JSCallbackInfo & info)570 void JSViewAbstract::JsScale(const JSCallbackInfo& info)
571 {
572 LOGD("JsScale");
573 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT};
574 if (!CheckJSCallbackInfo("JsScale", info, checkList)) {
575 return;
576 }
577
578 auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
579 AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
580 if (info[0]->IsObject()) {
581 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
582 if (!argsPtrItem || argsPtrItem->IsNull()) {
583 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
584 return;
585 }
586 if (argsPtrItem->Contains("x") || argsPtrItem->Contains("y") || argsPtrItem->Contains("z")) {
587 // default: x, y, z (1.0, 1.0, 1.0)
588 auto scaleX = 1.0f;
589 auto scaleY = 1.0f;
590 auto scaleZ = 1.0f;
591 // default centerX, centerY 50% 50%;
592 Dimension centerX = 0.5_pct;
593 Dimension centerY = 0.5_pct;
594 ParseJsScale(argsPtrItem, scaleX, scaleY, scaleZ, centerX, centerY);
595 transform->Scale(scaleX, scaleY, scaleZ, option);
596 transform->SetOriginDimension(DimensionOffset(centerX, centerY));
597 return;
598 }
599 }
600 double scale;
601 if (ParseJsDouble(info[0], scale)) {
602 transform->Scale(scale, option);
603 }
604 }
605
JsScaleX(const JSCallbackInfo & info)606 void JSViewAbstract::JsScaleX(const JSCallbackInfo& info)
607 {
608 LOGD("JsScaleX");
609 if (info.Length() < 1) {
610 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
611 return;
612 }
613
614 double scaleVal = 0.0;
615 if (!ParseJsDouble(info[0], scaleVal)) {
616 return;
617 }
618
619 auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
620 AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
621 transform->ScaleX(scaleVal, option);
622 }
623
JsScaleY(const JSCallbackInfo & info)624 void JSViewAbstract::JsScaleY(const JSCallbackInfo& info)
625 {
626 LOGD("JsScaleY");
627 if (info.Length() < 1) {
628 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
629 return;
630 }
631
632 double scaleVal = 0.0;
633 if (!ParseJsDouble(info[0], scaleVal)) {
634 return;
635 }
636
637 auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
638 AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
639 transform->ScaleY(scaleVal, option);
640 }
641
JsOpacity(const JSCallbackInfo & info)642 void JSViewAbstract::JsOpacity(const JSCallbackInfo& info)
643 {
644 LOGD("js_opacity");
645 if (info.Length() < 1) {
646 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
647 return;
648 }
649
650 double opacity = 0.0;
651 if (!ParseJsDouble(info[0], opacity)) {
652 return;
653 }
654
655 auto display = ViewStackProcessor::GetInstance()->GetDisplayComponent();
656 auto stack = ViewStackProcessor::GetInstance();
657 auto option = stack->GetImplicitAnimationOption();
658 if (!stack->IsVisualStateSet()) {
659 display->SetOpacity(opacity, option);
660 } else {
661 display->GetStateAttributes()->AddAttribute<AnimatableDouble>(DisplayStateAttribute::OPACITY,
662 AnimatableDouble(opacity, option), stack->GetVisualState());
663 if (!display->GetStateAttributes()->
664 HasAttribute(DisplayStateAttribute::OPACITY, VisualState::NORMAL)) {
665 display->GetStateAttributes()->AddAttribute<AnimatableDouble>(DisplayStateAttribute::OPACITY,
666 AnimatableDouble(display->GetOpacity(), option), VisualState::NORMAL);
667 }
668 }
669 }
670
JsTranslate(const JSCallbackInfo & info)671 void JSViewAbstract::JsTranslate(const JSCallbackInfo& info)
672 {
673 LOGD("JsTranslate");
674 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
675 JSCallbackInfoType::OBJECT };
676 if (!CheckJSCallbackInfo("JsTranslate", info, checkList)) {
677 return;
678 }
679
680 Dimension value;
681 auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
682 AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
683 if (info[0]->IsObject()) {
684 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
685 if (!argsPtrItem || argsPtrItem->IsNull()) {
686 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
687 return;
688 }
689 if (argsPtrItem->Contains("x") || argsPtrItem->Contains("y") || argsPtrItem->Contains("z")) {
690 // default: x, y, z (0.0, 0.0, 0.0)
691 auto translateX = Dimension(0.0);
692 auto translateY = Dimension(0.0);
693 auto translateZ = Dimension(0.0);
694 ParseJsTranslate(argsPtrItem, translateX, translateY, translateZ);
695 transform->Translate(translateX, translateY, translateZ, option);
696 return;
697 }
698 }
699 if (ParseJsDimensionVp(info[0], value)) {
700 transform->Translate(value, value, option);
701 }
702 }
703
JsTranslateX(const JSCallbackInfo & info)704 void JSViewAbstract::JsTranslateX(const JSCallbackInfo& info)
705 {
706 LOGD("JsTranslateX");
707 if (info.Length() < 1) {
708 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
709 return;
710 }
711 Dimension value;
712 if (!ParseJsDimensionVp(info[0], value)) {
713 return;
714 }
715
716 auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
717 AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
718 transform->TranslateX(value, option);
719 }
720
JsTranslateY(const JSCallbackInfo & info)721 void JSViewAbstract::JsTranslateY(const JSCallbackInfo& info)
722 {
723 LOGD("JsTranslateY");
724 if (info.Length() < 1) {
725 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
726 return;
727 }
728 Dimension value;
729 if (!ParseJsDimensionVp(info[0], value)) {
730 return;
731 }
732 auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
733 AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
734 transform->TranslateY(value, option);
735 }
736
JsRotate(const JSCallbackInfo & info)737 void JSViewAbstract::JsRotate(const JSCallbackInfo& info)
738 {
739 LOGD("JsRotate");
740 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT};
741 if (!CheckJSCallbackInfo("JsRotate", info, checkList)) {
742 return;
743 }
744
745 auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
746 AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
747 if (info[0]->IsObject()) {
748 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
749 if (!argsPtrItem || argsPtrItem->IsNull()) {
750 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
751 return;
752 }
753 if (argsPtrItem->Contains("x") || argsPtrItem->Contains("y") || argsPtrItem->Contains("z")) {
754 // default: dx, dy, dz (0.0, 0.0, 0.0)
755 float dx = 0.0f;
756 float dy = 0.0f;
757 float dz = 0.0f;
758 // default centerX, centerY 50% 50%;
759 Dimension centerX = 0.5_pct;
760 Dimension centerY = 0.5_pct;
761 std::optional<float> angle;
762 ParseJsRotate(argsPtrItem, dx, dy, dz, centerX, centerY, angle);
763 if (angle) {
764 transform->Rotate(dx, dy, dz, angle.value(), option);
765 transform->SetOriginDimension(DimensionOffset(centerX, centerY));
766 } else {
767 LOGE("Js JsRotate failed, not specify angle");
768 }
769 return;
770 }
771 }
772 double rotateZ;
773 if (ParseJsDouble(info[0], rotateZ)) {
774 transform->RotateZ(rotateZ, option);
775 }
776 }
777
JsRotateX(const JSCallbackInfo & info)778 void JSViewAbstract::JsRotateX(const JSCallbackInfo& info)
779 {
780 LOGD("JsRotateX");
781 if (info.Length() < 1) {
782 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
783 return;
784 }
785
786 double rotateVal = 0.0;
787 if (!ParseJsDouble(info[0], rotateVal)) {
788 return;
789 }
790
791 auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
792 AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
793 transform->RotateX(rotateVal, option);
794 }
795
JsRotateY(const JSCallbackInfo & info)796 void JSViewAbstract::JsRotateY(const JSCallbackInfo& info)
797 {
798 LOGD("JsRotateX");
799 if (info.Length() < 1) {
800 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
801 return;
802 }
803
804 double rotateVal = 0.0;
805 if (!ParseJsDouble(info[0], rotateVal)) {
806 return;
807 }
808
809 auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
810 AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
811 transform->RotateY(rotateVal, option);
812 }
813
JsTransform(const JSCallbackInfo & info)814 void JSViewAbstract::JsTransform(const JSCallbackInfo& info)
815 {
816 LOGD("JsTransform");
817 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
818 if (!CheckJSCallbackInfo("JsTransform", info, checkList)) {
819 return;
820 }
821 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
822 if (!argsPtrItem || argsPtrItem->IsNull()) {
823 LOGE("Js Parse object failed. argsPtr is null. %{public}s", info[0]->ToString().c_str());
824 return;
825 }
826 auto array = argsPtrItem->GetValue("matrix4x4");
827 const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
828 if (!array || array->IsNull() || !array->IsArray() || array->GetArraySize() != matrix4Len) {
829 LOGE("Js Parse object failed, matrix4x4 is null or not Array");
830 return;
831 }
832 std::vector<float> matrix(matrix4Len);
833 for (int32_t i = 0; i < matrix4Len; i++) {
834 double value = 0.0;
835 ParseJsonDouble(array->GetArrayItem(i), value);
836 matrix[i] = static_cast<float>(value);
837 }
838 auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
839 AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
840 transform->Matrix3d(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], matrix[6], matrix[7],
841 matrix[8], matrix[9], matrix[10], matrix[11], matrix[12], matrix[13], matrix[14], matrix[15], option);
842 }
843
JsTransition(const JSCallbackInfo & info)844 void JSViewAbstract::JsTransition(const JSCallbackInfo& info)
845 {
846 LOGD("JsTransition");
847 if (info.Length() > 1) {
848 LOGE("Too many arguments");
849 return;
850 }
851 if (info.Length() == 0) {
852 SetDefaultTransition(TransitionType::ALL);
853 return;
854 }
855 if (!info[0]->IsObject()) {
856 LOGE("arg is not Object.");
857 return;
858 }
859 auto transitionArgs = JsonUtil::ParseJsonString(info[0]->ToString());
860 ParseAndSetTransitionOption(transitionArgs);
861 }
862
ParseAndSetTransitionOption(std::unique_ptr<JsonValue> & transitionArgs)863 void JSViewAbstract::ParseAndSetTransitionOption(std::unique_ptr<JsonValue>& transitionArgs)
864 {
865 TransitionType transitionType = ParseTransitionType(transitionArgs->GetString("type", "All"));
866 bool hasEffect = false;
867 hasEffect = ParseAndSetOpacityTransition(transitionArgs, transitionType) || hasEffect;
868 hasEffect = ParseAndSetTranslateTransition(transitionArgs, transitionType) || hasEffect;
869 hasEffect = ParseAndSetScaleTransition(transitionArgs, transitionType) || hasEffect;
870 hasEffect = ParseAndSetRotateTransition(transitionArgs, transitionType) || hasEffect;
871 if (!hasEffect) {
872 SetDefaultTransition(transitionType);
873 }
874 }
875
JsWidth(const JSCallbackInfo & info)876 void JSViewAbstract::JsWidth(const JSCallbackInfo& info)
877 {
878 if (info.Length() < 1) {
879 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
880 return;
881 }
882
883 JsWidth(info[0]);
884 }
885
JsWidth(const JSRef<JSVal> & jsValue)886 bool JSViewAbstract::JsWidth(const JSRef<JSVal>& jsValue)
887 {
888 Dimension value;
889 if (!ParseJsDimensionVp(jsValue, value)) {
890 return false;
891 }
892
893 if (LessNotEqual(value.Value(), 0.0)) {
894 value.SetValue(0.0);
895 }
896
897 bool isPercentSize = value.Unit() == DimensionUnit::PERCENT ? true : false;
898 if (isPercentSize) {
899 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
900 auto renderComponent = AceType::DynamicCast<RenderComponent>(component);
901 if (renderComponent) {
902 renderComponent->SetIsPercentSize(isPercentSize);
903 }
904 }
905
906 auto stack = ViewStackProcessor::GetInstance();
907 auto box = stack->GetBoxComponent();
908 auto option = stack->GetImplicitAnimationOption();
909 if (!stack->IsVisualStateSet()) {
910 box->SetWidth(value, option);
911 } else {
912 box->GetStateAttributes()->AddAttribute<AnimatableDimension>(BoxStateAttribute::WIDTH,
913 AnimatableDimension(value, option), stack->GetVisualState());
914 if (!box->GetStateAttributes()->
915 HasAttribute(BoxStateAttribute::WIDTH, VisualState::NORMAL)) {
916 box->GetStateAttributes()->AddAttribute<AnimatableDimension>(BoxStateAttribute::WIDTH,
917 AnimatableDimension(box->GetWidth(), option), VisualState::NORMAL);
918 }
919 }
920 return true;
921 }
922
JsHeight(const JSCallbackInfo & info)923 void JSViewAbstract::JsHeight(const JSCallbackInfo& info)
924 {
925 if (info.Length() < 1) {
926 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
927 return;
928 }
929
930 JsHeight(info[0]);
931 }
932
JsHeight(const JSRef<JSVal> & jsValue)933 bool JSViewAbstract::JsHeight(const JSRef<JSVal>& jsValue)
934 {
935 Dimension value;
936 if (!ParseJsDimensionVp(jsValue, value)) {
937 return false;
938 }
939
940 if (LessNotEqual(value.Value(), 0.0)) {
941 value.SetValue(0.0);
942 }
943
944 bool isPercentSize = value.Unit() == DimensionUnit::PERCENT ? true : false;
945 if (isPercentSize) {
946 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
947 auto renderComponent = AceType::DynamicCast<RenderComponent>(component);
948 if (renderComponent) {
949 renderComponent->SetIsPercentSize(isPercentSize);
950 }
951 }
952
953 auto stack = ViewStackProcessor::GetInstance();
954 auto box = stack->GetBoxComponent();
955 auto option = stack->GetImplicitAnimationOption();
956 if (!stack->IsVisualStateSet()) {
957 box->SetHeight(value, option);
958 } else {
959 box->GetStateAttributes()->AddAttribute<AnimatableDimension>(BoxStateAttribute::HEIGHT,
960 AnimatableDimension(value, option), stack->GetVisualState());
961 if (!box->GetStateAttributes()->
962 HasAttribute(BoxStateAttribute::HEIGHT, VisualState::NORMAL)) {
963 box->GetStateAttributes()->AddAttribute<AnimatableDimension>(BoxStateAttribute::HEIGHT,
964 AnimatableDimension(box->GetHeight(), option), VisualState::NORMAL);
965 }
966 }
967 return true;
968 }
969
JsResponseRegion(const JSCallbackInfo & info)970 void JSViewAbstract::JsResponseRegion(const JSCallbackInfo& info)
971 {
972 if (info.Length() < 1) {
973 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
974 return;
975 }
976
977 std::vector<DimensionRect> result;
978 if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
979 return;
980 }
981
982 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
983 auto renderComponent = AceType::DynamicCast<RenderComponent>(component);
984 if (renderComponent) {
985 renderComponent->SetResponseRegion(result);
986 renderComponent->MarkResponseRegion(true);
987 }
988 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
989 box->SetResponseRegion(result);
990 box->MarkResponseRegion(true);
991 if (ViewStackProcessor::GetInstance()->HasClickGestureListenerComponent()) {
992 auto click = ViewStackProcessor::GetInstance()->GetClickGestureListenerComponent();
993 click->SetResponseRegion(result);
994 click->MarkResponseRegion(true);
995 }
996 if (ViewStackProcessor::GetInstance()->HasTouchListenerComponent()) {
997 auto touch = ViewStackProcessor::GetInstance()->GetTouchListenerComponent();
998 touch->SetResponseRegion(result);
999 touch->MarkResponseRegion(true);
1000 }
1001 }
1002
ParseJsDimensionRect(const JSRef<JSVal> & jsValue,DimensionRect & result)1003 bool JSViewAbstract::ParseJsDimensionRect(const JSRef<JSVal>& jsValue, DimensionRect& result)
1004 {
1005 if (!jsValue->IsObject()) {
1006 LOGE("arg is not Object.");
1007 return false;
1008 }
1009
1010 JSRef<JSObject> obj = JSRef<JSObject>::Cast(jsValue);
1011 JSRef<JSVal> x = obj->GetProperty("x");
1012 JSRef<JSVal> y = obj->GetProperty("y");
1013 JSRef<JSVal> width = obj->GetProperty("width");
1014 JSRef<JSVal> height = obj->GetProperty("height");
1015 Dimension xDimen = result.GetOffset().GetX();
1016 Dimension yDimen = result.GetOffset().GetY();
1017 Dimension widthDimen = result.GetWidth();
1018 Dimension heightDimen = result.GetHeight();
1019
1020 if (ParseJsDimension(x, xDimen, DimensionUnit::VP)) {
1021 auto offset = result.GetOffset();
1022 offset.SetX(xDimen);
1023 result.SetOffset(offset);
1024 }
1025 if (ParseJsDimension(y, yDimen, DimensionUnit::VP)) {
1026 auto offset = result.GetOffset();
1027 offset.SetY(yDimen);
1028 result.SetOffset(offset);
1029 }
1030 if (ParseJsDimension(width, widthDimen, DimensionUnit::VP)) {
1031 if (widthDimen.Unit() == DimensionUnit::PERCENT && widthDimen.Value() < 0) {
1032 return true;
1033 }
1034 result.SetWidth(widthDimen);
1035 }
1036 if (ParseJsDimension(height, heightDimen, DimensionUnit::VP)) {
1037 if (heightDimen.Unit() == DimensionUnit::PERCENT && heightDimen.Value() < 0) {
1038 return true;
1039 }
1040 result.SetHeight(heightDimen);
1041 }
1042 return true;
1043 }
1044
ParseJsResponseRegionArray(const JSRef<JSVal> & jsValue,std::vector<DimensionRect> & result)1045 bool JSViewAbstract::ParseJsResponseRegionArray(const JSRef<JSVal>& jsValue, std::vector<DimensionRect>& result)
1046 {
1047 if (!jsValue->IsArray() && !jsValue->IsObject()) {
1048 LOGE("arg is not array or Object.");
1049 return false;
1050 }
1051
1052 if (jsValue->IsArray()) {
1053 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
1054 for (size_t i = 0; i < array->Length(); i++) {
1055 Dimension xDimen = Dimension(0.0, DimensionUnit::VP);
1056 Dimension yDimen = Dimension(0.0, DimensionUnit::VP);
1057 Dimension widthDimen = Dimension(1, DimensionUnit::PERCENT);
1058 Dimension heightDimen = Dimension(1, DimensionUnit::PERCENT);
1059 DimensionOffset offsetDimen(xDimen, yDimen);
1060 DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
1061 if (ParseJsDimensionRect(array->GetValueAt(i), dimenRect)) {
1062 result.emplace_back(dimenRect);
1063 } else {
1064 LOGE("Array element is not Object.");
1065 return false;
1066 }
1067 }
1068 return true;
1069 }
1070
1071 Dimension xDimen = Dimension(0.0, DimensionUnit::VP);
1072 Dimension yDimen = Dimension(0.0, DimensionUnit::VP);
1073 Dimension widthDimen = Dimension(1, DimensionUnit::PERCENT);
1074 Dimension heightDimen = Dimension(1, DimensionUnit::PERCENT);
1075 DimensionOffset offsetDimen(xDimen, yDimen);
1076 DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
1077 if (ParseJsDimensionRect(jsValue, dimenRect)) {
1078 result.emplace_back(dimenRect);
1079 return true;
1080 } else {
1081 LOGE("Array element is not Object.");
1082 return false;
1083 }
1084 }
1085
JsSize(const JSCallbackInfo & info)1086 void JSViewAbstract::JsSize(const JSCallbackInfo& info)
1087 {
1088 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
1089 if (!CheckJSCallbackInfo("JsSize", info, checkList)) {
1090 return;
1091 }
1092
1093 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
1094 JsWidth(sizeObj->GetProperty("width"));
1095 JsHeight(sizeObj->GetProperty("height"));
1096 }
1097
JsConstraintSize(const JSCallbackInfo & info)1098 void JSViewAbstract::JsConstraintSize(const JSCallbackInfo& info)
1099 {
1100 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
1101 if (!CheckJSCallbackInfo("JsConstraintSize", info, checkList)) {
1102 return;
1103 }
1104
1105 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
1106 auto flexItem = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
1107 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
1108
1109 JSRef<JSVal> minWidthValue = sizeObj->GetProperty("minWidth");
1110 Dimension minWidth;
1111 if (ParseJsDimensionVp(minWidthValue, minWidth)) {
1112 box->SetMinWidth(minWidth);
1113 flexItem->SetMinWidth(minWidth);
1114 }
1115
1116 JSRef<JSVal> maxWidthValue = sizeObj->GetProperty("maxWidth");
1117 Dimension maxWidth;
1118 if (ParseJsDimensionVp(maxWidthValue, maxWidth)) {
1119 box->SetMaxWidth(maxWidth);
1120 flexItem->SetMaxWidth(maxWidth);
1121 }
1122
1123 JSRef<JSVal> minHeightValue = sizeObj->GetProperty("minHeight");
1124 Dimension minHeight;
1125 if (ParseJsDimensionVp(minHeightValue, minHeight)) {
1126 box->SetMinHeight(minHeight);
1127 flexItem->SetMinHeight(minHeight);
1128 }
1129
1130 JSRef<JSVal> maxHeightValue = sizeObj->GetProperty("maxHeight");
1131 Dimension maxHeight;
1132 if (ParseJsDimensionVp(maxHeightValue, maxHeight)) {
1133 box->SetMaxHeight(maxHeight);
1134 flexItem->SetMaxHeight(maxHeight);
1135 }
1136 }
1137
JsLayoutPriority(const JSCallbackInfo & info)1138 void JSViewAbstract::JsLayoutPriority(const JSCallbackInfo& info)
1139 {
1140 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER};
1141 if (!CheckJSCallbackInfo("JsLayoutPriority", info, checkList)) {
1142 return;
1143 }
1144
1145 int32_t priority;
1146 if (info[0]->IsNumber()) {
1147 priority = info[0]->ToNumber<int32_t>();
1148 } else {
1149 priority = static_cast<int32_t>(StringUtils::StringToUint(info[0]->ToString()));
1150 }
1151
1152 auto flex = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
1153 flex->SetDisplayIndex(priority);
1154 }
1155
JsLayoutWeight(const JSCallbackInfo & info)1156 void JSViewAbstract::JsLayoutWeight(const JSCallbackInfo& info)
1157 {
1158 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER};
1159 if (!CheckJSCallbackInfo("JsLayoutWeight", info, checkList)) {
1160 return;
1161 }
1162
1163 int32_t value;
1164 if (info[0]->IsNumber()) {
1165 value = info[0]->ToNumber<int32_t>();
1166 } else {
1167 value = static_cast<int32_t>(StringUtils::StringToUint(info[0]->ToString()));
1168 }
1169
1170 auto flex = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
1171 flex->SetFlexWeight(value);
1172 }
1173
JsAlign(const JSCallbackInfo & info)1174 void JSViewAbstract::JsAlign(const JSCallbackInfo& info)
1175 {
1176 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::NUMBER};
1177 if (!CheckJSCallbackInfo("JsAlign", info, checkList)) {
1178 return;
1179 }
1180 auto value = info[0]->ToNumber<int32_t>();
1181 Alignment alignment = ParseAlignment(value);
1182 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
1183 box->SetAlignment(alignment);
1184 }
1185
JsPosition(const JSCallbackInfo & info)1186 void JSViewAbstract::JsPosition(const JSCallbackInfo& info)
1187 {
1188 AnimatableDimension x;
1189 AnimatableDimension y;
1190 if (ParseLocationProps(info, x, y)) {
1191 auto flexItemComponent = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
1192 flexItemComponent->SetLeft(x);
1193 flexItemComponent->SetTop(y);
1194 flexItemComponent->SetPositionType(PositionType::ABSOLUTE);
1195 }
1196 }
1197
JsMarkAnchor(const JSCallbackInfo & info)1198 void JSViewAbstract::JsMarkAnchor(const JSCallbackInfo& info)
1199 {
1200 AnimatableDimension x;
1201 AnimatableDimension y;
1202 if (ParseLocationProps(info, x, y)) {
1203 auto flexItemComponent = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
1204 flexItemComponent->SetAnchorX(x);
1205 flexItemComponent->SetAnchorY(y);
1206 }
1207 }
1208
JsOffset(const JSCallbackInfo & info)1209 void JSViewAbstract::JsOffset(const JSCallbackInfo& info)
1210 {
1211 AnimatableDimension x;
1212 AnimatableDimension y;
1213 if (ParseLocationProps(info, x, y)) {
1214 auto flexItemComponent = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
1215 flexItemComponent->SetLeft(x);
1216 flexItemComponent->SetTop(y);
1217 flexItemComponent->SetPositionType(PositionType::OFFSET);
1218 }
1219 }
1220
JsEnabled(const JSCallbackInfo & info)1221 void JSViewAbstract::JsEnabled(const JSCallbackInfo& info)
1222 {
1223 if (info.Length() < 1) {
1224 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
1225 return;
1226 }
1227
1228 if (!info[0]->IsBoolean()) {
1229 LOGE("arg is not bool.");
1230 return;
1231 }
1232
1233 auto rootComponent = ViewStackProcessor::GetInstance()->GetRootComponent();
1234 rootComponent->SetDisabledStatus(!(info[0]->ToBoolean()));
1235 }
1236
JsAspectRatio(const JSCallbackInfo & info)1237 void JSViewAbstract::JsAspectRatio(const JSCallbackInfo& info)
1238 {
1239 if (info.Length() < 1) {
1240 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
1241 return;
1242 }
1243
1244 double value = 0.0;
1245 if (!ParseJsDouble(info[0], value)) {
1246 return;
1247 }
1248 auto boxComponent = ViewStackProcessor::GetInstance()->GetBoxComponent();
1249 AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
1250 boxComponent->SetAspectRatio(value, option);
1251 }
1252
JsOverlay(const JSCallbackInfo & info)1253 void JSViewAbstract::JsOverlay(const JSCallbackInfo& info)
1254 {
1255 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::STRING};
1256 if (!CheckJSCallbackInfo("JsOverlay", info, checkList)) {
1257 return;
1258 }
1259
1260 auto coverageComponent = ViewStackProcessor::GetInstance()->GetCoverageComponent();
1261 std::string text = info[0]->ToString();
1262 coverageComponent->SetTextVal(text);
1263 coverageComponent->SetIsOverLay(true);
1264
1265 if (info.Length() > 1 && !info[1]->IsNull()) {
1266 JSRef<JSObject> optionObj = JSRef<JSObject>::Cast(info[1]);
1267 JSRef<JSVal> alignVal = optionObj->GetProperty("align");
1268 auto value = alignVal->ToNumber<int32_t>();
1269 Alignment alignment = ParseAlignment(value);
1270 coverageComponent->SetAlignment(alignment);
1271
1272 JSRef<JSVal> val = optionObj->GetProperty("offset");
1273 if (val->IsObject()) {
1274 JSRef<JSObject> offsetObj = JSRef<JSObject>::Cast(val);
1275 JSRef<JSVal> xVal = offsetObj->GetProperty("x");
1276 Dimension x;
1277 if (ParseJsDimensionVp(xVal, x)) {
1278 coverageComponent->SetX(x);
1279 }
1280 JSRef<JSVal> yVal = offsetObj->GetProperty("y");
1281 Dimension y;
1282 if (ParseJsDimensionVp(yVal, y)) {
1283 coverageComponent->SetY(y);
1284 }
1285 }
1286 }
1287 }
1288
ParseAlignment(int32_t align)1289 Alignment JSViewAbstract::ParseAlignment(int32_t align)
1290 {
1291 Alignment alignment = Alignment::CENTER;
1292 switch (align) {
1293 case 0:
1294 alignment = Alignment::TOP_LEFT;
1295 break;
1296 case 1:
1297 alignment = Alignment::TOP_CENTER;
1298 break;
1299 case 2:
1300 alignment = Alignment::TOP_RIGHT;
1301 break;
1302 case 3:
1303 alignment = Alignment::CENTER_LEFT;
1304 break;
1305 case 4:
1306 alignment = Alignment::CENTER;
1307 break;
1308 case 5:
1309 alignment = Alignment::CENTER_RIGHT;
1310 break;
1311 case 6:
1312 alignment = Alignment::BOTTOM_LEFT;
1313 break;
1314 case 7:
1315 alignment = Alignment::BOTTOM_CENTER;
1316 break;
1317 case 8:
1318 alignment = Alignment::BOTTOM_RIGHT;
1319 break;
1320 default:
1321 LOGE("Invaild value for alignment");
1322 }
1323 return alignment;
1324 }
1325
SetVisibility(int value)1326 void JSViewAbstract::SetVisibility(int value)
1327 {
1328 auto display = ViewStackProcessor::GetInstance()->GetDisplayComponent();
1329 display->SetVisible(VisibleType(value));
1330 }
1331
JsFlexBasis(const JSCallbackInfo & info)1332 void JSViewAbstract::JsFlexBasis(const JSCallbackInfo& info)
1333 {
1334 if (info.Length() < 1) {
1335 LOGE("JsFlexBasis: The arg is wrong, it is supposed to have at least 1 arguments");
1336 return;
1337 }
1338 Dimension value;
1339 if (!ParseJsDimensionVp(info[0], value)) {
1340 return;
1341 }
1342 auto flexItem = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
1343 flexItem->SetFlexBasis(value);
1344 }
1345
JsFlexGrow(const JSCallbackInfo & info)1346 void JSViewAbstract::JsFlexGrow(const JSCallbackInfo& info)
1347 {
1348 if (info.Length() < 1) {
1349 LOGE("JsFlexGrow: The arg is wrong, it is supposed to have at least 1 arguments");
1350 return;
1351 }
1352 double value = 0.0;
1353 if (!ParseJsDouble(info[0], value)) {
1354 return;
1355 }
1356 auto flexItem = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
1357 flexItem->SetFlexGrow(value);
1358 }
1359
JsFlexShrink(const JSCallbackInfo & info)1360 void JSViewAbstract::JsFlexShrink(const JSCallbackInfo& info)
1361 {
1362 if (info.Length() < 1) {
1363 LOGE("JsFlexShrink: The arg is wrong, it is supposed to have at least 1 arguments");
1364 return;
1365 }
1366 double value = 0.0;
1367 if (!ParseJsDouble(info[0], value)) {
1368 return;
1369 }
1370 auto flexItem = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
1371 flexItem->SetFlexShrink(value);
1372 }
1373
JsDisplayPriority(const JSCallbackInfo & info)1374 void JSViewAbstract::JsDisplayPriority(const JSCallbackInfo& info)
1375 {
1376 if (info.Length() < 1) {
1377 LOGE("JsDisplayPriority: The arg is wrong, it is supposed to have at least 1 arguments");
1378 return;
1379 }
1380 double value = 0.0;
1381 if (!ParseJsDouble(info[0], value)) {
1382 return;
1383 }
1384 auto flexItem = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
1385 flexItem->SetDisplayIndex(value);
1386 }
1387
JsSharedTransition(const JSCallbackInfo & info)1388 void JSViewAbstract::JsSharedTransition(const JSCallbackInfo& info)
1389 {
1390 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::STRING};
1391 if (!CheckJSCallbackInfo("JsSharedTransition", info, checkList)) {
1392 return;
1393 }
1394 // id
1395 auto id = info[0]->ToString();
1396 if (id.empty()) {
1397 LOGE("JsSharedTransition: id is empty.");
1398 return;
1399 }
1400 auto sharedTransitionComponent = ViewStackProcessor::GetInstance()->GetSharedTransitionComponent();
1401 sharedTransitionComponent->SetShareId(id);
1402
1403 // options
1404 if (info.Length() > 1 && info[1]->IsObject()) {
1405 auto optionsArgs = JsonUtil::ParseJsonString(info[1]->ToString());
1406 // default: duration: 1000; if not specify: duration: 0
1407 int32_t duration = 0;
1408 auto durationValue = optionsArgs->GetValue("duration");
1409 if (durationValue && durationValue->IsNumber()) {
1410 duration = durationValue->GetInt();
1411 if (duration < 0) {
1412 duration = DEFAULT_DURATION;
1413 }
1414 }
1415 // default: delay: 0
1416 auto delay = optionsArgs->GetInt("delay", 0);
1417 if (delay < 0) {
1418 delay = 0;
1419 }
1420 // default: LinearCurve
1421 RefPtr<Curve> curve;
1422 auto curveArgs = optionsArgs->GetValue("curve");
1423 if (curveArgs->IsString()) {
1424 curve = CreateCurve(optionsArgs->GetString("curve", "linear"));
1425 } else if (curveArgs->IsObject()) {
1426 auto curveString = curveArgs->GetValue("__curveString");
1427 if (!curveString) {
1428 return;
1429 }
1430 curve = CreateCurve(curveString->GetString());
1431 } else {
1432 curve = AceType::MakeRefPtr<LinearCurve>();
1433 }
1434 TweenOption tweenOption;
1435 tweenOption.SetCurve(curve);
1436 tweenOption.SetDuration(static_cast<int32_t>(duration));
1437 tweenOption.SetDelay(static_cast<int32_t>(delay));
1438 // motionPath
1439
1440 if (optionsArgs->Contains("motionPath")) {
1441 MotionPathOption motionPathOption;
1442 if (ParseMotionPath(optionsArgs->GetValue("motionPath"), motionPathOption)) {
1443 tweenOption.SetMotioPathOption(motionPathOption);
1444 }
1445 }
1446 // zIndex
1447 int32_t zIndex = 0;
1448 if (optionsArgs->Contains("zIndex")) {
1449 zIndex = optionsArgs->GetInt("zIndex", 0);
1450 }
1451 // type
1452 SharedTransitionEffectType type = SharedTransitionEffectType::SHARED_EFFECT_EXCHANGE;
1453 if (optionsArgs->Contains("type")) {
1454 type = static_cast<SharedTransitionEffectType>(
1455 optionsArgs->GetInt("type", static_cast<int32_t>(SharedTransitionEffectType::SHARED_EFFECT_EXCHANGE)));
1456 }
1457 // effect: exchange
1458 auto sharedTransitionEffect =
1459 SharedTransitionEffect::GetSharedTransitionEffect(type, sharedTransitionComponent->GetShareId());
1460 sharedTransitionComponent->SetEffect(sharedTransitionEffect);
1461 sharedTransitionComponent->SetOption(tweenOption);
1462 if (zIndex != 0) {
1463 sharedTransitionComponent->SetZIndex(zIndex);
1464 }
1465 }
1466 }
1467
JsGeometryTransition(const JSCallbackInfo & info)1468 void JSViewAbstract::JsGeometryTransition(const JSCallbackInfo& info)
1469 {
1470 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::STRING};
1471 if (!CheckJSCallbackInfo("JsGeometryTransition", info, checkList)) {
1472 return;
1473 }
1474 // id
1475 auto id = info[0]->ToString();
1476 if (id.empty()) {
1477 LOGE("JsGeometryTransition: id is empty.");
1478 return;
1479 }
1480 auto boxComponent = ViewStackProcessor::GetInstance()->GetBoxComponent();
1481 boxComponent->SetGeometryTransitionId(id);
1482 }
1483
JsAlignSelf(const JSCallbackInfo & info)1484 void JSViewAbstract::JsAlignSelf(const JSCallbackInfo& info)
1485 {
1486 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::NUMBER};
1487 if (!CheckJSCallbackInfo("JsAlignSelf", info, checkList)) {
1488 return;
1489 }
1490 auto flexItem = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
1491 auto alignVal = info[0]->ToNumber<int32_t>();
1492
1493 if (alignVal >= 0 && alignVal <= MAX_ALIGN_VALUE) {
1494 flexItem->SetAlignSelf((FlexAlign)alignVal);
1495 }
1496 }
1497
JsBorderColor(const JSCallbackInfo & info)1498 void JSViewAbstract::JsBorderColor(const JSCallbackInfo& info)
1499 {
1500 if (info.Length() < 1) {
1501 LOGE("The argv is wrong, it is supposed to have at least 1 argument");
1502 return;
1503 }
1504 Color borderColor;
1505 if (!ParseJsColor(info[0], borderColor)) {
1506 return;
1507 }
1508
1509 auto stack = ViewStackProcessor::GetInstance();
1510 auto option = stack->GetImplicitAnimationOption();
1511 if (!stack->IsVisualStateSet()) {
1512 BoxComponentHelper::SetBorderColor(GetBackDecoration(), borderColor, option);
1513 } else {
1514 auto boxComponent = AceType::DynamicCast<BoxComponent>(stack->GetBoxComponent());
1515 boxComponent->GetStateAttributes()->AddAttribute<AnimatableColor>(BoxStateAttribute::BORDER_COLOR,
1516 AnimatableColor(borderColor, option), stack->GetVisualState());
1517 if (!boxComponent->GetStateAttributes()->
1518 HasAttribute(BoxStateAttribute::BORDER_COLOR, VisualState::NORMAL)) {
1519 auto c = BoxComponentHelper::GetBorderColor(GetBackDecoration());
1520 boxComponent->GetStateAttributes()->AddAttribute<AnimatableColor>(BoxStateAttribute::BORDER_COLOR,
1521 AnimatableColor(c, option), VisualState::NORMAL);
1522 }
1523 }
1524 }
1525
JsBackgroundColor(const JSCallbackInfo & info)1526 void JSViewAbstract::JsBackgroundColor(const JSCallbackInfo& info)
1527 {
1528 if (info.Length() < 1) {
1529 LOGE("The argv is wrong, it is supposed to have at least 1 argument");
1530 return;
1531 }
1532 Color backgroundColor;
1533 if (!ParseJsColor(info[0], backgroundColor)) {
1534 return;
1535 }
1536
1537 auto stack = ViewStackProcessor::GetInstance();
1538 auto boxComponent = stack->GetBoxComponent();
1539 auto option = stack->GetImplicitAnimationOption();
1540 if (!stack->IsVisualStateSet()) {
1541 boxComponent->SetColor(backgroundColor, option);
1542 } else {
1543 boxComponent->GetStateAttributes()->AddAttribute<AnimatableColor>(BoxStateAttribute::COLOR,
1544 AnimatableColor(backgroundColor, option), stack->GetVisualState());
1545 if (!boxComponent->GetStateAttributes()->
1546 HasAttribute(BoxStateAttribute::COLOR, VisualState::NORMAL)) {
1547 Color c = boxComponent->GetColor();
1548 boxComponent->GetStateAttributes()->AddAttribute<AnimatableColor>(BoxStateAttribute::COLOR,
1549 AnimatableColor(c, option), VisualState::NORMAL);
1550 }
1551 }
1552 }
1553
JsBackgroundImage(const JSCallbackInfo & info)1554 void JSViewAbstract::JsBackgroundImage(const JSCallbackInfo& info)
1555 {
1556 if (info.Length() < 1) {
1557 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
1558 return;
1559 }
1560
1561 std::string src;
1562 if (info[0]->IsString()) {
1563 src = info[0]->ToString();
1564 } else if (!ParseJsMedia(info[0], src)) {
1565 LOGE("can not parse image src.");
1566 return;
1567 }
1568
1569 auto decoration = GetBackDecoration();
1570 if (!decoration) {
1571 LOGE("The decoration is nullptr.");
1572 return;
1573 }
1574 auto image = decoration->GetImage();
1575 if (!image) {
1576 image = AceType::MakeRefPtr<BackgroundImage>();
1577 }
1578
1579 if (info[0]->IsString()) {
1580 image->SetSrc(src, GetThemeConstants());
1581 } else {
1582 image->SetParsedSrc(src);
1583 }
1584
1585 int32_t repeatIndex = 0;
1586 if (info.Length() == 2 && info[1]->IsNumber()) {
1587 repeatIndex = info[1]->ToNumber<int32_t>();
1588 }
1589 auto repeat = static_cast<ImageRepeat>(repeatIndex);
1590 image->SetImageRepeat(repeat);
1591 decoration->SetImage(image);
1592 }
1593
JsBackgroundImageSize(const JSCallbackInfo & info)1594 void JSViewAbstract::JsBackgroundImageSize(const JSCallbackInfo& info)
1595 {
1596 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT};
1597 if (!CheckJSCallbackInfo("JsBackgroungImageSize", info, checkList)) {
1598 return;
1599 }
1600 auto decoration = GetBackDecoration();
1601 if (!decoration) {
1602 LOGE("The decoration is nullptr.");
1603 return;
1604 }
1605 auto image = decoration->GetImage();
1606 if (!image) {
1607 image = AceType::MakeRefPtr<BackgroundImage>();
1608 }
1609 BackgroundImageSize bgImgSize;
1610 if (info[0]->IsNumber()) {
1611 auto sizeType = static_cast<BackgroundImageSizeType>(info[0]->ToNumber<int32_t>());
1612 bgImgSize.SetSizeTypeX(sizeType);
1613 bgImgSize.SetSizeTypeY(sizeType);
1614 } else {
1615 auto imageArgs = JsonUtil::ParseJsonString(info[0]->ToString());
1616 if (imageArgs->IsNull()) {
1617 LOGE("Js Parse failed. imageArgs is null.");
1618 return;
1619 }
1620 Dimension width;
1621 Dimension height;
1622 ParseJsonDimensionVp(imageArgs->GetValue("width"), width);
1623 ParseJsonDimensionVp(imageArgs->GetValue("height"), height);
1624 double valueWidth = width.Value();
1625 double valueHeight = height.Value();
1626 BackgroundImageSizeType typeWidth = BackgroundImageSizeType::LENGTH;
1627 BackgroundImageSizeType typeHeight = BackgroundImageSizeType::LENGTH;
1628 if (width.Unit() == DimensionUnit::PERCENT) {
1629 typeWidth = BackgroundImageSizeType::PERCENT;
1630 valueWidth = width.Value() * FULL_DIMENSION;
1631 }
1632 if (height.Unit() == DimensionUnit::PERCENT) {
1633 typeHeight = BackgroundImageSizeType::PERCENT;
1634 valueHeight = height.Value() * FULL_DIMENSION;
1635 }
1636 bgImgSize.SetSizeTypeX(typeWidth);
1637 bgImgSize.SetSizeValueX(valueWidth);
1638 bgImgSize.SetSizeTypeY(typeHeight);
1639 bgImgSize.SetSizeValueY(valueHeight);
1640 }
1641 image->SetImageSize(bgImgSize);
1642 decoration->SetImage(image);
1643 }
1644
JsBackgroundImagePosition(const JSCallbackInfo & info)1645 void JSViewAbstract::JsBackgroundImagePosition(const JSCallbackInfo& info)
1646 {
1647 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT};
1648 if (!CheckJSCallbackInfo("JsBackgroundImagePosition", info, checkList)) {
1649 return;
1650 }
1651 auto decoration = GetBackDecoration();
1652 if (!decoration) {
1653 LOGE("The decoration is nullptr.");
1654 return;
1655 }
1656 auto image = decoration->GetImage();
1657 if (!image) {
1658 image = AceType::MakeRefPtr<BackgroundImage>();
1659 }
1660 BackgroundImagePosition bgImgPosition;
1661 if (info[0]->IsNumber()) {
1662 int32_t align = info[0]->ToNumber<int32_t>();
1663 switch (align) {
1664 case 0:
1665 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT,
1666 0.0, 0.0, bgImgPosition);
1667 break;
1668 case 1:
1669 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT,
1670 HALF_DIMENSION, 0.0, bgImgPosition);
1671 break;
1672 case 2:
1673 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT,
1674 FULL_DIMENSION, 0.0, bgImgPosition);
1675 break;
1676 case 3:
1677 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT,
1678 0.0, HALF_DIMENSION, bgImgPosition);
1679 break;
1680 case 4:
1681 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT,
1682 HALF_DIMENSION, HALF_DIMENSION, bgImgPosition);
1683 break;
1684 case 5:
1685 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT,
1686 FULL_DIMENSION, HALF_DIMENSION, bgImgPosition);
1687 break;
1688 case 6:
1689 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT,
1690 0.0, FULL_DIMENSION, bgImgPosition);
1691 break;
1692 case 7:
1693 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT,
1694 HALF_DIMENSION, FULL_DIMENSION, bgImgPosition);
1695 break;
1696 case 8:
1697 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT,
1698 FULL_DIMENSION, FULL_DIMENSION, bgImgPosition);
1699 break;
1700 default:
1701 break;
1702 }
1703 } else {
1704 auto imageArgs = JsonUtil::ParseJsonString(info[0]->ToString());
1705 if (imageArgs->IsNull()) {
1706 LOGE("Js Parse failed. imageArgs is null.");
1707 return;
1708 }
1709 Dimension x;
1710 Dimension y;
1711 ParseJsonDimensionVp(imageArgs->GetValue("x"), x);
1712 ParseJsonDimensionVp(imageArgs->GetValue("y"), y);
1713 double valueX = x.Value();
1714 double valueY = y.Value();
1715 DimensionUnit typeX = DimensionUnit::PX;
1716 DimensionUnit typeY = DimensionUnit::PX;
1717 if (x.Unit() == DimensionUnit::PERCENT) {
1718 valueX = x.Value() * FULL_DIMENSION;
1719 typeX = DimensionUnit::PERCENT;
1720 }
1721 if (y.Unit() == DimensionUnit::PERCENT) {
1722 valueY = y.Value() * FULL_DIMENSION;
1723 typeY = DimensionUnit::PERCENT;
1724 }
1725 SetBgImgPosition(typeX, typeY, valueX, valueY, bgImgPosition);
1726 }
1727 image->SetImagePosition(bgImgPosition);
1728 decoration->SetImage(image);
1729 }
1730
JsBindMenu(const JSCallbackInfo & info)1731 void JSViewAbstract::JsBindMenu(const JSCallbackInfo& info)
1732 {
1733 ViewStackProcessor::GetInstance()->GetCoverageComponent();
1734 auto menuComponent = ViewStackProcessor::GetInstance()->GetMenuComponent(true);
1735 if (!menuComponent) {
1736 return;
1737 }
1738 auto click = ViewStackProcessor::GetInstance()->GetBoxComponent();
1739 RefPtr<Gesture> tapGesture = AceType::MakeRefPtr<TapGesture>();
1740 tapGesture->SetOnActionId([weak = WeakPtr<OHOS::Ace::MenuComponent>(menuComponent)](const GestureEvent& info) {
1741 auto refPtr = weak.Upgrade();
1742 if (!refPtr) {
1743 return;
1744 }
1745 auto showDialog = refPtr->GetTargetCallback();
1746 showDialog("BindMenu", info.GetGlobalLocation());
1747 });
1748 click->SetOnClick(tapGesture);
1749 auto menuTheme = GetTheme<SelectTheme>();
1750 menuComponent->SetTheme(menuTheme);
1751
1752 if (info[0]->IsArray()) {
1753 auto context = info.GetExecutionContext();
1754 auto paramArray = JSRef<JSArray>::Cast(info[0]);
1755 size_t size = paramArray->Length();
1756 for (size_t i = 0; i < size; i++) {
1757 std::string value;
1758 auto indexObject = JSRef<JSObject>::Cast(paramArray->GetValueAt(i));
1759 auto menuValue = indexObject->GetProperty("value");
1760 auto menuAction = indexObject->GetProperty("action");
1761 ParseJsString(menuValue, value);
1762 auto action = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(menuAction));
1763
1764 auto optionTheme = GetTheme<SelectTheme>();
1765 auto optionComponent = AceType::MakeRefPtr<OHOS::Ace::OptionComponent>(optionTheme);
1766 auto textComponent = AceType::MakeRefPtr<OHOS::Ace::TextComponent>(value);
1767
1768 optionComponent->SetTheme(optionTheme);
1769 optionComponent->SetText(textComponent);
1770 optionComponent->SetValue(value);
1771 optionComponent->SetCustomizedCallback([action, context] {
1772 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(context);
1773 ACE_SCORING_EVENT("menu.action");
1774 action->Execute();
1775 });
1776 menuComponent->AppendOption(optionComponent);
1777 }
1778 } else {
1779 JSRef<JSObject> menuObj;
1780 if (info[0]->IsObject()) {
1781 menuObj = JSRef<JSObject>::Cast(info[0]);
1782 } else {
1783 LOGE("No param object.");
1784 return;
1785 }
1786
1787 auto builder = menuObj->GetProperty("builder");
1788 if (!builder->IsFunction()) {
1789 LOGE("builder param is not a function.");
1790 return;
1791 }
1792 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1793 if (!builderFunc) {
1794 LOGE("builder function is null.");
1795 return;
1796 }
1797 // use another VSP instance while executing the builder function
1798 ScopedViewStackProcessor builderViewStackProcessor;
1799 {
1800 ACE_SCORING_EVENT("menu.builder");
1801 builderFunc->Execute();
1802 }
1803 auto customComponent = ViewStackProcessor::GetInstance()->Finish();
1804 if (!customComponent) {
1805 LOGE("Custom component is null.");
1806 return;
1807 }
1808
1809 auto optionTheme = GetTheme<SelectTheme>();
1810 auto optionComponent = AceType::MakeRefPtr<OHOS::Ace::OptionComponent>(optionTheme);
1811 optionComponent->SetCustomComponent(customComponent);
1812
1813 menuComponent->AppendOption(optionComponent);
1814 }
1815 }
1816
JsPadding(const JSCallbackInfo & info)1817 void JSViewAbstract::JsPadding(const JSCallbackInfo& info)
1818 {
1819 ParseMarginOrPadding(info, false);
1820 }
1821
JsMargin(const JSCallbackInfo & info)1822 void JSViewAbstract::JsMargin(const JSCallbackInfo& info)
1823 {
1824 JSViewAbstract::ParseMarginOrPadding(info, true);
1825 }
1826
ParseMarginOrPadding(const JSCallbackInfo & info,bool isMargin)1827 void JSViewAbstract::ParseMarginOrPadding(const JSCallbackInfo& info, bool isMargin)
1828 {
1829 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
1830 JSCallbackInfoType::OBJECT };
1831 if (!CheckJSCallbackInfo("ParseMarginOrPadding", info, checkList)) {
1832 return;
1833 }
1834
1835 if (info[0]->IsObject()) {
1836 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
1837 if (!argsPtrItem || argsPtrItem->IsNull()) {
1838 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
1839 return;
1840 }
1841 if (argsPtrItem->Contains("top") || argsPtrItem->Contains("bottom") || argsPtrItem->Contains("left") ||
1842 argsPtrItem->Contains("right")) {
1843 Dimension topDimen = Dimension(0.0, DimensionUnit::VP);
1844 Dimension bottomDimen = Dimension(0.0, DimensionUnit::VP);
1845 Dimension leftDimen = Dimension(0.0, DimensionUnit::VP);
1846 Dimension rightDimen = Dimension(0.0, DimensionUnit::VP);
1847 ParseJsonDimensionVp(argsPtrItem->GetValue("top"), topDimen);
1848 ParseJsonDimensionVp(argsPtrItem->GetValue("bottom"), bottomDimen);
1849 ParseJsonDimensionVp(argsPtrItem->GetValue("left"), leftDimen);
1850 ParseJsonDimensionVp(argsPtrItem->GetValue("right"), rightDimen);
1851 if (isMargin) {
1852 SetMargins(topDimen, bottomDimen, leftDimen, rightDimen);
1853 } else {
1854 SetPaddings(topDimen, bottomDimen, leftDimen, rightDimen);
1855 }
1856 return;
1857 }
1858 }
1859 AnimatableDimension length;
1860 if (!ParseJsAnimatableDimensionVp(info[0], length)) {
1861 return;
1862 }
1863 if (isMargin) {
1864 SetMargin(length);
1865 } else {
1866 SetPadding(length);
1867 }
1868 }
1869
JsBorder(const JSCallbackInfo & info)1870 void JSViewAbstract::JsBorder(const JSCallbackInfo& info)
1871 {
1872 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
1873 if (!CheckJSCallbackInfo("JsBorder", info, checkList)) {
1874 return;
1875 }
1876 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
1877 if (!argsPtrItem || argsPtrItem->IsNull()) {
1878 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
1879 info.ReturnSelf();
1880 return;
1881 }
1882
1883 auto stack = ViewStackProcessor::GetInstance();
1884 AnimationOption option = stack->GetImplicitAnimationOption();
1885 auto boxComponent = AceType::DynamicCast<BoxComponent>(stack->GetBoxComponent());
1886
1887 Dimension width;
1888 if (argsPtrItem->Contains("width") && ParseJsonDimensionVp(argsPtrItem->GetValue("width"), width)) {
1889 if (!stack->IsVisualStateSet()) {
1890 BoxComponentHelper::SetBorderWidth(GetBackDecoration(), width, option);
1891 } else {
1892 boxComponent->GetStateAttributes()->AddAttribute<AnimatableDimension>
1893 (BoxStateAttribute::BORDER_WIDTH, AnimatableDimension(width, option), stack->GetVisualState());
1894 if (!boxComponent->GetStateAttributes()->
1895 HasAttribute(BoxStateAttribute::BORDER_WIDTH, VisualState::NORMAL)) {
1896 boxComponent->GetStateAttributes()->AddAttribute<AnimatableDimension>(BoxStateAttribute::BORDER_WIDTH,
1897 AnimatableDimension(BoxComponentHelper::GetBorderWidth(GetBackDecoration()), option),
1898 VisualState::NORMAL);
1899 }
1900 }
1901 }
1902 Color color;
1903 if (argsPtrItem->Contains("color") && ParseJsonColor(argsPtrItem->GetValue("color"), color)) {
1904 if (!stack->IsVisualStateSet()) {
1905 BoxComponentHelper::SetBorderColor(GetBackDecoration(), color, option);
1906 } else {
1907 boxComponent->GetStateAttributes()->AddAttribute<AnimatableColor>(BoxStateAttribute::BORDER_COLOR,
1908 AnimatableColor(color, option), stack->GetVisualState());
1909 if (!boxComponent->GetStateAttributes()->
1910 HasAttribute(BoxStateAttribute::BORDER_COLOR, VisualState::NORMAL)) {
1911 Color c = BoxComponentHelper::GetBorderColor(GetBackDecoration());
1912 boxComponent->GetStateAttributes()->AddAttribute<AnimatableColor>
1913 (BoxStateAttribute::BORDER_COLOR, AnimatableColor(c, option), VisualState::NORMAL);
1914 }
1915 }
1916 }
1917 Dimension radius;
1918 if (argsPtrItem->Contains("radius") && ParseJsonDimensionVp(argsPtrItem->GetValue("radius"), radius)) {
1919 if (!stack->IsVisualStateSet()) {
1920 BoxComponentHelper::SetBorderRadius(GetBackDecoration(), radius, option);
1921 } else {
1922 boxComponent->GetStateAttributes()->AddAttribute<AnimatableDimension>(BoxStateAttribute::BORDER_RADIUS,
1923 AnimatableDimension(radius, option), stack->GetVisualState());
1924 if (!boxComponent->GetStateAttributes()->
1925 HasAttribute(BoxStateAttribute::BORDER_RADIUS, VisualState::NORMAL)) {
1926 boxComponent->GetStateAttributes()->AddAttribute<AnimatableDimension>(BoxStateAttribute::BORDER_RADIUS,
1927 AnimatableDimension(BoxComponentHelper::GetBorderRadius(GetBackDecoration()).GetX(), option),
1928 VisualState::NORMAL);
1929 }
1930 }
1931 }
1932 if (argsPtrItem->Contains("style")) {
1933 auto borderStyle = argsPtrItem->GetInt("style", static_cast<int32_t>(BorderStyle::SOLID));
1934 SetBorderStyle(borderStyle);
1935 }
1936 info.ReturnSelf();
1937 }
1938
JsBorderWidth(const JSCallbackInfo & info)1939 void JSViewAbstract::JsBorderWidth(const JSCallbackInfo& info)
1940 {
1941 if (info.Length() < 1) {
1942 LOGE("The argv is wrong, it is supposed to have at least 1 argument");
1943 return;
1944 }
1945 Dimension borderWidth;
1946 if (!ParseJsDimensionVp(info[0], borderWidth)) {
1947 return;
1948 }
1949 auto stack = ViewStackProcessor::GetInstance();
1950 AnimationOption option = stack->GetImplicitAnimationOption();
1951 if (!ViewStackProcessor::GetInstance()->IsVisualStateSet()) {
1952 BoxComponentHelper::SetBorderWidth(GetBackDecoration(), borderWidth, option);
1953 } else {
1954 auto boxComponent = AceType::DynamicCast<BoxComponent>(stack->GetBoxComponent());
1955 boxComponent->GetStateAttributes()->AddAttribute<AnimatableDimension>
1956 (BoxStateAttribute::BORDER_WIDTH, AnimatableDimension(borderWidth, option), stack->GetVisualState());
1957 if (!boxComponent->GetStateAttributes()->
1958 HasAttribute(BoxStateAttribute::BORDER_WIDTH, VisualState::NORMAL)) {
1959 boxComponent->GetStateAttributes()->AddAttribute<AnimatableDimension>(
1960 BoxStateAttribute::BORDER_WIDTH,
1961 AnimatableDimension(BoxComponentHelper::GetBorderWidth(GetBackDecoration()), option),
1962 VisualState::NORMAL);
1963 }
1964 }
1965 }
1966
JsBorderRadius(const JSCallbackInfo & info)1967 void JSViewAbstract::JsBorderRadius(const JSCallbackInfo& info)
1968 {
1969 if (info.Length() < 1) {
1970 LOGE("The argv is wrong, it is supposed to have at least 1 argument");
1971 return;
1972 }
1973 Dimension borderRadius;
1974 if (!ParseJsDimensionVp(info[0], borderRadius)) {
1975 return;
1976 }
1977 auto stack = ViewStackProcessor::GetInstance();
1978 AnimationOption option = stack->GetImplicitAnimationOption();
1979 if (!stack->IsVisualStateSet()) {
1980 SetBorderRadius(borderRadius, option);
1981 } else {
1982 auto boxComponent = AceType::DynamicCast<BoxComponent>(stack->GetBoxComponent());
1983 boxComponent->GetStateAttributes()->AddAttribute<AnimatableDimension>(BoxStateAttribute::BORDER_RADIUS,
1984 AnimatableDimension(borderRadius, option), stack->GetVisualState());
1985 if (!boxComponent->GetStateAttributes()->
1986 HasAttribute(BoxStateAttribute::BORDER_RADIUS, VisualState::NORMAL)) {
1987 boxComponent->GetStateAttributes()->AddAttribute<AnimatableDimension>(BoxStateAttribute::BORDER_RADIUS,
1988 AnimatableDimension(
1989 BoxComponentHelper::GetBorderRadius(GetBackDecoration()).GetX(), option), VisualState::NORMAL);
1990 }
1991 }
1992 }
1993
JsBlur(const JSCallbackInfo & info)1994 void JSViewAbstract::JsBlur(const JSCallbackInfo& info)
1995 {
1996 if (info.Length() < 1) {
1997 LOGE("The argv is wrong, it is supposed to have at least 1 argument");
1998 return;
1999 }
2000
2001 double blur = 0.0;
2002 if (!ParseJsDouble(info[0], blur)) {
2003 return;
2004 }
2005 SetBlur(blur);
2006 info.SetReturnValue(info.This());
2007 }
2008
JsColorBlend(const JSCallbackInfo & info)2009 void JSViewAbstract::JsColorBlend(const JSCallbackInfo& info)
2010 {
2011 if (info.Length() < 1) {
2012 LOGE("The argv is wrong, it is supposed to have at least 1 argument");
2013 return;
2014 }
2015 Color colorBlend;
2016 if (!ParseJsColor(info[0], colorBlend)) {
2017 return;
2018 }
2019 SetColorBlend(colorBlend);
2020 info.SetReturnValue(info.This());
2021 }
2022
JsBackdropBlur(const JSCallbackInfo & info)2023 void JSViewAbstract::JsBackdropBlur(const JSCallbackInfo& info)
2024 {
2025 if (info.Length() < 1) {
2026 LOGE("The argv is wrong, it is supposed to have at least 1 argument");
2027 return;
2028 }
2029
2030 double blur = 0.0;
2031 if (!ParseJsDouble(info[0], blur)) {
2032 return;
2033 }
2034 SetBackdropBlur(blur);
2035 info.SetReturnValue(info.This());
2036 }
2037
JsWindowBlur(const JSCallbackInfo & info)2038 void JSViewAbstract::JsWindowBlur(const JSCallbackInfo& info)
2039 {
2040 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
2041 if (!CheckJSCallbackInfo("JsWindowBlur", info, checkList)) {
2042 return;
2043 }
2044
2045 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
2046 if (!argsPtrItem || argsPtrItem->IsNull()) {
2047 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
2048 return;
2049 }
2050 double progress = 0.0;
2051 ParseJsonDouble(argsPtrItem->GetValue("percent"), progress);
2052 auto style = argsPtrItem->GetInt("style", static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT));
2053
2054 progress = std::clamp(progress, 0.0, 1.0);
2055 style = std::clamp(style, static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT),
2056 static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_XLARGE_DARK));
2057
2058 SetWindowBlur(static_cast<float>(progress), static_cast<WindowBlurStyle>(style));
2059 info.SetReturnValue(info.This());
2060 }
2061
ParseJsDimension(const JSRef<JSVal> & jsValue,Dimension & result,DimensionUnit defaultUnit)2062 bool JSViewAbstract::ParseJsDimension(const JSRef<JSVal>& jsValue, Dimension& result, DimensionUnit defaultUnit)
2063 {
2064 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
2065 LOGE("arg is not Number, String or Object.");
2066 return false;
2067 }
2068
2069 if (jsValue->IsNumber()) {
2070 result = Dimension(jsValue->ToNumber<double>(), defaultUnit);
2071 return true;
2072 }
2073 if (jsValue->IsString()) {
2074 result = StringUtils::StringToDimensionWithUnit(jsValue->ToString(), defaultUnit);
2075 return true;
2076 }
2077 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
2078 JSRef<JSVal> resId = jsObj->GetProperty("id");
2079 if (!resId->IsNumber()) {
2080 LOGW("resId is not number");
2081 return false;
2082 }
2083
2084 auto themeConstants = GetThemeConstants();
2085 if (!themeConstants) {
2086 LOGE("themeConstants is nullptr");
2087 return false;
2088 }
2089 result = themeConstants->GetDimension(resId->ToNumber<uint32_t>());
2090 return true;
2091 }
2092
ParseJsDimensionVp(const JSRef<JSVal> & jsValue,Dimension & result)2093 bool JSViewAbstract::ParseJsDimensionVp(const JSRef<JSVal>& jsValue, Dimension& result)
2094 {
2095 // 'vp' -> the value varies with piexl density of device.
2096 return ParseJsDimension(jsValue, result, DimensionUnit::VP);
2097 }
2098
ParseJsAnimatableDimensionVp(const JSRef<JSVal> & jsValue,AnimatableDimension & result)2099 bool JSViewAbstract::ParseJsAnimatableDimensionVp(const JSRef<JSVal>& jsValue, AnimatableDimension& result)
2100 {
2101 if (ParseJsDimensionVp(jsValue, result)) {
2102 AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
2103 result.SetAnimationOption(option);
2104 return true;
2105 }
2106 return false;
2107 }
2108
ParseJsDimensionFp(const JSRef<JSVal> & jsValue,Dimension & result)2109 bool JSViewAbstract::ParseJsDimensionFp(const JSRef<JSVal>& jsValue, Dimension& result)
2110 {
2111 // the 'fp' unit is used for text secnes.
2112 return ParseJsDimension(jsValue, result, DimensionUnit::FP);
2113 }
2114
ParseJsDimensionPx(const JSRef<JSVal> & jsValue,Dimension & result)2115 bool JSViewAbstract::ParseJsDimensionPx(const JSRef<JSVal>& jsValue, Dimension& result)
2116 {
2117 return ParseJsDimension(jsValue, result, DimensionUnit::PX);
2118 }
2119
ParseJsDouble(const JSRef<JSVal> & jsValue,double & result)2120 bool JSViewAbstract::ParseJsDouble(const JSRef<JSVal>& jsValue, double& result)
2121 {
2122 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
2123 LOGE("arg is not Number, String or Object.");
2124 return false;
2125 }
2126 if (jsValue->IsNumber()) {
2127 result = jsValue->ToNumber<double>();
2128 return true;
2129 }
2130 if (jsValue->IsString()) {
2131 return StringUtils::StringToDouble(jsValue->ToString(), result);
2132 }
2133 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
2134 JSRef<JSVal> resId = jsObj->GetProperty("id");
2135 if (!resId->IsNumber()) {
2136 LOGW("resId is not number");
2137 return false;
2138 }
2139
2140 auto themeConstants = GetThemeConstants();
2141 if (!themeConstants) {
2142 LOGW("themeConstants is nullptr");
2143 return false;
2144 }
2145 result = themeConstants->GetDouble(resId->ToNumber<uint32_t>());
2146 return true;
2147 }
2148
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result)2149 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result)
2150 {
2151 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
2152 LOGE("arg is not Number, String or Object.");
2153 return false;
2154 }
2155 if (jsValue->IsNumber()) {
2156 result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>()));
2157 return true;
2158 }
2159 if (jsValue->IsString()) {
2160 result = Color::FromString(jsValue->ToString());
2161 return true;
2162 }
2163 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
2164 JSRef<JSVal> resId = jsObj->GetProperty("id");
2165 if (!resId->IsNumber()) {
2166 LOGW("resId is not number");
2167 return false;
2168 }
2169
2170 auto themeConstants = GetThemeConstants();
2171 if (!themeConstants) {
2172 LOGW("themeConstants is nullptr");
2173 return false;
2174 }
2175 result = themeConstants->GetColor(resId->ToNumber<uint32_t>());
2176 return true;
2177 }
2178
ParseJsFontFamilies(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)2179 bool JSViewAbstract::ParseJsFontFamilies(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
2180 {
2181 result.clear();
2182 if (!jsValue->IsString() && !jsValue->IsObject()) {
2183 LOGE("arg is not String or Object.");
2184 return false;
2185 }
2186 if (jsValue->IsString()) {
2187 result = ConvertStrToFontFamilies(jsValue->ToString());
2188 return true;
2189 }
2190 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
2191 JSRef<JSVal> resId = jsObj->GetProperty("id");
2192 if (!resId->IsNumber()) {
2193 LOGW("resId is not number");
2194 return false;
2195 }
2196
2197 auto themeConstants = GetThemeConstants();
2198 if (!themeConstants) {
2199 LOGW("themeConstants is nullptr");
2200 return false;
2201 }
2202 result.emplace_back(themeConstants->GetString(resId->ToNumber<uint32_t>()));
2203 return true;
2204 }
2205
ParseJsString(const JSRef<JSVal> & jsValue,std::string & result)2206 bool JSViewAbstract::ParseJsString(const JSRef<JSVal>& jsValue, std::string& result)
2207 {
2208 if (!jsValue->IsString() && !jsValue->IsObject()) {
2209 LOGE("arg is not String or Object.");
2210 return false;
2211 }
2212
2213 if (jsValue->IsString()) {
2214 LOGD("jsValue->IsString()");
2215 result = jsValue->ToString();
2216 return true;
2217 }
2218
2219 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
2220 JSRef<JSVal> type = jsObj->GetProperty("type");
2221 if (!type->IsNumber()) {
2222 LOGW("type is not number");
2223 return false;
2224 }
2225
2226 JSRef<JSVal> resId = jsObj->GetProperty("id");
2227 if (!resId->IsNumber()) {
2228 LOGW("resId is not number");
2229 return false;
2230 }
2231
2232 auto themeConstants = GetThemeConstants();
2233 if (!themeConstants) {
2234 LOGW("themeConstants is nullptr");
2235 return false;
2236 }
2237
2238 JSRef<JSVal> args = jsObj->GetProperty("params");
2239 if (!args->IsArray()) {
2240 LOGW("args is not array");
2241 return false;
2242 }
2243
2244 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
2245 if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::STRING)) {
2246 auto originStr = themeConstants->GetString(resId->ToNumber<uint32_t>());
2247 ReplaceHolder(originStr, params, 0);
2248 result = originStr;
2249 } else if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::PLURAL)) {
2250 auto countJsVal = params->GetValueAt(0);
2251 int count = 0;
2252 if (!countJsVal->IsNumber()) {
2253 LOGW("pluralString, pluralnumber is not number");
2254 return false;
2255 }
2256 count = countJsVal->ToNumber<int>();
2257 auto pluralStr = themeConstants->GetPluralString(resId->ToNumber<uint32_t>(), count);
2258 ReplaceHolder(pluralStr, params, 1);
2259 result = pluralStr;
2260 } else {
2261 return false;
2262 }
2263
2264 return true;
2265 }
2266
ParseJsMedia(const JSRef<JSVal> & jsValue,std::string & result)2267 bool JSViewAbstract::ParseJsMedia(const JSRef<JSVal>& jsValue, std::string& result)
2268 {
2269 if (!jsValue->IsObject() && !jsValue->IsString()) {
2270 LOGE("arg is not Object and String.");
2271 return false;
2272 }
2273 if (jsValue->IsString()) {
2274 result = jsValue->ToString();
2275 return true;
2276 }
2277 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
2278 JSRef<JSVal> type = jsObj->GetProperty("type");
2279 JSRef<JSVal> resId = jsObj->GetProperty("id");
2280 if (!resId->IsNull() && !type->IsNull() && type->IsNumber() && resId->IsNumber()) {
2281 auto themeConstants = GetThemeConstants();
2282 if (!themeConstants) {
2283 LOGW("themeConstants is nullptr");
2284 return false;
2285 }
2286 auto typeInteger = type->ToNumber<int32_t>();
2287 if (typeInteger == static_cast<int>(ResourceType::MEDIA)) {
2288 result = themeConstants->GetMediaPath(resId->ToNumber<uint32_t>());
2289 return true;
2290 }
2291 if (typeInteger == static_cast<int>(ResourceType::RAWFILE)) {
2292 JSRef<JSVal> args = jsObj->GetProperty("params");
2293 if (!args->IsArray()) {
2294 LOGW("args is not Array");
2295 return false;
2296 }
2297 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
2298 auto fileName = params->GetValueAt(0);
2299 if (!fileName->IsString()) {
2300 LOGW("fileName is not String");
2301 return false;
2302 }
2303 result = themeConstants->GetRawfile(fileName->ToString());
2304 return true;
2305 }
2306 LOGE("JSImage::Create ParseJsMedia type is wrong");
2307 return false;
2308 }
2309 LOGI("input value is not string or number, using PixelMap");
2310 return false;
2311 }
2312
ParseJsBool(const JSRef<JSVal> & jsValue,bool & result)2313 bool JSViewAbstract::ParseJsBool(const JSRef<JSVal>& jsValue, bool& result)
2314 {
2315 if (!jsValue->IsBoolean() && !jsValue->IsObject()) {
2316 LOGE("arg is not bool or Object.");
2317 return false;
2318 }
2319
2320 if (jsValue->IsBoolean()) {
2321 LOGD("jsValue->IsBoolean()");
2322 result = jsValue->ToBoolean();
2323 return true;
2324 }
2325
2326 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
2327 JSRef<JSVal> type = jsObj->GetProperty("type");
2328 if (!type->IsNumber()) {
2329 LOGW("type is not number");
2330 return false;
2331 }
2332
2333 JSRef<JSVal> resId = jsObj->GetProperty("id");
2334 if (!resId->IsNumber()) {
2335 LOGW("resId is not number");
2336 return false;
2337 }
2338
2339 auto themeConstants = GetThemeConstants();
2340 if (!themeConstants) {
2341 LOGW("themeConstants is nullptr");
2342 return false;
2343 }
2344
2345 if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::BOOLEAN)) {
2346 result = themeConstants->GetBoolean(resId->ToNumber<uint32_t>());
2347 return true;
2348 } else {
2349 return false;
2350 }
2351 }
2352
ParseJsInteger(const JSRef<JSVal> & jsValue,uint32_t & result)2353 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, uint32_t& result)
2354 {
2355 if (!jsValue->IsNumber() && !jsValue->IsObject()) {
2356 LOGE("arg is not number or Object.");
2357 return false;
2358 }
2359
2360 if (jsValue->IsNumber()) {
2361 LOGD("jsValue->IsNumber()");
2362 result = jsValue->ToNumber<uint32_t>();
2363 return true;
2364 }
2365
2366 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
2367 JSRef<JSVal> type = jsObj->GetProperty("type");
2368 if (!type->IsNumber()) {
2369 LOGW("type is not number");
2370 return false;
2371 }
2372
2373 JSRef<JSVal> resId = jsObj->GetProperty("id");
2374 if (!resId->IsNumber()) {
2375 LOGW("resId is not number");
2376 return false;
2377 }
2378
2379 auto themeConstants = GetThemeConstants();
2380 if (!themeConstants) {
2381 LOGW("themeConstants is nullptr");
2382 return false;
2383 }
2384
2385 if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::INTEGER)) {
2386 result = static_cast<uint32_t>(themeConstants->GetInt(resId->ToNumber<uint32_t>()));
2387 return true;
2388 } else {
2389 return false;
2390 }
2391 }
2392
ParseJsIntegerArray(const JSRef<JSVal> & jsValue,std::vector<uint32_t> & result)2393 bool JSViewAbstract::ParseJsIntegerArray(const JSRef<JSVal>& jsValue, std::vector<uint32_t>& result)
2394 {
2395 if (!jsValue->IsArray() && !jsValue->IsObject()) {
2396 LOGE("arg is not array or Object.");
2397 return false;
2398 }
2399
2400 if (jsValue->IsArray()) {
2401 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
2402 for (size_t i = 0; i < array->Length(); i++) {
2403 JSRef<JSVal> value = array->GetValueAt(i);
2404 if (value->IsNumber()) {
2405 result.emplace_back(value->ToNumber<uint32_t>());
2406 } else if (value->IsObject()) {
2407 uint32_t singleResInt;
2408 if (ParseJsInteger(value, singleResInt)) {
2409 result.emplace_back(singleResInt);
2410 } else {
2411 return false;
2412 }
2413 } else {
2414 return false;
2415 }
2416 }
2417 return true;
2418 }
2419
2420 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
2421 JSRef<JSVal> type = jsObj->GetProperty("type");
2422 if (!type->IsNumber()) {
2423 LOGW("type is not number");
2424 return false;
2425 }
2426
2427 JSRef<JSVal> resId = jsObj->GetProperty("id");
2428 if (!resId->IsNumber()) {
2429 LOGW("resId is not number");
2430 return false;
2431 }
2432
2433 auto themeConstants = GetThemeConstants();
2434 if (!themeConstants) {
2435 LOGW("themeConstants is nullptr");
2436 return false;
2437 }
2438
2439 if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::INTARRAY)) {
2440 result = themeConstants->GetIntArray(resId->ToNumber<uint32_t>());
2441 return true;
2442 } else {
2443 return false;
2444 }
2445 }
2446
ParseJsStrArray(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)2447 bool JSViewAbstract::ParseJsStrArray(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
2448 {
2449 if (!jsValue->IsArray() && !jsValue->IsObject()) {
2450 LOGE("arg is not array or Object.");
2451 return false;
2452 }
2453
2454 if (jsValue->IsArray()) {
2455 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
2456 for (size_t i = 0; i < array->Length(); i++) {
2457 JSRef<JSVal> value = array->GetValueAt(i);
2458 if (value->IsString()) {
2459 result.emplace_back(value->ToString());
2460 } else if (value->IsObject()) {
2461 std::string singleResStr;
2462 if (ParseJsString(value, singleResStr)) {
2463 result.emplace_back(singleResStr);
2464 } else {
2465 return false;
2466 }
2467 } else {
2468 return false;
2469 }
2470 }
2471 return true;
2472 }
2473
2474 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
2475 JSRef<JSVal> type = jsObj->GetProperty("type");
2476 if (!type->IsNumber()) {
2477 LOGW("type is not number");
2478 return false;
2479 }
2480
2481 JSRef<JSVal> resId = jsObj->GetProperty("id");
2482 if (!resId->IsNumber()) {
2483 LOGW("resId is not number");
2484 return false;
2485 }
2486
2487 auto themeConstants = GetThemeConstants();
2488 if (!themeConstants) {
2489 LOGW("themeConstants is nullptr");
2490 return false;
2491 }
2492
2493 if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::STRARRAY)) {
2494 result = themeConstants->GetStringArray(resId->ToNumber<uint32_t>());
2495 return true;
2496 } else {
2497 return false;
2498 }
2499 }
2500
ParseSize(const JSCallbackInfo & info)2501 std::pair<Dimension, Dimension> JSViewAbstract::ParseSize(const JSCallbackInfo& info)
2502 {
2503 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
2504 if (!CheckJSCallbackInfo("ParseSize", info, checkList)) {
2505 return std::pair<Dimension, Dimension>();
2506 }
2507 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
2508 if (!argsPtrItem || argsPtrItem->IsNull()) {
2509 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
2510 info.SetReturnValue(info.This());
2511 return std::pair<Dimension, Dimension>();
2512 }
2513 Dimension width;
2514 Dimension height;
2515 if (!ParseJsonDimensionVp(argsPtrItem->GetValue("width"), width) ||
2516 !ParseJsonDimensionVp(argsPtrItem->GetValue("height"), height)) {
2517 return std::pair<Dimension, Dimension>();
2518 }
2519 LOGD("JsSize width = %lf unit = %d, height = %lf unit = %d", width.Value(), width.Unit(), height.Value(),
2520 height.Unit());
2521 info.SetReturnValue(info.This());
2522 return std::pair<Dimension, Dimension>(width, height);
2523 }
2524
JsUseAlign(const JSCallbackInfo & info)2525 void JSViewAbstract::JsUseAlign(const JSCallbackInfo& info)
2526 {
2527 if (info.Length() < 2) {
2528 LOGE("The arg is wrong, it is supposed to have atleast 2 arguments");
2529 return;
2530 }
2531
2532 if (!info[0]->IsObject() && !info[1]->IsObject()) {
2533 LOGE("arg is not IsObject.");
2534 return;
2535 }
2536
2537 AlignDeclaration* declaration = JSRef<JSObject>::Cast(info[0])->Unwrap<AlignDeclaration>();
2538 if (declaration == nullptr) {
2539 LOGE("declaration is nullptr");
2540 return;
2541 }
2542
2543 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
2544 JSRef<JSVal> side = obj->GetProperty("side");
2545 JSRef<JSVal> offset = obj->GetProperty("offset");
2546
2547 if (!side->IsNumber()) {
2548 LOGE("side is not Number [%s]", side->ToString().c_str());
2549 return;
2550 }
2551
2552 auto sideValue = side->ToNumber<int32_t>();
2553
2554 if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::HORIZONTAL) {
2555 if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::START) ||
2556 sideValue > static_cast<int32_t>(AlignDeclaration::Edge::END)) {
2557 LOGE("side should be Edge.Start Edge.Middle or Edge.End with HorizontalAlignDeclaration");
2558 return;
2559 }
2560 } else if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::VERTICAL) {
2561 if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::TOP) ||
2562 sideValue > static_cast<int32_t>(AlignDeclaration::Edge::BASELINE)) {
2563 LOGE("side should be Edge.Top Edge.Center Edge.Bottom or Edge.Baseline with VerticalAlignDeclaration");
2564 return;
2565 }
2566 }
2567 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
2568 box->SetAlignDeclarationPtr(declaration);
2569 box->SetUseAlignSide(static_cast<AlignDeclaration::Edge>(sideValue));
2570 Dimension offsetDimension;
2571 if (ParseJsDimensionVp(offset, offsetDimension)) {
2572 box->SetUseAlignOffset(offsetDimension);
2573 }
2574 }
2575
JsGridSpan(const JSCallbackInfo & info)2576 void JSViewAbstract::JsGridSpan(const JSCallbackInfo& info)
2577 {
2578 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::NUMBER};
2579 if (!CheckJSCallbackInfo("JsGridSpan", info, checkList)) {
2580 return;
2581 }
2582 auto gridContainerInfo = JSGridContainer::GetContainer();
2583 if (gridContainerInfo != nullptr) {
2584 auto span = info[0]->ToNumber<uint32_t>();
2585 auto builder = ViewStackProcessor::GetInstance()->GetBoxComponent()->GetGridColumnInfoBuilder();
2586 builder->SetParent(gridContainerInfo);
2587 builder->SetColumns(span);
2588 }
2589 }
2590
JsGridOffset(const JSCallbackInfo & info)2591 void JSViewAbstract::JsGridOffset(const JSCallbackInfo& info)
2592 {
2593 if (info.Length() < 1) {
2594 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
2595 return;
2596 }
2597
2598 auto gridContainerInfo = JSGridContainer::GetContainer();
2599 if (info[0]->IsNumber() && gridContainerInfo != nullptr) {
2600 auto builder = ViewStackProcessor::GetInstance()->GetBoxComponent()->GetGridColumnInfoBuilder();
2601 builder->SetParent(gridContainerInfo);
2602 int32_t offset = info[0]->ToNumber<int32_t>();
2603 builder->SetOffset(offset);
2604 }
2605 }
2606
ParseSpanAndOffset(const JSRef<JSVal> & val,uint32_t & span,int32_t & offset)2607 static bool ParseSpanAndOffset(const JSRef<JSVal>& val, uint32_t& span, int32_t& offset)
2608 {
2609 // {lg: 4}
2610 if (val->IsNumber()) {
2611 span = val->ToNumber<uint32_t>();
2612 return true;
2613 }
2614
2615 if (!val->IsObject()) {
2616 LOGE("The argument is not object or number.");
2617 return false;
2618 }
2619
2620 // {lg: {span: 1, offset: 2}}
2621 JSRef<JSObject> obj = JSRef<JSObject>::Cast(val);
2622 span = obj->GetProperty("span")->ToNumber<uint32_t>();
2623 offset = obj->GetProperty("offset")->ToNumber<int32_t>();
2624 return true;
2625 }
2626
JsUseSizeType(const JSCallbackInfo & info)2627 void JSViewAbstract::JsUseSizeType(const JSCallbackInfo& info)
2628 {
2629 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
2630 if (!CheckJSCallbackInfo("JsUseSizeType", info, checkList)) {
2631 return;
2632 }
2633 auto gridContainerInfo = JSGridContainer::GetContainer();
2634 if (gridContainerInfo == nullptr) {
2635 LOGE("No valid grid container.");
2636 return;
2637 }
2638 auto builder = ViewStackProcessor::GetInstance()->GetBoxComponent()->GetGridColumnInfoBuilder();
2639 builder->SetParent(gridContainerInfo);
2640
2641 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
2642 // keys order must be strictly refer to GridSizeType
2643 const char* keys[] = { "", "xs", "sm", "md", "lg" };
2644 for (uint32_t i = 1; i < sizeof(keys) / sizeof(const char*); i++) {
2645 JSRef<JSVal> val = sizeObj->GetProperty(keys[i]);
2646 if (val->IsNull() || val->IsEmpty()) {
2647 continue;
2648 }
2649 uint32_t span = 0;
2650 int32_t offset = 0;
2651 if (ParseSpanAndOffset(val, span, offset)) {
2652 builder->SetSizeColumn(static_cast<GridSizeType>(i), span);
2653 builder->SetOffset(offset, static_cast<GridSizeType>(i));
2654 }
2655 }
2656 }
2657
JsZIndex(const JSCallbackInfo & info)2658 void JSViewAbstract::JsZIndex(const JSCallbackInfo& info)
2659 {
2660 if (info.Length() < 1) {
2661 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
2662 return;
2663 }
2664
2665 int zIndex = 0;
2666 if (info[0]->IsNumber()) {
2667 zIndex = info[0]->ToNumber<int>();
2668 }
2669 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
2670 auto renderComponent = AceType::DynamicCast<RenderComponent>(component);
2671 if (renderComponent) {
2672 renderComponent->SetZIndex(zIndex);
2673 }
2674 }
2675
Pop()2676 void JSViewAbstract::Pop()
2677 {
2678 ViewStackProcessor::GetInstance()->Pop();
2679 }
2680
JsOnDragStart(const JSCallbackInfo & info)2681 void JSViewAbstract::JsOnDragStart(const JSCallbackInfo& info)
2682 {
2683 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::FUNCTION};
2684 if (!CheckJSCallbackInfo("JsOnDragStart", info, checkList)) {
2685 return;
2686 }
2687
2688 RefPtr<JsDragFunction> jsOnDragStartFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
2689 auto onDragStartId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragStartFunc)](
2690 const RefPtr<DragEvent>& info, const std::string &extraParams) -> DragItemInfo {
2691 DragItemInfo itemInfo;
2692 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, itemInfo);
2693
2694 auto ret = func->Execute(info, extraParams);
2695 if (!ret->IsObject()) {
2696 LOGE("builder param is not an object.");
2697 return itemInfo;
2698 }
2699 auto componnet = ParseDragItemComponent(ret);
2700 if (componnet) {
2701 LOGI("use custom builder param.");
2702 itemInfo.customComponent = componnet;
2703 return itemInfo;
2704 }
2705
2706 auto builderObj = JSRef<JSObject>::Cast(ret);
2707 #if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM)
2708 auto pixmap = builderObj->GetProperty("pixelMap");
2709 itemInfo.pixelMap = CreatePixelMapFromNapiValue(pixmap);
2710 #endif
2711 auto extarInfo = builderObj->GetProperty("extraInfo");
2712 ParseJsString(extarInfo, itemInfo.extraInfo);
2713 auto component = ParseDragItemComponent(builderObj->GetProperty("builder"));
2714 itemInfo.customComponent = component;
2715 return itemInfo;
2716 };
2717 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
2718 box->SetOnDragStartId(onDragStartId);
2719 }
2720
ParseDragItemComponent(const JSRef<JSVal> & info)2721 RefPtr<Component> JSViewAbstract::ParseDragItemComponent(const JSRef<JSVal>& info)
2722 {
2723 JSRef<JSVal> builder;
2724 if (info->IsObject()) {
2725 auto builderObj = JSRef<JSObject>::Cast(info);
2726 builder = builderObj->GetProperty("builder");
2727 } else if (info->IsFunction()) {
2728 builder = info;
2729 } else {
2730 return nullptr;
2731 }
2732 if (!builder->IsFunction()) {
2733 return nullptr;
2734 }
2735 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
2736 if (!builderFunc) {
2737 return nullptr;
2738 }
2739 // use another VSP instance while executing the builder function
2740 ScopedViewStackProcessor builderViewStackProcessor;
2741 {
2742 ACE_SCORING_EVENT("onDragStart.builder");
2743 builderFunc->Execute();
2744 }
2745 auto component = ViewStackProcessor::GetInstance()->Finish();
2746 if (!component) {
2747 LOGE("Custom component is null.");
2748 }
2749 return component;
2750 }
2751
JsOnDragEnter(const JSCallbackInfo & info)2752 void JSViewAbstract::JsOnDragEnter(const JSCallbackInfo& info)
2753 {
2754 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::FUNCTION};
2755 if (!CheckJSCallbackInfo("JsOnDragEnter", info, checkList)) {
2756 return;
2757 }
2758 RefPtr<JsDragFunction> jsOnDragEnterFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
2759 auto onDragEnterId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEnterFunc)](
2760 const RefPtr<DragEvent>& info, const std::string &extraParams) {
2761 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2762 ACE_SCORING_EVENT("onDragEnter");
2763 func->Execute(info, extraParams);
2764 };
2765 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
2766 box->SetOnDragEnterId(onDragEnterId);
2767 }
2768
JsOnDragMove(const JSCallbackInfo & info)2769 void JSViewAbstract::JsOnDragMove(const JSCallbackInfo& info)
2770 {
2771 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::FUNCTION};
2772 if (!CheckJSCallbackInfo("JsOnDragMove", info, checkList)) {
2773 return;
2774 }
2775 RefPtr<JsDragFunction> jsOnDragMoveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
2776 auto onDragMoveId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragMoveFunc)](
2777 const RefPtr<DragEvent>& info, const std::string &extraParams) {
2778 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2779 ACE_SCORING_EVENT("onDragMove");
2780 func->Execute(info, extraParams);
2781 };
2782 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
2783 box->SetOnDragMoveId(onDragMoveId);
2784 }
2785
JsOnDragLeave(const JSCallbackInfo & info)2786 void JSViewAbstract::JsOnDragLeave(const JSCallbackInfo& info)
2787 {
2788 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::FUNCTION};
2789 if (!CheckJSCallbackInfo("JsOnDragLeave", info, checkList)) {
2790 return;
2791 }
2792 RefPtr<JsDragFunction> jsOnDragLeaveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
2793 auto onDragLeaveId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragLeaveFunc)](
2794 const RefPtr<DragEvent>& info, const std::string &extraParams) {
2795 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2796 ACE_SCORING_EVENT("onDragLeave");
2797 func->Execute(info, extraParams);
2798 };
2799 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
2800 box->SetOnDragLeaveId(onDragLeaveId);
2801 }
2802
JsOnDrop(const JSCallbackInfo & info)2803 void JSViewAbstract::JsOnDrop(const JSCallbackInfo& info)
2804 {
2805 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::FUNCTION};
2806 if (!CheckJSCallbackInfo("JsOnDrop", info, checkList)) {
2807 return;
2808 }
2809 RefPtr<JsDragFunction> jsOnDropFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
2810 auto onDropId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDropFunc)](
2811 const RefPtr<DragEvent>& info, const std::string &extraParams) {
2812 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2813 ACE_SCORING_EVENT("onDrop");
2814 func->Execute(info, extraParams);
2815 };
2816 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
2817 box->SetOnDropId(onDropId);
2818 }
2819
JsOnAreaChange(const JSCallbackInfo & info)2820 void JSViewAbstract::JsOnAreaChange(const JSCallbackInfo& info)
2821 {
2822 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::FUNCTION};
2823 if (!CheckJSCallbackInfo("JsOnAreaChange", info, checkList)) {
2824 return;
2825 }
2826 auto jsOnAreaChangeFunction = AceType::MakeRefPtr<JsOnAreaChangeFunction>(JSRef<JSFunc>::Cast(info[0]));
2827 auto onAreaChangeCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAreaChangeFunction)](
2828 const Rect& oldRect, const Offset& oldOrigin, const Rect& rect,
2829 const Offset& origin) {
2830 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2831 ACE_SCORING_EVENT("onAreaChange");
2832 func->Execute(oldRect, oldOrigin, rect, origin);
2833 };
2834 auto boxComponent = ViewStackProcessor::GetInstance()->GetBoxComponent();
2835 boxComponent->GetEventExtensions()->GetOnAreaChangeExtension()->AddOnAreaChangeEvent(
2836 std::move(onAreaChangeCallback));
2837 }
2838
2839 #ifndef WEARABLE_PRODUCT
JsBindPopup(const JSCallbackInfo & info)2840 void JSViewAbstract::JsBindPopup(const JSCallbackInfo& info)
2841 {
2842 if (info.Length() < 2) {
2843 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
2844 return;
2845 }
2846
2847 if (!info[0]->IsBoolean() && !info[0]->IsObject()) {
2848 LOGE("The first param type is not bool or object, invaild.");
2849 return;
2850 }
2851
2852 if (!info[1]->IsObject()) {
2853 LOGE("The second param type is not object, invaild.");
2854 return;
2855 }
2856
2857 ViewStackProcessor::GetInstance()->GetCoverageComponent();
2858 auto popupComponent = ViewStackProcessor::GetInstance()->GetPopupComponent(true);
2859 if (!popupComponent) {
2860 return;
2861 }
2862 auto popupParam = popupComponent->GetPopupParam();
2863 if (!popupParam) {
2864 return;
2865 }
2866
2867 auto inspector = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
2868 if (!inspector) {
2869 LOGE("this component does not hava inspetor");
2870 return;
2871 }
2872 popupParam->SetTargetId(inspector->GetId());
2873 if (info[0]->IsBoolean()) {
2874 popupParam->SetIsShow(info[0]->ToBoolean());
2875 } else {
2876 JSRef<JSObject> showObj = JSRef<JSObject>::Cast(info[0]);
2877 ParseShowObject(info, showObj, popupComponent);
2878 popupParam->SetIsShow(showObj->GetProperty("value")->ToBoolean());
2879 }
2880
2881 JSRef<JSObject> popupObj = JSRef<JSObject>::Cast(info[1]);
2882 if (popupObj->GetProperty("message")->IsString()) {
2883 ParsePopupParam(info, popupObj, popupComponent);
2884 } else {
2885 ParseCustomPopupParam(info, popupObj, popupComponent);
2886 }
2887 }
2888 #endif
2889
JsLinearGradient(const JSCallbackInfo & info)2890 void JSViewAbstract::JsLinearGradient(const JSCallbackInfo& info)
2891 {
2892 if (info.Length() < 1) {
2893 LOGE("The arg is wrong, it is supposed to have at least 1 argument");
2894 return;
2895 }
2896 if (!info[0]->IsObject()) {
2897 LOGE("arg is not a object.");
2898 return;
2899 }
2900
2901 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
2902 if (!argsPtrItem || argsPtrItem->IsNull()) {
2903 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
2904 info.ReturnSelf();
2905 return;
2906 }
2907 Gradient lineGradient;
2908 lineGradient.SetType(GradientType::LINEAR);
2909 AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
2910 // angle
2911 std::optional<float> degree;
2912 GetAngle("angle", argsPtrItem, degree);
2913 if (degree) {
2914 lineGradient.GetLinearGradient().angle = AnimatableDimension(degree.value(), DimensionUnit::PX, option);
2915 degree.reset();
2916 }
2917 // direction
2918 auto direction =
2919 static_cast<GradientDirection>(argsPtrItem->GetInt("direction", static_cast<int32_t>(GradientDirection::NONE)));
2920 switch (direction) {
2921 case GradientDirection::LEFT:
2922 lineGradient.GetLinearGradient().linearX = GradientDirection::LEFT;
2923 break;
2924 case GradientDirection::RIGHT:
2925 lineGradient.GetLinearGradient().linearX = GradientDirection::RIGHT;
2926 break;
2927 case GradientDirection::TOP:
2928 lineGradient.GetLinearGradient().linearY = GradientDirection::TOP;
2929 break;
2930 case GradientDirection::BOTTOM:
2931 lineGradient.GetLinearGradient().linearY = GradientDirection::BOTTOM;
2932 break;
2933 case GradientDirection::LEFT_TOP:
2934 lineGradient.GetLinearGradient().linearX = GradientDirection::LEFT;
2935 lineGradient.GetLinearGradient().linearY = GradientDirection::TOP;
2936 break;
2937 case GradientDirection::LEFT_BOTTOM:
2938 lineGradient.GetLinearGradient().linearX = GradientDirection::LEFT;
2939 lineGradient.GetLinearGradient().linearY = GradientDirection::BOTTOM;
2940 break;
2941 case GradientDirection::RIGHT_TOP:
2942 lineGradient.GetLinearGradient().linearX = GradientDirection::RIGHT;
2943 lineGradient.GetLinearGradient().linearY = GradientDirection::TOP;
2944 break;
2945 case GradientDirection::RIGHT_BOTTOM:
2946 lineGradient.GetLinearGradient().linearX = GradientDirection::RIGHT;
2947 lineGradient.GetLinearGradient().linearY = GradientDirection::BOTTOM;
2948 break;
2949 case GradientDirection::NONE:
2950 case GradientDirection::START_TO_END:
2951 case GradientDirection::END_TO_START:
2952 default:
2953 break;
2954 }
2955 // repeating
2956 auto repeating = argsPtrItem->GetBool("repeating", false);
2957 lineGradient.SetRepeat(repeating);
2958 // color stops
2959 GetGradientColorStops(lineGradient, argsPtrItem->GetValue("colors"));
2960
2961 auto stack = ViewStackProcessor::GetInstance();
2962 if (!stack->IsVisualStateSet()) {
2963 auto decoration = GetBackDecoration();
2964 if (decoration) {
2965 decoration->SetGradient(lineGradient);
2966 }
2967 } else {
2968 auto boxComponent = stack->GetBoxComponent();
2969 boxComponent->GetStateAttributes()->AddAttribute<Gradient>
2970 (BoxStateAttribute::GRADIENT, lineGradient, stack->GetVisualState());
2971 if (!boxComponent->GetStateAttributes()->
2972 HasAttribute(BoxStateAttribute::GRADIENT, VisualState::NORMAL)) {
2973 boxComponent->GetStateAttributes()->AddAttribute<Gradient>(BoxStateAttribute::GRADIENT,
2974 GetBackDecoration()->GetGradient(), VisualState::NORMAL);
2975 }
2976 }
2977 }
2978
JsRadialGradient(const JSCallbackInfo & info)2979 void JSViewAbstract::JsRadialGradient(const JSCallbackInfo& info)
2980 {
2981 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
2982 if (!CheckJSCallbackInfo("JsRadialGradient", info, checkList)) {
2983 return;
2984 }
2985
2986 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
2987 if (!argsPtrItem || argsPtrItem->IsNull()) {
2988 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
2989 info.ReturnSelf();
2990 return;
2991 }
2992
2993 Gradient radialGradient;
2994 radialGradient.SetType(GradientType::RADIAL);
2995 AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
2996 // center
2997 auto center = argsPtrItem->GetValue("center");
2998 if (center && !center->IsNull() && center->IsArray() && center->GetArraySize() == 2) {
2999 Dimension value;
3000 if (ParseJsonDimensionVp(center->GetArrayItem(0), value)) {
3001 radialGradient.GetRadialGradient().radialCenterX = AnimatableDimension(value, option);
3002 if (value.Unit() == DimensionUnit::PERCENT) {
3003 // [0,1] -> [0, 100]
3004 radialGradient.GetRadialGradient().radialCenterX =
3005 AnimatableDimension(value.Value() * 100.0, DimensionUnit::PERCENT, option);
3006 }
3007 }
3008 if (ParseJsonDimensionVp(center->GetArrayItem(1), value)) {
3009 radialGradient.GetRadialGradient().radialCenterY = AnimatableDimension(value, option);
3010 if (value.Unit() == DimensionUnit::PERCENT) {
3011 // [0,1] -> [0, 100]
3012 radialGradient.GetRadialGradient().radialCenterY =
3013 AnimatableDimension(value.Value() * 100.0, DimensionUnit::PERCENT, option);
3014 }
3015 }
3016 }
3017 // radius
3018 Dimension radius;
3019 if (ParseJsonDimensionVp(argsPtrItem->GetValue("radius"), radius)) {
3020 radialGradient.GetRadialGradient().radialVerticalSize = AnimatableDimension(radius, option);
3021 radialGradient.GetRadialGradient().radialHorizontalSize = AnimatableDimension(radius, option);
3022 }
3023 // repeating
3024 auto repeating = argsPtrItem->GetBool("repeating", false);
3025 radialGradient.SetRepeat(repeating);
3026 // color stops
3027 GetGradientColorStops(radialGradient, argsPtrItem->GetValue("colors"));
3028
3029 auto stack = ViewStackProcessor::GetInstance();
3030 if (!stack->IsVisualStateSet()) {
3031 auto decoration = GetBackDecoration();
3032 if (decoration) {
3033 decoration->SetGradient(radialGradient);
3034 }
3035 } else {
3036 auto boxComponent = stack->GetBoxComponent();
3037 boxComponent->GetStateAttributes()->AddAttribute<Gradient>
3038 (BoxStateAttribute::GRADIENT, radialGradient, stack->GetVisualState());
3039 if (!boxComponent->GetStateAttributes()->
3040 HasAttribute(BoxStateAttribute::GRADIENT, VisualState::NORMAL)) {
3041 boxComponent->GetStateAttributes()->AddAttribute<Gradient>(BoxStateAttribute::GRADIENT,
3042 GetBackDecoration()->GetGradient(), VisualState::NORMAL);
3043 }
3044 }
3045 }
3046
JsSweepGradient(const JSCallbackInfo & info)3047 void JSViewAbstract::JsSweepGradient(const JSCallbackInfo& info)
3048 {
3049 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
3050 if (!CheckJSCallbackInfo("JsSweepGradient", info, checkList)) {
3051 return;
3052 }
3053
3054 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
3055 if (!argsPtrItem || argsPtrItem->IsNull()) {
3056 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
3057 info.ReturnSelf();
3058 return;
3059 }
3060
3061 Gradient sweepGradient;
3062 sweepGradient.SetType(GradientType::SWEEP);
3063 AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
3064 // center
3065 auto center = argsPtrItem->GetValue("center");
3066 if (center && !center->IsNull() && center->IsArray() && center->GetArraySize() == 2) {
3067 Dimension value;
3068 if (ParseJsonDimensionVp(center->GetArrayItem(0), value)) {
3069 sweepGradient.GetSweepGradient().centerX = AnimatableDimension(value, option);
3070 if (value.Unit() == DimensionUnit::PERCENT) {
3071 // [0,1] -> [0, 100]
3072 sweepGradient.GetSweepGradient().centerX =
3073 AnimatableDimension(value.Value() * 100.0, DimensionUnit::PERCENT, option);
3074 }
3075 }
3076 if (ParseJsonDimensionVp(center->GetArrayItem(1), value)) {
3077 sweepGradient.GetSweepGradient().centerY = AnimatableDimension(value, option);
3078 if (value.Unit() == DimensionUnit::PERCENT) {
3079 // [0,1] -> [0, 100]
3080 sweepGradient.GetSweepGradient().centerY =
3081 AnimatableDimension(value.Value() * 100.0, DimensionUnit::PERCENT, option);
3082 }
3083 }
3084 }
3085 std::optional<float> degree;
3086 // start
3087 GetAngle("start", argsPtrItem, degree);
3088 if (degree) {
3089 sweepGradient.GetSweepGradient().startAngle = AnimatableDimension(degree.value(), DimensionUnit::PX, option);
3090 degree.reset();
3091 }
3092 // end
3093 GetAngle("end", argsPtrItem, degree);
3094 if (degree) {
3095 sweepGradient.GetSweepGradient().endAngle = AnimatableDimension(degree.value(), DimensionUnit::PX, option);
3096 degree.reset();
3097 }
3098 // rotation
3099 GetAngle("rotation", argsPtrItem, degree);
3100 if (degree) {
3101 sweepGradient.GetSweepGradient().rotation = AnimatableDimension(degree.value(), DimensionUnit::PX, option);
3102 degree.reset();
3103 }
3104 // repeating
3105 auto repeating = argsPtrItem->GetBool("repeating", false);
3106 sweepGradient.SetRepeat(repeating);
3107 // color stops
3108 GetGradientColorStops(sweepGradient, argsPtrItem->GetValue("colors"));
3109
3110 auto stack = ViewStackProcessor::GetInstance();
3111 if (!stack->IsVisualStateSet()) {
3112 auto decoration = GetBackDecoration();
3113 if (decoration) {
3114 decoration->SetGradient(sweepGradient);
3115 }
3116 } else {
3117 auto boxComponent = stack->GetBoxComponent();
3118 boxComponent->GetStateAttributes()->AddAttribute<Gradient>
3119 (BoxStateAttribute::GRADIENT, sweepGradient, stack->GetVisualState());
3120 if (!boxComponent->GetStateAttributes()->
3121 HasAttribute(BoxStateAttribute::GRADIENT, VisualState::NORMAL)) {
3122 boxComponent->GetStateAttributes()->AddAttribute<Gradient>(BoxStateAttribute::GRADIENT,
3123 GetBackDecoration()->GetGradient(), VisualState::NORMAL);
3124 }
3125 }
3126 }
3127
JsMotionPath(const JSCallbackInfo & info)3128 void JSViewAbstract::JsMotionPath(const JSCallbackInfo& info)
3129 {
3130 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
3131 if (!CheckJSCallbackInfo("JsMotionPath", info, checkList)) {
3132 return;
3133 }
3134 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
3135 MotionPathOption motionPathOption;
3136 if (ParseMotionPath(argsPtrItem, motionPathOption)) {
3137 if (motionPathOption.GetRotate()) {
3138 ViewStackProcessor::GetInstance()->GetTransformComponent();
3139 }
3140 auto flexItem = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
3141 flexItem->SetMotionPathOption(motionPathOption);
3142 } else {
3143 LOGE("parse motionPath failed. %{public}s", info[0]->ToString().c_str());
3144 }
3145 }
3146
JsShadow(const JSCallbackInfo & info)3147 void JSViewAbstract::JsShadow(const JSCallbackInfo& info)
3148 {
3149 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
3150 if (!CheckJSCallbackInfo("JsShadow", info, checkList)) {
3151 return;
3152 }
3153 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
3154 if (!argsPtrItem || argsPtrItem->IsNull()) {
3155 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
3156 info.ReturnSelf();
3157 return;
3158 }
3159 double radius = 0.0;
3160 ParseJsonDouble(argsPtrItem->GetValue("radius"), radius);
3161 if (LessOrEqual(radius, 0.0)) {
3162 LOGE("JsShadow Parse radius failed, radius = %{public}lf", radius);
3163 return;
3164 }
3165 std::vector<Shadow> shadows(1);
3166 shadows.begin()->SetBlurRadius(radius);
3167 Dimension offsetX;
3168 if (ParseJsonDimensionVp(argsPtrItem->GetValue("offsetX"), offsetX)) {
3169 shadows.begin()->SetOffsetX(offsetX.Value());
3170 }
3171 Dimension offsetY;
3172 if (ParseJsonDimensionVp(argsPtrItem->GetValue("offsetY"), offsetY)) {
3173 shadows.begin()->SetOffsetY(offsetY.Value());
3174 }
3175 Color color;
3176 if (ParseJsonColor(argsPtrItem->GetValue("color"), color)) {
3177 shadows.begin()->SetColor(color);
3178 }
3179 auto backDecoration = GetBackDecoration();
3180 backDecoration->SetShadows(shadows);
3181 }
3182
JsGrayScale(const JSCallbackInfo & info)3183 void JSViewAbstract::JsGrayScale(const JSCallbackInfo& info)
3184 {
3185 if (info.Length() < 1) {
3186 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
3187 return;
3188 }
3189
3190 Dimension value;
3191 if (!ParseJsDimensionVp(info[0], value)) {
3192 return;
3193 }
3194
3195 if (LessNotEqual(value.Value(), 0.0)) {
3196 value.SetValue(0.0);
3197 }
3198
3199 if (GreatNotEqual(value.Value(), 1.0)) {
3200 value.SetValue(1.0);
3201 }
3202
3203 auto frontDecoration = GetFrontDecoration();
3204 frontDecoration->SetGrayScale(value);
3205 }
3206
JsBrightness(const JSCallbackInfo & info)3207 void JSViewAbstract::JsBrightness(const JSCallbackInfo& info)
3208 {
3209 if (info.Length() < 1) {
3210 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
3211 return;
3212 }
3213
3214 Dimension value;
3215 if (!ParseJsDimensionVp(info[0], value)) {
3216 return;
3217 }
3218
3219 auto frontDecoration = GetFrontDecoration();
3220 frontDecoration->SetBrightness(value);
3221 }
3222
JsContrast(const JSCallbackInfo & info)3223 void JSViewAbstract::JsContrast(const JSCallbackInfo& info)
3224 {
3225 if (info.Length() < 1) {
3226 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
3227 return;
3228 }
3229
3230 Dimension value;
3231 if (!ParseJsDimensionVp(info[0], value)) {
3232 return;
3233 }
3234
3235 if (LessNotEqual(value.Value(), 0.0)) {
3236 value.SetValue(0.0);
3237 }
3238 auto frontDecoration = GetFrontDecoration();
3239 frontDecoration->SetContrast(value);
3240 }
3241
JsSaturate(const JSCallbackInfo & info)3242 void JSViewAbstract::JsSaturate(const JSCallbackInfo& info)
3243 {
3244 if (info.Length() < 1) {
3245 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
3246 return;
3247 }
3248 Dimension value;
3249 if (!ParseJsDimensionVp(info[0], value)) {
3250 return;
3251 }
3252
3253 if (LessNotEqual(value.Value(), 0.0)) {
3254 value.SetValue(0.0);
3255 }
3256 auto frontDecoration = GetFrontDecoration();
3257 frontDecoration->SetSaturate(value);
3258 }
3259
JsSepia(const JSCallbackInfo & info)3260 void JSViewAbstract::JsSepia(const JSCallbackInfo& info)
3261 {
3262 if (info.Length() < 1) {
3263 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
3264 return;
3265 }
3266
3267 Dimension value;
3268 if (!ParseJsDimensionVp(info[0], value)) {
3269 return;
3270 }
3271
3272 if (LessNotEqual(value.Value(), 0.0)) {
3273 value.SetValue(0.0);
3274 }
3275 auto frontDecoration = GetFrontDecoration();
3276 frontDecoration->SetSepia(value);
3277 }
3278
JsInvert(const JSCallbackInfo & info)3279 void JSViewAbstract::JsInvert(const JSCallbackInfo& info)
3280 {
3281 if (info.Length() < 1) {
3282 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
3283 return;
3284 }
3285 Dimension value;
3286 if (!ParseJsDimensionVp(info[0], value)) {
3287 return;
3288 }
3289 if (LessNotEqual(value.Value(), 0.0)) {
3290 value.SetValue(0.0);
3291 }
3292 auto frontDecoration = GetFrontDecoration();
3293 frontDecoration->SetInvert(value);
3294 }
3295
JsHueRotate(const JSCallbackInfo & info)3296 void JSViewAbstract::JsHueRotate(const JSCallbackInfo& info)
3297 {
3298 std::optional<float> degree;
3299 if (info.Length() < 1) {
3300 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
3301 return;
3302 }
3303 if (info[0]->IsString()) {
3304 degree = static_cast<float>(StringUtils::StringToDegree(info[0]->ToString()));
3305 } else if (info[0]->IsNumber()) {
3306 degree = static_cast<float>(info[0]->ToNumber<uint32_t>());
3307 } else {
3308 LOGE("Invalid value type");
3309 }
3310 float deg = 0.0;
3311 if (degree) {
3312 deg = degree.value();
3313 degree.reset();
3314 }
3315 auto decoration = GetFrontDecoration();
3316 if (decoration) {
3317 decoration->SetHueRotate(deg);
3318 }
3319 }
3320
JsClip(const JSCallbackInfo & info)3321 void JSViewAbstract::JsClip(const JSCallbackInfo& info)
3322 {
3323 if (info.Length() > 0) {
3324 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3325 if (info[0]->IsObject()) {
3326 JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
3327 if (clipShape == nullptr) {
3328 LOGE("clipShape is null.");
3329 return;
3330 }
3331 auto clipPath = AceType::MakeRefPtr<ClipPath>();
3332 clipPath->SetBasicShape(clipShape->GetBasicShape());
3333 box->SetClipPath(clipPath);
3334 } else if (info[0]->IsBoolean()) {
3335 box->SetBoxClipFlag(info[0]->ToBoolean());
3336 }
3337 }
3338 }
3339
JsMask(const JSCallbackInfo & info)3340 void JSViewAbstract::JsMask(const JSCallbackInfo& info)
3341 {
3342 if (info.Length() > 0 && info[0]->IsObject()) {
3343 JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
3344 if (maskShape == nullptr) {
3345 return;
3346 }
3347 auto maskPath = AceType::MakeRefPtr<MaskPath>();
3348 maskPath->SetBasicShape(maskShape->GetBasicShape());
3349 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3350 box->SetMask(maskPath);
3351 }
3352 }
3353
JsFocusable(const JSCallbackInfo & info)3354 void JSViewAbstract::JsFocusable(const JSCallbackInfo& info)
3355 {
3356 if (!info[0]->IsBoolean()) {
3357 LOGE("The info is wrong, it is supposed to be an boolean");
3358 return;
3359 }
3360
3361 auto focusComponent = ViewStackProcessor::GetInstance()->GetFocusableComponent();
3362 if (!focusComponent) {
3363 LOGE("The focusComponent is null");
3364 return;
3365 } else {
3366 focusComponent->SetFocusable(info[0]->ToBoolean());
3367 }
3368 }
3369
JsOnFocusMove(const JSCallbackInfo & args)3370 void JSViewAbstract::JsOnFocusMove(const JSCallbackInfo& args)
3371 {
3372 if (args[0]->IsFunction()) {
3373 RefPtr<JsFocusFunction> jsOnFocusMove = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(args[0]));
3374 auto onFocusMove = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocusMove)](int info) {
3375 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3376 ACE_SCORING_EVENT("onFocusMove");
3377 func->Execute(info);
3378 };
3379 auto focusableComponent = ViewStackProcessor::GetInstance()->GetFocusableComponent();
3380 focusableComponent->SetOnFocusMove(onFocusMove);
3381 }
3382 }
3383
JsOnFocus(const JSCallbackInfo & args)3384 void JSViewAbstract::JsOnFocus(const JSCallbackInfo& args)
3385 {
3386 if (args[0]->IsFunction()) {
3387 RefPtr<JsFocusFunction> jsOnFocus = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(args[0]));
3388 auto onFocus = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocus)]() {
3389 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3390 ACE_SCORING_EVENT("onFocus");
3391 func->Execute();
3392 };
3393 auto focusableComponent = ViewStackProcessor::GetInstance()->GetFocusableComponent();
3394 focusableComponent->SetOnFocus(onFocus);
3395 }
3396 }
3397
JsOnBlur(const JSCallbackInfo & args)3398 void JSViewAbstract::JsOnBlur(const JSCallbackInfo& args)
3399 {
3400 if (args[0]->IsFunction()) {
3401 RefPtr<JsFocusFunction> jsOnBlur = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(args[0]));
3402 auto onBlur_ = [execCtx = args.GetExecutionContext(), func = std::move(jsOnBlur)]() {
3403 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3404 ACE_SCORING_EVENT("onBlur");
3405 func->Execute();
3406 };
3407 auto focusableComponent = ViewStackProcessor::GetInstance()->GetFocusableComponent();
3408 focusableComponent->SetOnBlur(onBlur_);
3409 }
3410 }
3411
JsKey(const std::string & key)3412 void JSViewAbstract::JsKey(const std::string& key)
3413 {
3414 auto component = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
3415 if (component) {
3416 component->SetInspectorKey(key);
3417 }
3418 }
3419
JsId(const std::string & id)3420 void JSViewAbstract::JsId(const std::string& id)
3421 {
3422 JsKey(id);
3423 }
3424
JsRestoreId(int32_t restoreId)3425 void JSViewAbstract::JsRestoreId(int32_t restoreId)
3426 {
3427 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
3428 if (component) {
3429 component->SetRestoreId(restoreId);
3430 }
3431 }
3432
3433 #if defined(WINDOWS_PLATFORM) || defined(MAC_PLATFORM)
JsDebugLine(const JSCallbackInfo & info)3434 void JSViewAbstract::JsDebugLine(const JSCallbackInfo& info)
3435 {
3436 std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::STRING};
3437 if (!CheckJSCallbackInfo("JsDebugLine", info, checkList)) {
3438 return;
3439 }
3440
3441 auto component = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
3442 if (component) {
3443 component->SetDebugLine(info[0]->ToString());
3444 }
3445 }
3446 #endif
3447
JsOpacityPassThrough(const JSCallbackInfo & info)3448 void JSViewAbstract::JsOpacityPassThrough(const JSCallbackInfo& info)
3449 {
3450 JSViewAbstract::JsOpacity(info);
3451 if (ViewStackProcessor::GetInstance()->HasDisplayComponent()) {
3452 auto display = ViewStackProcessor::GetInstance()->GetDisplayComponent();
3453 display->DisableLayer(true);
3454 }
3455 }
3456
JsTransitionPassThrough(const JSCallbackInfo & info)3457 void JSViewAbstract::JsTransitionPassThrough(const JSCallbackInfo& info)
3458 {
3459 JSViewAbstract::JsTransition(info);
3460 if (ViewStackProcessor::GetInstance()->HasDisplayComponent()) {
3461 auto display = ViewStackProcessor::GetInstance()->GetDisplayComponent();
3462 display->DisableLayer(true);
3463 }
3464 }
3465
JsAccessibilityGroup(bool accessible)3466 void JSViewAbstract::JsAccessibilityGroup(bool accessible)
3467 {
3468 auto inspector = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
3469 if (!inspector) {
3470 LOGE("this component does not hava inspetor");
3471 return;
3472 }
3473 inspector->SetAccessibilityGroup(accessible);
3474 }
3475
JsAccessibilityText(const std::string & text)3476 void JSViewAbstract::JsAccessibilityText(const std::string& text)
3477 {
3478 auto inspector = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
3479 if (!inspector) {
3480 LOGE("this component does not hava inspetor");
3481 return;
3482 }
3483 inspector->SetAccessibilitytext(text);
3484 }
3485
JsAccessibilityDescription(const std::string & description)3486 void JSViewAbstract::JsAccessibilityDescription(const std::string& description)
3487 {
3488 auto inspector = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
3489 if (!inspector) {
3490 LOGE("this component does not hava inspetor");
3491 return;
3492 }
3493 inspector->SetAccessibilityDescription(description);
3494 }
3495
JsAccessibilityImportance(const std::string & importance)3496 void JSViewAbstract::JsAccessibilityImportance(const std::string& importance)
3497 {
3498 auto inspector = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
3499 if (!inspector) {
3500 LOGE("this component does not hava inspetor");
3501 return;
3502 }
3503 inspector->SetAccessibilityImportance(importance);
3504 }
3505
JsBindContextMenu(const JSCallbackInfo & info)3506 void JSViewAbstract::JsBindContextMenu(const JSCallbackInfo& info)
3507 {
3508 ViewStackProcessor::GetInstance()->GetCoverageComponent();
3509 auto menuComponent = ViewStackProcessor::GetInstance()->GetMenuComponent(true);
3510 if (!menuComponent) {
3511 return;
3512 }
3513 #if defined(MULTIPLE_WINDOW_SUPPORTED)
3514 menuComponent->SetIsContextMenu(true);
3515 #endif
3516 int32_t responseType = static_cast<int32_t>(ResponseType::LONGPRESS);
3517 if (info.Length() == 2 && info[1]->IsNumber()) {
3518 responseType = info[1]->ToNumber<int32_t>();
3519 LOGI("Set the responseType is %d.", responseType);
3520 }
3521
3522 if (responseType == static_cast<int32_t>(ResponseType::RIGHT_CLICK)) {
3523 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3524 box->SetOnMouseId([weak = WeakPtr<OHOS::Ace::MenuComponent>(menuComponent)](MouseInfo& info) {
3525 auto refPtr = weak.Upgrade();
3526 if (!refPtr) {
3527 return;
3528 }
3529 if (info.GetButton() == MouseButton::RIGHT_BUTTON && info.GetAction() == MouseAction::RELEASE) {
3530 auto showMenu = refPtr->GetTargetCallback();
3531 #if defined(MULTIPLE_WINDOW_SUPPORTED)
3532 showMenu("", info.GetScreenLocation());
3533 #else
3534 showMenu("", info.GetGlobalLocation());
3535 #endif
3536 }
3537 });
3538 } else if (responseType == static_cast<int32_t>(ResponseType::LONGPRESS)) {
3539 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3540 RefPtr<Gesture> longGesture =
3541 AceType::MakeRefPtr<LongPressGesture>(DEFAULT_LONG_PRESS_FINGER, false, DEFAULT_LONG_PRESS_DURATION);
3542 longGesture->SetOnActionId([weak = WeakPtr<OHOS::Ace::MenuComponent>(menuComponent)](const GestureEvent& info) {
3543 auto refPtr = weak.Upgrade();
3544 if (!refPtr) {
3545 return;
3546 }
3547 auto showMenu = refPtr->GetTargetCallback();
3548 #if defined(MULTIPLE_WINDOW_SUPPORTED)
3549 showMenu("", info.GetScreenLocation());
3550 #else
3551 showMenu("", info.GetGlobalLocation());
3552 #endif
3553 });
3554 box->SetOnLongPress(longGesture);
3555 } else {
3556 LOGE("The arg responseType is invalid.");
3557 return;
3558 }
3559 auto menuTheme = GetTheme<SelectTheme>();
3560 menuComponent->SetTheme(menuTheme);
3561
3562 if (info[0]->IsObject()) {
3563 JSRef<JSObject> menuObj = JSRef<JSObject>::Cast(info[0]);
3564
3565 auto builder = menuObj->GetProperty("builder");
3566 if (!builder->IsFunction()) {
3567 LOGE("builder param is not a function.");
3568 return;
3569 }
3570 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
3571 if (!builderFunc) {
3572 LOGE("builder function is null.");
3573 return;
3574 }
3575 // use another VSP instance while executing the builder function
3576 ScopedViewStackProcessor builderViewStackProcessor;
3577 {
3578 ACE_SCORING_EVENT("contextMenu.builder");
3579 builderFunc->Execute();
3580 }
3581 auto customComponent = ViewStackProcessor::GetInstance()->Finish();
3582 if (!customComponent) {
3583 LOGE("Custom component is null.");
3584 return;
3585 }
3586
3587 auto optionTheme = GetTheme<SelectTheme>();
3588 auto optionComponent = AceType::MakeRefPtr<OHOS::Ace::OptionComponent>(optionTheme);
3589 optionComponent->SetCustomComponent(customComponent);
3590 menuComponent->ClearOptions();
3591 menuComponent->AppendOption(optionComponent);
3592 } else {
3593 LOGE("Param is invalid");
3594 return;
3595 }
3596 }
3597
JSBind()3598 void JSViewAbstract::JSBind()
3599 {
3600 JSClass<JSViewAbstract>::Declare("JSViewAbstract");
3601
3602 // staticmethods
3603 MethodOptions opt = MethodOptions::NONE;
3604 JSClass<JSViewAbstract>::StaticMethod("pop", &JSViewAbstract::Pop, opt);
3605
3606 JSClass<JSViewAbstract>::StaticMethod("width", &JSViewAbstract::JsWidth);
3607 JSClass<JSViewAbstract>::StaticMethod("height", &JSViewAbstract::JsHeight);
3608 JSClass<JSViewAbstract>::StaticMethod("responseRegion", &JSViewAbstract::JsResponseRegion);
3609 JSClass<JSViewAbstract>::StaticMethod("size", &JSViewAbstract::JsSize);
3610 JSClass<JSViewAbstract>::StaticMethod("constraintSize", &JSViewAbstract::JsConstraintSize);
3611 JSClass<JSViewAbstract>::StaticMethod("layoutPriority", &JSViewAbstract::JsLayoutPriority);
3612 JSClass<JSViewAbstract>::StaticMethod("layoutWeight", &JSViewAbstract::JsLayoutWeight);
3613
3614 JSClass<JSViewAbstract>::StaticMethod("margin", &JSViewAbstract::JsMargin);
3615 JSClass<JSViewAbstract>::StaticMethod("marginTop", &JSViewAbstract::SetMarginTop, opt);
3616 JSClass<JSViewAbstract>::StaticMethod("marginBottom", &JSViewAbstract::SetMarginBottom, opt);
3617 JSClass<JSViewAbstract>::StaticMethod("marginLeft", &JSViewAbstract::SetMarginLeft, opt);
3618 JSClass<JSViewAbstract>::StaticMethod("marginRight", &JSViewAbstract::SetMarginRight, opt);
3619
3620 JSClass<JSViewAbstract>::StaticMethod("padding", &JSViewAbstract::JsPadding);
3621 JSClass<JSViewAbstract>::StaticMethod("paddingTop", &JSViewAbstract::SetPaddingTop, opt);
3622 JSClass<JSViewAbstract>::StaticMethod("paddingBottom", &JSViewAbstract::SetPaddingBottom, opt);
3623 JSClass<JSViewAbstract>::StaticMethod("paddingLeft", &JSViewAbstract::SetPaddingLeft, opt);
3624 JSClass<JSViewAbstract>::StaticMethod("paddingRight", &JSViewAbstract::SetPaddingRight, opt);
3625
3626 JSClass<JSViewAbstract>::StaticMethod("backgroundColor", &JSViewAbstract::JsBackgroundColor);
3627 JSClass<JSViewAbstract>::StaticMethod("backgroundImage", &JSViewAbstract::JsBackgroundImage);
3628 JSClass<JSViewAbstract>::StaticMethod("backgroundImageSize", &JSViewAbstract::JsBackgroundImageSize);
3629 JSClass<JSViewAbstract>::StaticMethod("backgroundImagePosition", &JSViewAbstract::JsBackgroundImagePosition);
3630 JSClass<JSViewAbstract>::StaticMethod("borderStyle", &JSViewAbstract::SetBorderStyle, opt);
3631 JSClass<JSViewAbstract>::StaticMethod("borderColor", &JSViewAbstract::JsBorderColor);
3632 JSClass<JSViewAbstract>::StaticMethod("border", &JSViewAbstract::JsBorder);
3633 JSClass<JSViewAbstract>::StaticMethod("borderWidth", &JSViewAbstract::JsBorderWidth);
3634 JSClass<JSViewAbstract>::StaticMethod("borderRadius", &JSViewAbstract::JsBorderRadius);
3635
3636 JSClass<JSViewAbstract>::StaticMethod("scale", &JSViewAbstract::JsScale);
3637 JSClass<JSViewAbstract>::StaticMethod("scaleX", &JSViewAbstract::JsScaleX);
3638 JSClass<JSViewAbstract>::StaticMethod("scaleY", &JSViewAbstract::JsScaleY);
3639 JSClass<JSViewAbstract>::StaticMethod("opacity", &JSViewAbstract::JsOpacity);
3640 JSClass<JSViewAbstract>::StaticMethod("rotate", &JSViewAbstract::JsRotate);
3641 JSClass<JSViewAbstract>::StaticMethod("rotateX", &JSViewAbstract::JsRotateX);
3642 JSClass<JSViewAbstract>::StaticMethod("rotateY", &JSViewAbstract::JsRotateY);
3643 JSClass<JSViewAbstract>::StaticMethod("translate", &JSViewAbstract::JsTranslate);
3644 JSClass<JSViewAbstract>::StaticMethod("translateX", &JSViewAbstract::JsTranslateX);
3645 JSClass<JSViewAbstract>::StaticMethod("translateY", &JSViewAbstract::JsTranslateY);
3646 JSClass<JSViewAbstract>::StaticMethod("transform", &JSViewAbstract::JsTransform);
3647 JSClass<JSViewAbstract>::StaticMethod("transition", &JSViewAbstract::JsTransition);
3648
3649 JSClass<JSViewAbstract>::StaticMethod("align", &JSViewAbstract::JsAlign);
3650 JSClass<JSViewAbstract>::StaticMethod("position", &JSViewAbstract::JsPosition);
3651 JSClass<JSViewAbstract>::StaticMethod("markAnchor", &JSViewAbstract::JsMarkAnchor);
3652 JSClass<JSViewAbstract>::StaticMethod("offset", &JSViewAbstract::JsOffset);
3653 JSClass<JSViewAbstract>::StaticMethod("enabled", &JSViewAbstract::JsEnabled);
3654 JSClass<JSViewAbstract>::StaticMethod("aspectRatio", &JSViewAbstract::JsAspectRatio);
3655 JSClass<JSViewAbstract>::StaticMethod("overlay", &JSViewAbstract::JsOverlay);
3656
3657 JSClass<JSViewAbstract>::StaticMethod("blur", &JSViewAbstract::JsBlur);
3658 JSClass<JSViewAbstract>::StaticMethod("colorBlend", &JSViewAbstract::JsColorBlend);
3659 JSClass<JSViewAbstract>::StaticMethod("backdropBlur", &JSViewAbstract::JsBackdropBlur);
3660 JSClass<JSViewAbstract>::StaticMethod("windowBlur", &JSViewAbstract::JsWindowBlur);
3661 JSClass<JSViewAbstract>::StaticMethod("visibility", &JSViewAbstract::SetVisibility);
3662 JSClass<JSViewAbstract>::StaticMethod("flexBasis", &JSViewAbstract::JsFlexBasis);
3663 JSClass<JSViewAbstract>::StaticMethod("flexGrow", &JSViewAbstract::JsFlexGrow);
3664 JSClass<JSViewAbstract>::StaticMethod("flexShrink", &JSViewAbstract::JsFlexShrink);
3665 JSClass<JSViewAbstract>::StaticMethod("alignSelf", &JSViewAbstract::JsAlignSelf);
3666 JSClass<JSViewAbstract>::StaticMethod("displayPriority", &JSViewAbstract::JsDisplayPriority);
3667 JSClass<JSViewAbstract>::StaticMethod("useAlign", &JSViewAbstract::JsUseAlign);
3668 JSClass<JSViewAbstract>::StaticMethod("zIndex", &JSViewAbstract::JsZIndex);
3669 JSClass<JSViewAbstract>::StaticMethod("sharedTransition", &JSViewAbstract::JsSharedTransition);
3670 JSClass<JSViewAbstract>::StaticMethod("direction", &JSViewAbstract::SetDirection, opt);
3671 #ifndef WEARABLE_PRODUCT
3672 JSClass<JSViewAbstract>::StaticMethod("bindPopup", &JSViewAbstract::JsBindPopup);
3673 #endif
3674
3675 JSClass<JSViewAbstract>::StaticMethod("bindMenu", &JSViewAbstract::JsBindMenu);
3676 JSClass<JSViewAbstract>::StaticMethod("bindContextMenu", &JSViewAbstract::JsBindContextMenu);
3677 JSClass<JSViewAbstract>::StaticMethod("onDragStart", &JSViewAbstract::JsOnDragStart);
3678 JSClass<JSViewAbstract>::StaticMethod("onDragEnter", &JSViewAbstract::JsOnDragEnter);
3679 JSClass<JSViewAbstract>::StaticMethod("onDragMove", &JSViewAbstract::JsOnDragMove);
3680 JSClass<JSViewAbstract>::StaticMethod("onDragLeave", &JSViewAbstract::JsOnDragLeave);
3681 JSClass<JSViewAbstract>::StaticMethod("onDrop", &JSViewAbstract::JsOnDrop);
3682
3683 JSClass<JSViewAbstract>::StaticMethod("linearGradient", &JSViewAbstract::JsLinearGradient);
3684 JSClass<JSViewAbstract>::StaticMethod("sweepGradient", &JSViewAbstract::JsSweepGradient);
3685 JSClass<JSViewAbstract>::StaticMethod("radialGradient", &JSViewAbstract::JsRadialGradient);
3686 JSClass<JSViewAbstract>::StaticMethod("motionPath", &JSViewAbstract::JsMotionPath);
3687 JSClass<JSViewAbstract>::StaticMethod("gridSpan", &JSViewAbstract::JsGridSpan);
3688 JSClass<JSViewAbstract>::StaticMethod("gridOffset", &JSViewAbstract::JsGridOffset);
3689 JSClass<JSViewAbstract>::StaticMethod("useSizeType", &JSViewAbstract::JsUseSizeType);
3690 JSClass<JSViewAbstract>::StaticMethod("shadow", &JSViewAbstract::JsShadow);
3691 JSClass<JSViewAbstract>::StaticMethod("grayscale", &JSViewAbstract::JsGrayScale);
3692 JSClass<JSViewAbstract>::StaticMethod("focusable", &JSViewAbstract::JsFocusable);
3693 JSClass<JSViewAbstract>::StaticMethod("onFocusMove", &JSViewAbstract::JsOnFocusMove);
3694 JSClass<JSViewAbstract>::StaticMethod("onFocus", &JSViewAbstract::JsOnFocus);
3695 JSClass<JSViewAbstract>::StaticMethod("onBlur", &JSViewAbstract::JsOnBlur);
3696 JSClass<JSViewAbstract>::StaticMethod("brightness", &JSViewAbstract::JsBrightness);
3697 JSClass<JSViewAbstract>::StaticMethod("contrast", &JSViewAbstract::JsContrast);
3698 JSClass<JSViewAbstract>::StaticMethod("saturate", &JSViewAbstract::JsSaturate);
3699 JSClass<JSViewAbstract>::StaticMethod("sepia", &JSViewAbstract::JsSepia);
3700 JSClass<JSViewAbstract>::StaticMethod("invert", &JSViewAbstract::JsInvert);
3701 JSClass<JSViewAbstract>::StaticMethod("hueRotate", &JSViewAbstract::JsHueRotate);
3702 JSClass<JSViewAbstract>::StaticMethod("clip", &JSViewAbstract::JsClip);
3703 JSClass<JSViewAbstract>::StaticMethod("mask", &JSViewAbstract::JsMask);
3704 JSClass<JSViewAbstract>::StaticMethod("key", &JSViewAbstract::JsKey);
3705 JSClass<JSViewAbstract>::StaticMethod("id", &JSViewAbstract::JsId);
3706 JSClass<JSViewAbstract>::StaticMethod("restoreId", &JSViewAbstract::JsRestoreId);
3707 JSClass<JSViewAbstract>::StaticMethod("hoverEffect", &JSViewAbstract::JsHoverEffect);
3708 JSClass<JSViewAbstract>::StaticMethod("onMouse", &JSViewAbstract::JsOnMouse);
3709 #if defined(WINDOWS_PLATFORM) || defined(MAC_PLATFORM)
3710 JSClass<JSViewAbstract>::StaticMethod("debugLine", &JSViewAbstract::JsDebugLine);
3711 #endif
3712 JSClass<JSViewAbstract>::StaticMethod("geometryTransition", &JSViewAbstract::JsGeometryTransition);
3713 JSClass<JSViewAbstract>::StaticMethod("onAreaChange", &JSViewAbstract::JsOnAreaChange);
3714 JSClass<JSViewAbstract>::StaticMethod("touchable", &JSInteractableView::JsTouchable);
3715
3716 JSClass<JSViewAbstract>::StaticMethod("accessibilityGroup", &JSViewAbstract::JsAccessibilityGroup);
3717 JSClass<JSViewAbstract>::StaticMethod("accessibilityText", &JSViewAbstract::JsAccessibilityText);
3718 JSClass<JSViewAbstract>::StaticMethod("accessibilityDescription", &JSViewAbstract::JsAccessibilityDescription);
3719 JSClass<JSViewAbstract>::StaticMethod("accessibilityImportance", &JSViewAbstract::JsAccessibilityImportance);
3720 JSClass<JSViewAbstract>::StaticMethod("onAccessibility", &JSInteractableView::JsOnAccessibility);
3721 }
3722
GetFrontDecoration()3723 RefPtr<Decoration> JSViewAbstract::GetFrontDecoration()
3724 {
3725 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3726 auto decoration = box->GetFrontDecoration();
3727 if (!decoration) {
3728 decoration = AceType::MakeRefPtr<Decoration>();
3729 box->SetFrontDecoration(decoration);
3730 }
3731
3732 return decoration;
3733 }
3734
GetBackDecoration()3735 RefPtr<Decoration> JSViewAbstract::GetBackDecoration()
3736 {
3737 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3738 auto decoration = box->GetBackDecoration();
3739 if (!decoration) {
3740 decoration = AceType::MakeRefPtr<Decoration>();
3741 box->SetBackDecoration(decoration);
3742 }
3743 return decoration;
3744 }
3745
SetBorderRadius(const Dimension & value,const AnimationOption & option)3746 void JSViewAbstract::SetBorderRadius(const Dimension& value, const AnimationOption& option)
3747 {
3748 BoxComponentHelper::SetBorderRadius(GetBackDecoration(), value, option);
3749 }
3750
SetBorderStyle(int32_t style)3751 void JSViewAbstract::SetBorderStyle(int32_t style)
3752 {
3753 BorderStyle borderStyle = BorderStyle::SOLID;
3754
3755 if (static_cast<int32_t>(BorderStyle::SOLID) == style) {
3756 borderStyle = BorderStyle::SOLID;
3757 } else if (static_cast<int32_t>(BorderStyle::DASHED) == style) {
3758 borderStyle = BorderStyle::DASHED;
3759 } else if (static_cast<int32_t>(BorderStyle::DOTTED) == style) {
3760 borderStyle = BorderStyle::DOTTED;
3761 } else {
3762 borderStyle = BorderStyle::NONE;
3763 }
3764
3765 auto stack = ViewStackProcessor::GetInstance();
3766 if (!stack->IsVisualStateSet()) {
3767 BoxComponentHelper::SetBorderStyle(GetBackDecoration(), borderStyle);
3768 } else {
3769 auto boxComponent = AceType::DynamicCast<BoxComponent>(stack->GetBoxComponent());
3770 boxComponent->GetStateAttributes()->AddAttribute<BorderStyle>
3771 (BoxStateAttribute::BORDER_STYLE, borderStyle, stack->GetVisualState());
3772 if (!boxComponent->GetStateAttributes()->
3773 HasAttribute(BoxStateAttribute::BORDER_STYLE, VisualState::NORMAL)) {
3774 boxComponent->GetStateAttributes()->AddAttribute<BorderStyle>(BoxStateAttribute::BORDER_STYLE,
3775 BoxComponentHelper::GetBorderStyle(GetBackDecoration()), VisualState::NORMAL);
3776 }
3777 }
3778 }
3779
SetMarginTop(const JSCallbackInfo & info)3780 void JSViewAbstract::SetMarginTop(const JSCallbackInfo& info)
3781 {
3782 if (info.Length() < 1) {
3783 LOGE("The arg is wrong, it is supposed to have at least 1 argument");
3784 return;
3785 }
3786 AnimatableDimension value;
3787 if (!ParseJsAnimatableDimensionVp(info[0], value)) {
3788 return;
3789 }
3790 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3791 Edge margin = box->GetMargin();
3792 margin.SetTop(value);
3793 box->SetMargin(margin);
3794 }
3795
SetMarginBottom(const JSCallbackInfo & info)3796 void JSViewAbstract::SetMarginBottom(const JSCallbackInfo& info)
3797 {
3798 if (info.Length() < 1) {
3799 LOGE("The arg is wrong, it is supposed to have at least 1 argument");
3800 return;
3801 }
3802 AnimatableDimension value;
3803 if (!ParseJsAnimatableDimensionVp(info[0], value)) {
3804 return;
3805 }
3806 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3807 Edge margin = box->GetMargin();
3808 margin.SetBottom(value);
3809 box->SetMargin(margin);
3810 }
3811
SetMarginLeft(const JSCallbackInfo & info)3812 void JSViewAbstract::SetMarginLeft(const JSCallbackInfo& info)
3813 {
3814 if (info.Length() < 1) {
3815 LOGE("The arg is wrong, it is supposed to have at least 1 argument");
3816 return;
3817 }
3818 AnimatableDimension value;
3819 if (!ParseJsAnimatableDimensionVp(info[0], value)) {
3820 return;
3821 }
3822 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3823 Edge margin = box->GetMargin();
3824 margin.SetLeft(value);
3825 box->SetMargin(margin);
3826 }
3827
SetMarginRight(const JSCallbackInfo & info)3828 void JSViewAbstract::SetMarginRight(const JSCallbackInfo& info)
3829 {
3830 if (info.Length() < 1) {
3831 LOGE("The arg is wrong, it is supposed to have at least 1 argument");
3832 return;
3833 }
3834 AnimatableDimension value;
3835 if (!ParseJsAnimatableDimensionVp(info[0], value)) {
3836 return;
3837 }
3838 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3839 Edge margin = box->GetMargin();
3840 margin.SetRight(value);
3841 box->SetMargin(margin);
3842 }
3843
SetMargins(const Dimension & top,const Dimension & bottom,const Dimension & left,const Dimension & right)3844 void JSViewAbstract::SetMargins(
3845 const Dimension& top, const Dimension& bottom, const Dimension& left, const Dimension& right)
3846 {
3847 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3848 AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
3849 Edge margin(left, top, right, bottom, option);
3850 box->SetMargin(margin);
3851 }
3852
SetPaddingTop(const JSCallbackInfo & info)3853 void JSViewAbstract::SetPaddingTop(const JSCallbackInfo& info)
3854 {
3855 if (info.Length() < 1) {
3856 LOGE("The arg is wrong, it is supposed to have at least 1 argument");
3857 return;
3858 }
3859 AnimatableDimension value;
3860 if (!ParseJsAnimatableDimensionVp(info[0], value)) {
3861 return;
3862 }
3863 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3864 Edge padding = box->GetPadding();
3865 padding.SetTop(value);
3866 box->SetPadding(padding);
3867 }
3868
SetPaddingBottom(const JSCallbackInfo & info)3869 void JSViewAbstract::SetPaddingBottom(const JSCallbackInfo& info)
3870 {
3871 if (info.Length() < 1) {
3872 LOGE("The arg is wrong, it is supposed to have at least 1 argument");
3873 return;
3874 }
3875 AnimatableDimension value;
3876 if (!ParseJsAnimatableDimensionVp(info[0], value)) {
3877 return;
3878 }
3879 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3880 Edge padding = box->GetPadding();
3881 padding.SetBottom(value);
3882 box->SetPadding(padding);
3883 }
3884
SetPaddingLeft(const JSCallbackInfo & info)3885 void JSViewAbstract::SetPaddingLeft(const JSCallbackInfo& info)
3886 {
3887 if (info.Length() < 1) {
3888 LOGE("The arg is wrong, it is supposed to have at least 1 argument");
3889 return;
3890 }
3891 AnimatableDimension value;
3892 if (!ParseJsAnimatableDimensionVp(info[0], value)) {
3893 return;
3894 }
3895 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3896 Edge padding = box->GetPadding();
3897 padding.SetLeft(value);
3898 box->SetPadding(padding);
3899 }
3900
SetPaddingRight(const JSCallbackInfo & info)3901 void JSViewAbstract::SetPaddingRight(const JSCallbackInfo& info)
3902 {
3903 if (info.Length() < 1) {
3904 LOGE("The arg is wrong, it is supposed to have at least 1 argument");
3905 return;
3906 }
3907 AnimatableDimension value;
3908 if (!ParseJsAnimatableDimensionVp(info[0], value)) {
3909 return;
3910 }
3911 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3912 Edge padding = box->GetPadding();
3913 padding.SetRight(value);
3914 box->SetPadding(padding);
3915 }
3916
SetPadding(const Dimension & value)3917 void JSViewAbstract::SetPadding(const Dimension& value)
3918 {
3919 SetPaddings(value, value, value, value);
3920 }
3921
SetPaddings(const Dimension & top,const Dimension & bottom,const Dimension & left,const Dimension & right)3922 void JSViewAbstract::SetPaddings(
3923 const Dimension& top, const Dimension& bottom, const Dimension& left, const Dimension& right)
3924 {
3925 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3926 AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
3927 Edge padding(left, top, right, bottom, option);
3928 box->SetPadding(padding);
3929 }
3930
SetMargin(const Dimension & value)3931 void JSViewAbstract::SetMargin(const Dimension& value)
3932 {
3933 SetMargins(value, value, value, value);
3934 }
3935
SetBlur(float radius)3936 void JSViewAbstract::SetBlur(float radius)
3937 {
3938 auto decoration = GetFrontDecoration();
3939 SetBlurRadius(decoration, radius);
3940 }
3941
SetColorBlend(Color color)3942 void JSViewAbstract::SetColorBlend(Color color)
3943 {
3944 auto decoration = GetFrontDecoration();
3945 if (decoration) {
3946 decoration->SetColorBlend(color);
3947 }
3948 }
3949
SetBackdropBlur(float radius)3950 void JSViewAbstract::SetBackdropBlur(float radius)
3951 {
3952 auto decoration = GetBackDecoration();
3953 SetBlurRadius(decoration, radius);
3954 }
3955
SetBlurRadius(const RefPtr<Decoration> & decoration,float radius)3956 void JSViewAbstract::SetBlurRadius(const RefPtr<Decoration>& decoration, float radius)
3957 {
3958 if (decoration) {
3959 AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
3960 decoration->SetBlurRadius(AnimatableDimension(radius, DimensionUnit::PX, option));
3961 }
3962 }
3963
SetWindowBlur(float progress,WindowBlurStyle blurStyle)3964 void JSViewAbstract::SetWindowBlur(float progress, WindowBlurStyle blurStyle)
3965 {
3966 auto decoration = GetBackDecoration();
3967 if (decoration) {
3968 decoration->SetWindowBlurProgress(progress);
3969 decoration->SetWindowBlurStyle(blurStyle);
3970 }
3971 }
3972
ParseJsonDimension(const std::unique_ptr<JsonValue> & jsonValue,Dimension & result,DimensionUnit defaultUnit)3973 bool JSViewAbstract::ParseJsonDimension(
3974 const std::unique_ptr<JsonValue>& jsonValue, Dimension& result, DimensionUnit defaultUnit)
3975 {
3976 if (!jsonValue || jsonValue->IsNull()) {
3977 LOGD("invalid json value");
3978 return false;
3979 }
3980 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
3981 LOGE("json value is not numner, string or object");
3982 return false;
3983 }
3984 if (jsonValue->IsNumber()) {
3985 result = Dimension(jsonValue->GetDouble(), defaultUnit);
3986 return true;
3987 }
3988 if (jsonValue->IsString()) {
3989 result = StringUtils::StringToDimensionWithUnit(jsonValue->GetString(), defaultUnit);
3990 return true;
3991 }
3992 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
3993 auto resId = resVal->GetValue("id");
3994 if (!resId || !resId->IsNumber()) {
3995 LOGE("invalid resource id");
3996 return false;
3997 }
3998 auto themeConstants = GetThemeConstants();
3999 if (!themeConstants) {
4000 LOGE("themeConstants is nullptr");
4001 return false;
4002 }
4003 result = themeConstants->GetDimension(resId->GetUInt());
4004 return true;
4005 }
4006
ParseJsonDimensionVp(const std::unique_ptr<JsonValue> & jsonValue,Dimension & result)4007 bool JSViewAbstract::ParseJsonDimensionVp(const std::unique_ptr<JsonValue>& jsonValue, Dimension& result)
4008 {
4009 return ParseJsonDimension(jsonValue, result, DimensionUnit::VP);
4010 }
4011
ParseJsonDouble(const std::unique_ptr<JsonValue> & jsonValue,double & result)4012 bool JSViewAbstract::ParseJsonDouble(const std::unique_ptr<JsonValue>& jsonValue, double& result)
4013 {
4014 if (!jsonValue || jsonValue->IsNull()) {
4015 LOGD("invalid json value");
4016 return false;
4017 }
4018 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
4019 LOGE("json value is not numner, string or object");
4020 return false;
4021 }
4022 if (jsonValue->IsNumber()) {
4023 result = jsonValue->GetDouble();
4024 return true;
4025 }
4026 if (jsonValue->IsString()) {
4027 result = StringUtils::StringToDouble(jsonValue->GetString());
4028 return true;
4029 }
4030 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
4031 auto resId = resVal->GetValue("id");
4032 if (!resId || !resId->IsNumber()) {
4033 LOGE("invalid resource id");
4034 return false;
4035 }
4036 auto themeConstants = GetThemeConstants();
4037 if (!themeConstants) {
4038 LOGW("themeConstants is nullptr");
4039 return false;
4040 }
4041 result = themeConstants->GetDouble(resId->GetUInt());
4042 return true;
4043 }
4044
ParseJsonColor(const std::unique_ptr<JsonValue> & jsonValue,Color & result)4045 bool JSViewAbstract::ParseJsonColor(const std::unique_ptr<JsonValue>& jsonValue, Color& result)
4046 {
4047 if (!jsonValue || jsonValue->IsNull()) {
4048 LOGD("invalid json value");
4049 return false;
4050 }
4051 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
4052 LOGE("json value is not numner, string or object");
4053 return false;
4054 }
4055 if (jsonValue->IsNumber()) {
4056 result = Color(ColorAlphaAdapt(jsonValue->GetUInt()));
4057 return true;
4058 }
4059 if (jsonValue->IsString()) {
4060 result = Color::FromString(jsonValue->GetString());
4061 return true;
4062 }
4063 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
4064 auto resId = resVal->GetValue("id");
4065 if (!resId || !resId->IsNumber()) {
4066 LOGE("invalid resource id");
4067 return false;
4068 }
4069 auto themeConstants = GetThemeConstants();
4070 if (!themeConstants) {
4071 LOGW("themeConstants is nullptr");
4072 return false;
4073 }
4074 result = themeConstants->GetColor(resId->GetUInt());
4075 return true;
4076 }
4077
GetAngle(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,std::optional<float> & angle)4078 void JSViewAbstract::GetAngle(
4079 const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, std::optional<float>& angle)
4080 {
4081 auto value = jsonValue->GetValue(key);
4082 if (value && value->IsString()) {
4083 angle = static_cast<float>(StringUtils::StringToDegree(value->GetString()));
4084 } else if (value && value->IsNumber()) {
4085 angle = static_cast<float>(value->GetDouble());
4086 } else {
4087 LOGE("Invalid value type");
4088 }
4089 }
4090
GetGradientColorStops(Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)4091 void JSViewAbstract::GetGradientColorStops(Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
4092 {
4093 if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
4094 return;
4095 }
4096
4097 for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
4098 GradientColor gradientColor;
4099 auto item = colorStops->GetArrayItem(i);
4100 if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
4101 auto colorParams = item->GetArrayItem(0);
4102 // color
4103 Color color;
4104 if (!ParseJsonColor(colorParams, color)) {
4105 LOGE("parse colorParams failed");
4106 continue;
4107 }
4108 gradientColor.SetColor(color);
4109 gradientColor.SetHasValue(false);
4110 // stop value
4111 if (item->GetArraySize() <= 1) {
4112 continue;
4113 }
4114 auto stopValue = item->GetArrayItem(1);
4115 double value = 0.0;
4116 if (ParseJsonDouble(stopValue, value)) {
4117 value = std::clamp(value, 0.0, 1.0);
4118 gradientColor.SetHasValue(true);
4119 // [0, 1] -> [0, 100.0];
4120 gradientColor.SetDimension(Dimension(value * 100.0, DimensionUnit::PERCENT));
4121 }
4122
4123 gradient.AddColor(gradientColor);
4124 }
4125 }
4126 }
4127
SetDirection(const std::string & dir)4128 void JSViewAbstract::SetDirection(const std::string& dir)
4129 {
4130 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
4131 if (!box) {
4132 return;
4133 }
4134
4135 if (dir == "Ltr") {
4136 box->SetTextDirection(TextDirection::LTR);
4137 box->SetInspectorDirection(TextDirection::LTR);
4138 } else if (dir == "Rtl") {
4139 box->SetTextDirection(TextDirection::RTL);
4140 box->SetInspectorDirection(TextDirection::RTL);
4141 } else if (dir == "Auto") {
4142 box->SetTextDirection(
4143 AceApplicationInfo::GetInstance().IsRightToLeft() ? TextDirection::RTL : TextDirection::LTR);
4144 box->SetInspectorDirection(TextDirection::AUTO);
4145 }
4146 }
4147
GetThemeConstants()4148 RefPtr<ThemeConstants> JSViewAbstract::GetThemeConstants()
4149 {
4150 auto container = Container::Current();
4151 if (!container) {
4152 LOGW("container is null");
4153 return nullptr;
4154 }
4155 auto pipelineContext = container->GetPipelineContext();
4156 if (!pipelineContext) {
4157 LOGE("pipelineContext is null!");
4158 return nullptr;
4159 }
4160 auto themeManager = pipelineContext->GetThemeManager();
4161 if (!themeManager) {
4162 LOGE("themeManager is null!");
4163 return nullptr;
4164 }
4165 return themeManager->GetThemeConstants();
4166 }
4167
JsHoverEffect(const JSCallbackInfo & info)4168 void JSViewAbstract::JsHoverEffect(const JSCallbackInfo& info)
4169 {
4170 if (!info[0]->IsNumber()) {
4171 LOGE("info[0] is not a number");
4172 return;
4173 }
4174 auto boxComponent = ViewStackProcessor::GetInstance()->GetBoxComponent();
4175 boxComponent->SetMouseAnimationType(static_cast<HoverAnimationType>(info[0]->ToNumber<int32_t>()));
4176 }
4177
GetTapGesture(const JSCallbackInfo & info,int32_t countNum,int32_t fingerNum)4178 RefPtr<Gesture> JSViewAbstract::GetTapGesture(const JSCallbackInfo& info, int32_t countNum, int32_t fingerNum)
4179 {
4180 auto inspector = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
4181 if (!inspector) {
4182 LOGE("fail to get inspector for on touch event");
4183 return nullptr;
4184 }
4185 auto impl = inspector->GetInspectorFunctionImpl();
4186 RefPtr<Gesture> tapGesture = AceType::MakeRefPtr<TapGesture>(countNum, fingerNum);
4187 RefPtr<JsClickFunction> jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
4188 tapGesture->SetOnActionId(
4189 [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc), impl](GestureEvent& info) {
4190 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
4191 if (impl) {
4192 impl->UpdateEventInfo(info);
4193 }
4194 ACE_SCORING_EVENT("onClick");
4195 func->Execute(info);
4196 });
4197 return tapGesture;
4198 }
4199
JsOnMouse(const JSCallbackInfo & args)4200 void JSViewAbstract::JsOnMouse(const JSCallbackInfo& args)
4201 {
4202 if (args[0]->IsFunction()) {
4203 auto inspector = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
4204 if (!inspector) {
4205 LOGE("fail to get inspector for on mouse event");
4206 return;
4207 }
4208 auto impl = inspector->GetInspectorFunctionImpl();
4209 RefPtr<JsClickFunction> jsOnMouseFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(args[0]));
4210 auto onMouseId = [execCtx = args.GetExecutionContext(), func = std::move(jsOnMouseFunc), impl](
4211 MouseInfo& info) {
4212 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
4213 if (impl) {
4214 impl->UpdateEventInfo(info);
4215 }
4216 ACE_SCORING_EVENT("onMouse");
4217 func->Execute(info);
4218 };
4219 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
4220 box->SetOnMouseId(onMouseId);
4221 }
4222 }
4223
4224 } // namespace OHOS::Ace::Framework
4225