• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "frameworks/bridge/declarative_frontend/jsview/js_interactable_view.h"
17 
18 #include "base/log/ace_scoring_log.h"
19 #include "base/log/log_wrapper.h"
20 #include "bridge/declarative_frontend/engine/functions/js_click_function.h"
21 #include "bridge/declarative_frontend/engine/functions/js_hover_function.h"
22 #include "bridge/declarative_frontend/engine/functions/js_key_function.h"
23 #include "bridge/declarative_frontend/engine/js_execution_scope_defines.h"
24 #include "bridge/declarative_frontend/jsview/js_pan_handler.h"
25 #include "bridge/declarative_frontend/jsview/js_touch_handler.h"
26 #include "bridge/declarative_frontend/jsview/js_utils.h"
27 #include "bridge/declarative_frontend/view_stack_processor.h"
28 #include "core/common/container.h"
29 #include "core/components/gesture_listener/gesture_listener_component.h"
30 #include "core/components_ng/base/view_abstract_model.h"
31 #include "core/components_ng/base/view_stack_processor.h"
32 #include "core/gestures/click_recognizer.h"
33 #include "core/pipeline/base/single_child.h"
34 #include "core/pipeline/pipeline_context.h"
35 
36 #ifdef PLUGIN_COMPONENT_SUPPORTED
37 #include "core/common/plugin_manager.h"
38 #endif
39 
40 namespace OHOS::Ace::Framework {
41 
JsOnTouch(const JSCallbackInfo & args)42 void JSInteractableView::JsOnTouch(const JSCallbackInfo& args)
43 {
44     if (args[0]->IsUndefined() && IsDisableEventVersion()) {
45         ViewAbstractModel::GetInstance()->DisableOnTouch();
46         return;
47     }
48     if (!args[0]->IsFunction()) {
49         return;
50     }
51     RefPtr<JsTouchFunction> jsOnTouchFunc = AceType::MakeRefPtr<JsTouchFunction>(JSRef<JSFunc>::Cast(args[0]));
52     WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
53     auto onTouch = [execCtx = args.GetExecutionContext(), func = std::move(jsOnTouchFunc), node = frameNode](
54                        TouchEventInfo& info) {
55         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
56         ACE_SCORING_EVENT("onTouch");
57         PipelineContext::SetCallBackNode(node);
58         func->Execute(info);
59     };
60     ViewAbstractModel::GetInstance()->SetOnTouch(std::move(onTouch));
61 }
62 
JsOnKey(const JSCallbackInfo & args)63 void JSInteractableView::JsOnKey(const JSCallbackInfo& args)
64 {
65     if (args[0]->IsUndefined() && IsDisableEventVersion()) {
66         ViewAbstractModel::GetInstance()->DisableOnKeyEvent();
67         return;
68     }
69     if (!args[0]->IsFunction()) {
70         return;
71     }
72     RefPtr<JsKeyFunction> JsOnKeyEvent = AceType::MakeRefPtr<JsKeyFunction>(JSRef<JSFunc>::Cast(args[0]));
73     WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
74     auto onKeyEvent = [execCtx = args.GetExecutionContext(), func = std::move(JsOnKeyEvent), node = frameNode](
75                           KeyEventInfo& info) {
76         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
77         ACE_SCORING_EVENT("onKey");
78         PipelineContext::SetCallBackNode(node);
79         func->Execute(info);
80     };
81     ViewAbstractModel::GetInstance()->SetOnKeyEvent(std::move(onKeyEvent));
82 }
83 
JsOnHover(const JSCallbackInfo & info)84 void JSInteractableView::JsOnHover(const JSCallbackInfo& info)
85 {
86     if (info[0]->IsUndefined() && IsDisableEventVersion()) {
87         ViewAbstractModel::GetInstance()->DisableOnHover();
88         return;
89     }
90     if (!info[0]->IsFunction()) {
91         return;
92     }
93     RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
94     WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
95     auto onHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc), node = frameNode](
96                        bool isHover, HoverInfo& hoverInfo) {
97         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
98         ACE_SCORING_EVENT("onHover");
99         PipelineContext::SetCallBackNode(node);
100         func->HoverExecute(isHover, hoverInfo);
101     };
102     ViewAbstractModel::GetInstance()->SetOnHover(std::move(onHover));
103 }
104 
JsOnPan(const JSCallbackInfo & args)105 void JSInteractableView::JsOnPan(const JSCallbackInfo& args)
106 {
107     if (args[0]->IsObject()) {
108         // TODO: JSPanHandler should support ng build
109 #ifndef NG_BUILD
110         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
111         JSPanHandler* handler = obj->Unwrap<JSPanHandler>();
112         if (handler) {
113             handler->CreateComponent(args);
114         }
115 #endif
116     }
117 }
118 
JsOnDelete(const JSCallbackInfo & info)119 void JSInteractableView::JsOnDelete(const JSCallbackInfo& info)
120 {
121     if (info[0]->IsFunction()) {
122         RefPtr<JsFunction> jsOnDeleteFunc =
123             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
124         WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
125         auto onDelete = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDeleteFunc), node = frameNode]() {
126             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
127             ACE_SCORING_EVENT("onDelete");
128             PipelineContext::SetCallBackNode(node);
129             func->Execute();
130         };
131         ViewAbstractModel::GetInstance()->SetOnDelete(std::move(onDelete));
132     }
133 }
134 
JsTouchable(const JSCallbackInfo & info)135 void JSInteractableView::JsTouchable(const JSCallbackInfo& info)
136 {
137     if (info[0]->IsBoolean()) {
138         ViewAbstractModel::GetInstance()->SetTouchable(info[0]->ToBoolean());
139     }
140 }
141 
JsMonopolizeEvents(const JSCallbackInfo & info)142 void JSInteractableView::JsMonopolizeEvents(const JSCallbackInfo& info)
143 {
144     if (info[0]->IsBoolean()) {
145         ViewAbstractModel::GetInstance()->SetMonopolizeEvents(info[0]->ToBoolean());
146     } else {
147         ViewAbstractModel::GetInstance()->SetMonopolizeEvents(false);
148     }
149 }
150 
JsOnClick(const JSCallbackInfo & info)151 void JSInteractableView::JsOnClick(const JSCallbackInfo& info)
152 {
153     JSRef<JSVal> jsOnClickVal = info[0];
154     if (jsOnClickVal->IsUndefined() && IsDisableEventVersion()) {
155         ViewAbstractModel::GetInstance()->DisableOnClick();
156         return;
157     }
158     if (!jsOnClickVal->IsFunction()) {
159         return;
160     }
161     WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
162     auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
163     auto onTap = [execCtx = info.GetExecutionContext(), func = jsOnClickFunc, node = frameNode](GestureEvent& info) {
164         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
165         ACE_SCORING_EVENT("onClick");
166         PipelineContext::SetCallBackNode(node);
167         func->Execute(info);
168     };
169     auto onClick = [execCtx = info.GetExecutionContext(), func = jsOnClickFunc, node = frameNode](
170                        const ClickInfo* info) {
171         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
172         ACE_SCORING_EVENT("onClick");
173         PipelineContext::SetCallBackNode(node);
174         func->Execute(*info);
175     };
176 
177     ViewAbstractModel::GetInstance()->SetOnClick(std::move(onTap), std::move(onClick));
178     auto focusHub = NG::ViewStackProcessor::GetInstance()->GetOrCreateMainFrameNodeFocusHub();
179     CHECK_NULL_VOID(focusHub);
180     focusHub->SetFocusable(true, false);
181 }
182 
SetFocusable(bool focusable)183 void JSInteractableView::SetFocusable(bool focusable)
184 {
185     ViewAbstractModel::GetInstance()->SetFocusable(focusable);
186 }
187 
SetFocusNode(bool isFocusNode)188 void JSInteractableView::SetFocusNode(bool isFocusNode)
189 {
190     ViewAbstractModel::GetInstance()->SetFocusNode(isFocusNode);
191 }
192 
JsOnAppear(const JSCallbackInfo & info)193 void JSInteractableView::JsOnAppear(const JSCallbackInfo& info)
194 {
195     if (info[0]->IsUndefined() && IsDisableEventVersion()) {
196         ViewAbstractModel::GetInstance()->DisableOnAppear();
197         return;
198     }
199     if (info[0]->IsFunction()) {
200         RefPtr<JsFunction> jsOnAppearFunc =
201             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
202         WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
203         auto onAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAppearFunc), node = frameNode]() {
204             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
205             ACE_SCORING_EVENT("onAppear");
206             PipelineContext::SetCallBackNode(node);
207             func->Execute();
208         };
209         ViewAbstractModel::GetInstance()->SetOnAppear(std::move(onAppear));
210     }
211 }
212 
JsOnDisAppear(const JSCallbackInfo & info)213 void JSInteractableView::JsOnDisAppear(const JSCallbackInfo& info)
214 {
215     if (info[0]->IsUndefined() && IsDisableEventVersion()) {
216         ViewAbstractModel::GetInstance()->DisableOnDisAppear();
217         return;
218     }
219     if (info[0]->IsFunction()) {
220         RefPtr<JsFunction> jsOnDisAppearFunc =
221             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
222         WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
223         auto onDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDisAppearFunc),
224                                node = frameNode]() {
225             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
226             ACE_SCORING_EVENT("onDisAppear");
227             PipelineContext::SetCallBackNode(node);
228             func->Execute();
229         };
230         ViewAbstractModel::GetInstance()->SetOnDisAppear(std::move(onDisappear));
231     }
232 }
233 
JsOnAccessibility(const JSCallbackInfo & info)234 void JSInteractableView::JsOnAccessibility(const JSCallbackInfo& info)
235 {
236     if (!info[0]->IsFunction()) {
237         return;
238     }
239     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
240     WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
241     auto onAccessibility = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
242                                const std::string& param) {
243         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
244         ACE_SCORING_EVENT("onAccessibility");
245         PipelineContext::SetCallBackNode(node);
246 
247         func->Execute({ "eventType" }, param);
248     };
249     ViewAbstractModel::GetInstance()->SetOnAccessibility(std::move(onAccessibility));
250 }
251 
JsCommonRemoteMessage(const JSCallbackInfo & info)252 void JSInteractableView::JsCommonRemoteMessage(const JSCallbackInfo& info)
253 {
254     if (info.Length() != 0 && info[0]->IsObject()) {
255         RemoteCallback remoteCallback;
256         JsRemoteMessage(info, remoteCallback);
257         ViewAbstractModel::GetInstance()->SetOnRemoteMessage(std::move(remoteCallback));
258     }
259 }
260 
JsRemoteMessage(const JSCallbackInfo & info,RemoteCallback & remoteCallback)261 void JSInteractableView::JsRemoteMessage(const JSCallbackInfo& info, RemoteCallback& remoteCallback)
262 {
263     if (!info[0]->IsObject()) {
264         return;
265     }
266 
267     auto eventCallback = GetRemoteMessageEventCallback(info);
268     remoteCallback = [func = std::move(eventCallback)](const BaseEventInfo* info) {
269         auto touchInfo = TypeInfoHelper::DynamicCast<ClickInfo>(info);
270         if (touchInfo && touchInfo->GetType().compare("onClick") == 0) {
271             func();
272         }
273     };
274 }
275 
GetRemoteMessageEventCallback(const JSCallbackInfo & info)276 std::function<void()> JSInteractableView::GetRemoteMessageEventCallback(const JSCallbackInfo& info)
277 {
278     auto obj = JSRef<JSObject>::Cast(info[0]);
279     auto actionValue = obj->GetProperty("action");
280     std::string action;
281     if (actionValue->IsString()) {
282         action = actionValue->ToString();
283     }
284     auto abilityValue = obj->GetProperty("ability");
285     std::string ability;
286     if (abilityValue->IsString()) {
287         ability = abilityValue->ToString();
288     }
289     auto paramsObj = obj->GetProperty("params");
290     std::string params;
291     if (paramsObj->IsObject()) {
292         params = paramsObj->ToString();
293     }
294     auto eventCallback = [action, ability, params]() {
295         if (action.compare("message") == 0) {
296             // onCall
297         } else if (action.compare("route") == 0) {
298             // startAbility
299 #ifdef PLUGIN_COMPONENT_SUPPORTED
300             std::vector<std::string> strList;
301             SplitString(ability, '/', strList);
302             if (strList.size() <= 1) {
303                 return;
304             }
305             int32_t result = PluginManager::GetInstance().StartAbility(strList[0], strList[1], params);
306             if (result != 0) {
307                 LOGW("Failed to start the APP %{public}s.", ability.c_str());
308             }
309 #else
310             LOGW("Unsupported Windows and Mac platforms to start APP.");
311 #endif
312         }
313     };
314 
315     return eventCallback;
316 }
317 
SplitString(const std::string & str,char tag,std::vector<std::string> & strList)318 void JSInteractableView::SplitString(const std::string& str, char tag, std::vector<std::string>& strList)
319 {
320     std::string subStr;
321     for (size_t i = 0; i < str.length(); i++) {
322         if (tag == str[i]) {
323             if (!subStr.empty()) {
324                 strList.push_back(subStr);
325                 subStr.clear();
326             }
327         } else {
328             subStr.push_back(str[i]);
329         }
330     }
331     if (!subStr.empty()) {
332         strList.push_back(subStr);
333     }
334 }
335 } // namespace OHOS::Ace::Framework
336