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_navdestination.h"
17
18 #include "base/log/ace_scoring_log.h"
19 #include "bridge/declarative_frontend/jsview/js_utils.h"
20 #include "core/components_ng/base/view_stack_processor.h"
21 #include "core/components_ng/pattern/navigation/navigation_declaration.h"
22 #include "core/components_ng/pattern/navrouter/navdestination_view.h"
23
24 namespace OHOS::Ace::Framework {
25
26 namespace {
27
ParseCommonTitle(const JSRef<JSVal> & jsValue)28 bool ParseCommonTitle(const JSRef<JSVal>& jsValue)
29 {
30 if (!Container::IsCurrentUseNewPipeline()) {
31 return false;
32 }
33
34 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
35 JSRef<JSVal> title = jsObj->GetProperty("main");
36 bool isCommonTitle = false;
37 if (title->IsString()) {
38 NG::NavDestinationView::SetTitle(title->ToString());
39 isCommonTitle = true;
40 }
41 JSRef<JSVal> subtitle = jsObj->GetProperty("sub");
42 if (subtitle->IsString()) {
43 NG::NavDestinationView::SetSubtitle(subtitle->ToString());
44 isCommonTitle = true;
45 }
46 return isCommonTitle;
47 }
48
49 } // namespace
50
Create()51 void JSNavDestination::Create()
52 {
53 if (!Container::IsCurrentUseNewPipeline()) {
54 return;
55 }
56 NG::NavDestinationView::Create();
57 }
58
Create(const JSCallbackInfo & info)59 void JSNavDestination::Create(const JSCallbackInfo& info)
60 {
61 if (!Container::IsCurrentUseNewPipeline()) {
62 return;
63 }
64 CreateForPartialUpdate(info);
65 }
66
CreateForPartialUpdate(const JSCallbackInfo & info)67 void JSNavDestination::CreateForPartialUpdate(const JSCallbackInfo& info)
68 {
69 if (info.Length() <= 0 && !info[0]->IsFunction()) {
70 NG::NavDestinationView::Create();
71 return;
72 }
73
74 JSRef<JSVal> builderFunctionJS = info[0];
75 auto builderFunc = [context = info.GetExecutionContext(), builder = std::move(builderFunctionJS)]() {
76 JAVASCRIPT_EXECUTION_SCOPE(context)
77 JSRef<JSFunc>::Cast(builder)->Call(JSRef<JSObject>());
78 };
79 NG::NavDestinationView::Create(std::move(builderFunc));
80 }
81
SetHideTitleBar(bool hide)82 void JSNavDestination::SetHideTitleBar(bool hide)
83 {
84 if (!Container::IsCurrentUseNewPipeline()) {
85 return;
86 }
87 NG::NavDestinationView::SetHideTitleBar(hide);
88 }
89
SetTitle(const JSCallbackInfo & info)90 void JSNavDestination::SetTitle(const JSCallbackInfo& info)
91 {
92 if (!Container::IsCurrentUseNewPipeline()) {
93 return;
94 }
95 if (info.Length() < 1) {
96 LOGE("The arg is wrong, it is supposed to have at least 1 argument");
97 return;
98 }
99
100 if (info[0]->IsString()) {
101 NG::NavDestinationView::SetTitle(info[0]->ToString());
102 } else if (info[0]->IsObject()) {
103 if (ParseCommonTitle(info[0])) {
104 return;
105 }
106
107 // CustomBuilder | NavigationCustomTitle
108 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
109 JSRef<JSVal> builderObject = jsObj->GetProperty("builder");
110 if (builderObject->IsFunction()) {
111 RefPtr<NG::UINode> customNode;
112 {
113 NG::ScopedViewStackProcessor builderViewStackProcessor;
114 JsFunction jsBuilderFunc(info.This(), JSRef<JSObject>::Cast(builderObject));
115 ACE_SCORING_EVENT("Navdestination.title.builder");
116 jsBuilderFunc.Execute();
117 customNode = NG::ViewStackProcessor::GetInstance()->Finish();
118 }
119 NG::NavDestinationView::SetCustomTitle(customNode);
120 }
121
122 JSRef<JSVal> height = jsObj->GetProperty("height");
123 if (height->IsNumber()) {
124 if (height->ToNumber<int32_t>() == 0) {
125 NG::NavDestinationView::SetTitleHeight(NG::FULL_SINGLE_LINE_TITLEBAR_HEIGHT);
126 }
127 if (height->ToNumber<int32_t>() == 1) {
128 NG::NavDestinationView::SetTitleHeight(NG::FULL_DOUBLE_LINE_TITLEBAR_HEIGHT);
129 }
130 Dimension titleHeight;
131 if (!JSContainerBase::ParseJsDimensionVp(height, titleHeight)) {
132 return;
133 }
134 NG::NavDestinationView::SetTitleHeight(titleHeight);
135 }
136 } else {
137 LOGE("arg is not [String|Function].");
138 }
139 }
140
JSBind(BindingTarget globalObj)141 void JSNavDestination::JSBind(BindingTarget globalObj)
142 {
143 JSClass<JSNavDestination>::Declare("NavDestination");
144 JSClass<JSNavDestination>::StaticMethod("create", &JSNavDestination::Create);
145 JSClass<JSNavDestination>::StaticMethod("title", &JSNavDestination::SetTitle);
146 JSClass<JSNavDestination>::StaticMethod("hideTitleBar", &JSNavDestination::SetHideTitleBar);
147 JSClass<JSNavDestination>::Inherit<JSContainerBase>();
148 JSClass<JSNavDestination>::Inherit<JSViewAbstract>();
149 JSClass<JSNavDestination>::Bind<>(globalObj);
150 }
151
152 } // namespace OHOS::Ace::Framework