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