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