1 /*
2 * Copyright (c) 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 "frameworks/bridge/declarative_frontend/jsview/js_relative_container.h"
17
18 #include "base/log/ace_trace.h"
19 #include "bridge/declarative_frontend/jsview/models/relative_container_model_impl.h"
20 #include "core/components_ng/pattern/relative_container/relative_container_model_ng.h"
21 #include "frameworks/bridge/declarative_frontend/engine/js_ref_ptr.h"
22 #include "frameworks/bridge/declarative_frontend/jsview/js_view_common_def.h"
23 #include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
24
25 namespace OHOS::Ace {
26
27 constexpr int32_t LOCALIZED_BARRIER_DIRECTION_START = 4;
28
GetInstance()29 RelativeContainerModel* RelativeContainerModel::GetInstance()
30 {
31 #ifdef NG_BUILD
32 static NG::RelativeContainerModelNG instance;
33 return &instance;
34 #else
35 if (Container::IsCurrentUseNewPipeline()) {
36 static NG::RelativeContainerModelNG instance;
37 return &instance;
38 } else {
39 static Framework::RelativeContainerModelImpl instance;
40 return &instance;
41 }
42 #endif
43 }
44 } // namespace OHOS::Ace
45
46 namespace OHOS::Ace::Framework {
47
JSBind(BindingTarget globalObj)48 void JSRelativeContainer::JSBind(BindingTarget globalObj)
49 {
50 JSClass<JSRelativeContainer>::Declare("RelativeContainer");
51 MethodOptions opt = MethodOptions::NONE;
52 JSClass<JSRelativeContainer>::StaticMethod("create", &JSRelativeContainer::Create, opt);
53 JSClass<JSRelativeContainer>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
54 JSClass<JSRelativeContainer>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
55 JSClass<JSRelativeContainer>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
56 JSClass<JSRelativeContainer>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
57 JSClass<JSRelativeContainer>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
58 JSClass<JSRelativeContainer>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
59 JSClass<JSRelativeContainer>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
60 JSClass<JSRelativeContainer>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
61 JSClass<JSRelativeContainer>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
62 JSClass<JSRelativeContainer>::StaticMethod("remoteMessage", &JSInteractableView::JsCommonRemoteMessage);
63 JSClass<JSRelativeContainer>::StaticMethod("barrier", &JSRelativeContainer::JsBarrier);
64 JSClass<JSRelativeContainer>::StaticMethod("guideLine", &JSRelativeContainer::JsGuideline);
65 JSClass<JSRelativeContainer>::InheritAndBind<JSContainerBase>(globalObj);
66 }
67
Create(const JSCallbackInfo & info)68 void JSRelativeContainer::Create(const JSCallbackInfo& info)
69 {
70 RelativeContainerModel::GetInstance()->Create();
71 }
72
ParseBarrierInfo(const JSRef<JSVal> & args,BarrierInfo & barrierInfoItem)73 void JSRelativeContainer::ParseBarrierInfo(const JSRef<JSVal>& args, BarrierInfo& barrierInfoItem)
74 {
75 if (!args->IsObject()) {
76 return;
77 }
78 JSRef<JSObject> barrierInfoObj = JSRef<JSObject>::Cast(args);
79 JSRef<JSVal> idVal = barrierInfoObj->GetProperty("id");
80 JSRef<JSVal> directionVal = barrierInfoObj->GetProperty("direction");
81 JSRef<JSVal> localizedDirectionVal = barrierInfoObj->GetProperty("localizedDirection");
82 JSRef<JSVal> referencedIdVal = barrierInfoObj->GetProperty("referencedId");
83
84 if (idVal->IsString()) {
85 barrierInfoItem.id = idVal->ToString();
86 }
87
88 if (directionVal->IsNumber()) {
89 auto direction = directionVal->ToNumber<int32_t>();
90 barrierInfoItem.direction = static_cast<BarrierDirection>(direction);
91 } else if (localizedDirectionVal->IsNumber()) {
92 auto direction = localizedDirectionVal->ToNumber<int32_t>();
93 if (direction > static_cast<int32_t>(BarrierDirection::RIGHT)) {
94 barrierInfoItem.direction = static_cast<BarrierDirection>(direction);
95 } else {
96 barrierInfoItem.direction = static_cast<BarrierDirection>(direction + LOCALIZED_BARRIER_DIRECTION_START);
97 }
98 }
99
100 if (referencedIdVal->IsArray()) {
101 JSRef<JSArray> array = JSRef<JSArray>::Cast(referencedIdVal);
102 for (size_t i = 0; i < array->Length(); i++) {
103 JSRef<JSVal> idVal = array->GetValueAt(i);
104 if (idVal->IsString()) {
105 barrierInfoItem.referencedId.emplace_back(idVal->ToString());
106 }
107 }
108 }
109 }
110
JsBarrier(const JSCallbackInfo & info)111 void JSRelativeContainer::JsBarrier(const JSCallbackInfo& info)
112 {
113 auto tmpInfo = info[0];
114 std::vector<BarrierInfo> barrierInfos;
115 if (tmpInfo->IsUndefined()) {
116 RelativeContainerModel::GetInstance()->SetBarrier(barrierInfos);
117 return;
118 }
119 if (!tmpInfo->IsArray() && !tmpInfo->IsObject()) {
120 RelativeContainerModel::GetInstance()->SetBarrier(barrierInfos);
121 return;
122 }
123
124 if (tmpInfo->IsArray()) {
125 JSRef<JSArray> array = JSRef<JSArray>::Cast(tmpInfo);
126 for (size_t i = 0; i < array->Length(); i++) {
127 BarrierInfo barrierInfoItem;
128 ParseBarrierInfo(array->GetValueAt(i), barrierInfoItem);
129 barrierInfos.emplace_back(barrierInfoItem);
130 }
131 }
132
133 RelativeContainerModel::GetInstance()->SetBarrier(barrierInfos);
134 }
135
ParseGuideline(const JSRef<JSVal> & args,GuidelineInfo & guidelineInfoItem)136 void JSRelativeContainer::ParseGuideline(const JSRef<JSVal>& args, GuidelineInfo& guidelineInfoItem)
137 {
138 if (!args->IsObject()) {
139 return;
140 }
141 JSRef<JSObject> guildLineInfoObj = JSRef<JSObject>::Cast(args);
142 JSRef<JSVal> idVal = guildLineInfoObj->GetProperty("id");
143 JSRef<JSVal> directionVal = guildLineInfoObj->GetProperty("direction");
144 JSRef<JSVal> positionVal = guildLineInfoObj->GetProperty("position");
145
146 if (idVal->IsString()) {
147 guidelineInfoItem.id = idVal->ToString();
148 }
149
150 if (directionVal->IsNumber()) {
151 auto direction = directionVal->ToNumber<int32_t>();
152 guidelineInfoItem.direction = static_cast<LineDirection>(direction);
153 }
154
155 CalcDimension start;
156 CalcDimension end;
157 if (positionVal->IsObject()) {
158 JSRef<JSObject> val = JSRef<JSObject>::Cast(positionVal);
159 JSRef<JSVal> startVal = val->GetProperty("start");
160 JSRef<JSVal> endVal = val->GetProperty("end");
161
162 if (JSViewAbstract::ParseJsDimensionVpNG(startVal, start)) {
163 guidelineInfoItem.start = start;
164 }
165 if (JSViewAbstract::ParseJsDimensionVpNG(endVal, end)) {
166 guidelineInfoItem.end = end;
167 }
168 }
169 }
170
JsGuideline(const JSCallbackInfo & info)171 void JSRelativeContainer::JsGuideline(const JSCallbackInfo& info)
172 {
173 auto tmpInfo = info[0];
174 std::vector<GuidelineInfo> guidelineInfos;
175 if (tmpInfo->IsUndefined()) {
176 RelativeContainerModel::GetInstance()->SetGuideline(guidelineInfos);
177 return;
178 }
179 if (!tmpInfo->IsArray() && !tmpInfo->IsObject()) {
180 RelativeContainerModel::GetInstance()->SetGuideline(guidelineInfos);
181 return;
182 }
183
184 if (tmpInfo->IsArray()) {
185 JSRef<JSArray> array = JSRef<JSArray>::Cast(tmpInfo);
186 for (size_t i = 0; i < array->Length(); i++) {
187 GuidelineInfo guidelineInfoItem;
188 ParseGuideline(array->GetValueAt(i), guidelineInfoItem);
189 guidelineInfos.emplace_back(guidelineInfoItem);
190 }
191 }
192 RelativeContainerModel::GetInstance()->SetGuideline(guidelineInfos);
193 }
194 } // namespace OHOS::Ace::Framework
195