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_stack_processor.h"
17
18 #include "bridge/declarative_frontend/engine/bindings.h"
19 #include "bridge/declarative_frontend/engine/js_types.h"
20 #include "bridge/declarative_frontend/jsview/models/view_stack_model_impl.h"
21 #include "bridge/declarative_frontend/view_stack_processor.h"
22 #include "core/common/container.h"
23 #include "core/components_ng/base/view_stack_model.h"
24 #include "core/components_ng/base/view_stack_model_ng.h"
25 #include "core/components_ng/base/view_stack_processor.h"
26 #include "frameworks/core/pipeline/base/element_register.h"
27 #include "foundation/arkui/ace_engine/frameworks/core/common/ace_application_info.h"
28
29 namespace OHOS::Ace {
30
GetInstance()31 ViewStackModel* ViewStackModel::GetInstance()
32 {
33 #ifdef NG_BUILD
34 static NG::ViewStackModelNG instance;
35 return &instance;
36 #else
37 if (Container::IsCurrentUseNewPipeline()) {
38 static NG::ViewStackModelNG instance;
39 return &instance;
40 } else {
41 static Framework::ViewStackModelImpl instance;
42 return &instance;
43 }
44 #endif
45 }
46
47 } // namespace OHOS::Ace
48 namespace OHOS::Ace::Framework {
49
JSVisualState(const JSCallbackInfo & info)50 void JSViewStackProcessor::JSVisualState(const JSCallbackInfo& info)
51 {
52 if ((info.Length() < 1) || (!info[0]->IsString())) {
53 ViewStackModel::GetInstance()->ClearVisualState();
54 return;
55 }
56
57 std::string state = info[0]->ToString();
58 VisualState visualState = JSViewStackProcessor::StringToVisualState(state);
59 ViewStackModel::GetInstance()->SetVisualState(visualState);
60 }
61
62 // public static emthods exposed to JS
JSBind(BindingTarget globalObj)63 void JSViewStackProcessor::JSBind(BindingTarget globalObj)
64 {
65 JSClass<JSViewStackProcessor>::Declare("ViewStackProcessor");
66 MethodOptions opt = MethodOptions::NONE;
67
68 JSClass<JSViewStackProcessor>::StaticMethod(
69 "AllocateNewElmetIdForNextComponent", &JSViewStackProcessor::JsAllocateNewElmetIdForNextComponent, opt);
70 JSClass<JSViewStackProcessor>::StaticMethod(
71 "StartGetAccessRecordingFor", &JSViewStackProcessor::JsStartGetAccessRecordingFor, opt);
72 JSClass<JSViewStackProcessor>::StaticMethod(
73 "SetElmtIdToAccountFor", &JSViewStackProcessor::JsSetElmtIdToAccountFor, opt);
74 JSClass<JSViewStackProcessor>::StaticMethod(
75 "GetElmtIdToAccountFor", &JSViewStackProcessor::JsGetElmtIdToAccountFor, opt);
76 JSClass<JSViewStackProcessor>::StaticMethod(
77 "StopGetAccessRecording", &JSViewStackProcessor::JsStopGetAccessRecording, opt);
78 JSClass<JSViewStackProcessor>::StaticMethod(
79 "ImplicitPopBeforeContinue", &JSViewStackProcessor::JsImplicitPopBeforeContinue, opt);
80 JSClass<JSViewStackProcessor>::StaticMethod("visualState", JSVisualState, opt);
81 JSClass<JSViewStackProcessor>::StaticMethod("MakeUniqueId", &JSViewStackProcessor::JSMakeUniqueId, opt);
82 JSClass<JSViewStackProcessor>::StaticMethod("UsesNewPipeline", &JSViewStackProcessor::JsUsesNewPipeline, opt);
83 JSClass<JSViewStackProcessor>::StaticMethod("getApiVersion", &JSViewStackProcessor::JsGetApiVersion, opt);
84 JSClass<JSViewStackProcessor>::StaticMethod("GetAndPushFrameNode", &JSViewStackProcessor::JsGetAndPushFrameNode);
85 JSClass<JSViewStackProcessor>::StaticMethod("moveDeletedElmtIds", &JSViewStackProcessor::JsMoveDeletedElmtIds);
86 JSClass<JSViewStackProcessor>::Bind<>(globalObj);
87 }
88
StringToVisualState(const std::string & stateString)89 VisualState JSViewStackProcessor::StringToVisualState(const std::string& stateString)
90 {
91 if (stateString == "normal") {
92 return VisualState::NORMAL;
93 }
94 if (stateString == "focused") {
95 return VisualState::FOCUSED;
96 }
97 if (stateString == "pressed" || stateString == "clicked") {
98 return VisualState::PRESSED;
99 }
100 if (stateString == "disabled") {
101 return VisualState::DISABLED;
102 }
103 if (stateString == "hover") {
104 return VisualState::HOVER;
105 }
106 if (stateString == "selected") {
107 return VisualState::SELECTED;
108 }
109 LOGE("Unknown visual state \"%{public}s\", resetting to UNDEFINED", stateString.c_str());
110 return VisualState::NOTSET;
111 }
112
JsStartGetAccessRecordingFor(ElementIdType elmtId)113 void JSViewStackProcessor::JsStartGetAccessRecordingFor(ElementIdType elmtId)
114 {
115 ViewStackModel::GetInstance()->StartGetAccessRecordingFor(elmtId);
116 }
117
JsGetElmtIdToAccountFor()118 int32_t JSViewStackProcessor::JsGetElmtIdToAccountFor()
119 {
120 return ViewStackModel::GetInstance()->GetElmtIdToAccountFor();
121 }
122
JsSetElmtIdToAccountFor(ElementIdType elmtId)123 void JSViewStackProcessor::JsSetElmtIdToAccountFor(ElementIdType elmtId)
124 {
125 ViewStackModel::GetInstance()->SetElmtIdToAccountFor(elmtId);
126 }
127
JsStopGetAccessRecording()128 void JSViewStackProcessor::JsStopGetAccessRecording()
129 {
130 return ViewStackModel::GetInstance()->StopGetAccessRecording();
131 }
132
JsImplicitPopBeforeContinue()133 void JSViewStackProcessor::JsImplicitPopBeforeContinue()
134 {
135 ViewStackModel::GetInstance()->ImplicitPopBeforeContinue();
136 }
137
JSMakeUniqueId(const JSCallbackInfo & info)138 void JSViewStackProcessor::JSMakeUniqueId(const JSCallbackInfo& info)
139 {
140 const auto result = ElementRegister::GetInstance()->MakeUniqueId();
141 info.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
142 }
JsMoveDeletedElmtIds(const JSCallbackInfo & info)143 void JSViewStackProcessor::JsMoveDeletedElmtIds(const JSCallbackInfo& info)
144 {
145 auto jsArrInfo = info[0];
146 if (!jsArrInfo->IsArray()) {
147 return;
148 }
149 JSRef<JSArray> jsArr = JSRef<JSArray>::Cast(jsArrInfo);
150
151 RemovedElementsType removedElements;
152 ElementRegister::GetInstance()->MoveRemovedItems(removedElements);
153 size_t index = jsArr->Length();
154 for (const auto& rmElmtId : removedElements) {
155 jsArr->SetValueAt(index++, JSRef<JSVal>::Make(ToJSValue(rmElmtId)));
156 }
157 }
158
159 /**
160 * return true of current Container uses new Pipeline
161 */
JsUsesNewPipeline()162 bool JSViewStackProcessor::JsUsesNewPipeline()
163 {
164 auto container = Container::Current();
165 return container ? container->IsUseNewPipeline() : AceApplicationInfo::GetInstance().IsUseNewPipeline();
166 }
167
168 /**
169 * return the API version specified in the manifest.json
170 */
JsGetApiVersion()171 int32_t JSViewStackProcessor::JsGetApiVersion()
172 {
173 return AceApplicationInfo::GetInstance().GetApiTargetVersion();
174 }
175
JsGetAndPushFrameNode(const JSCallbackInfo & info)176 void JSViewStackProcessor::JsGetAndPushFrameNode(const JSCallbackInfo& info)
177 {
178 if (info.Length() < 2) {
179 return;
180 }
181 if (!info[0]->IsString() || !info[1]->IsNumber()) {
182 return;
183 }
184 ViewStackModel::GetInstance()->GetAndPushFrameNode(info[0]->ToString(), info[1]->ToNumber<int32_t>());
185 }
186
187 } // namespace OHOS::Ace::Framework
188