• 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_marquee.h"
17 #include <limits>
18 #include <optional>
19 #include <string>
20 #include <vector>
21 
22 #include "base/geometry/dimension.h"
23 #include "base/log/ace_scoring_log.h"
24 #include "base/utils/utils.h"
25 #include "bridge/declarative_frontend/engine/functions/js_function.h"
26 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
27 #include "bridge/declarative_frontend/jsview/models/marquee_model_impl.h"
28 #include "core/components/text/text_theme.h"
29 #include "core/components_ng/base/view_stack_processor.h"
30 #include "core/components_ng/pattern/marquee/marquee_model.h"
31 #include "core/components_ng/pattern/marquee/marquee_model_ng.h"
32 
33 namespace OHOS::Ace {
34 
35 std::unique_ptr<MarqueeModel> MarqueeModel::instance_ = nullptr;
36 std::mutex MarqueeModel::mutex_;
GetInstance()37 MarqueeModel* MarqueeModel::GetInstance()
38 {
39     if (!instance_) {
40         std::lock_guard<std::mutex> lock(mutex_);
41         if (!instance_) {
42 #ifdef NG_BUILD
43             instance_.reset(new NG::MarqueeModelNG());
44 #else
45             if (Container::IsCurrentUseNewPipeline()) {
46                 instance_.reset(new NG::MarqueeModelNG());
47             } else {
48                 instance_.reset(new Framework::MarqueeModelImpl());
49             }
50 #endif
51         }
52     }
53     return instance_.get();
54 }
55 } // namespace OHOS::Ace
56 
57 namespace OHOS::Ace::Framework {
58 
59 const std::vector<MarqueeUpdateStrategy> MARQUEE_UPDATE_STRATEGYS = { MarqueeUpdateStrategy::DEFAULT,
60     MarqueeUpdateStrategy::PRESERVE_POSITION};
61 
Create(const JSCallbackInfo & info)62 void JSMarquee::Create(const JSCallbackInfo& info)
63 {
64     if (info.Length() < 1 || !info[0]->IsObject()) {
65         return;
66     }
67 
68     MarqueeModel::GetInstance()->Create();
69     auto paramObject = JSRef<JSObject>::Cast(info[0]);
70     auto src = paramObject->GetProperty("src");
71     std::optional<std::string> srcOpt;
72     if (src->IsString()) {
73         srcOpt = src->ToString();
74     }
75     MarqueeModel::GetInstance()->SetValue(srcOpt);
76 
77     auto getStart = paramObject->GetProperty("start");
78     std::optional<bool> startOpt = getStart->IsBoolean() ? getStart->ToBoolean() : false;
79     MarqueeModel::GetInstance()->SetPlayerStatus(startOpt);
80 
81     auto getStep = paramObject->GetProperty("step");
82     std::optional<double> stepOpt;
83     if (getStep->IsNumber()) {
84         auto step = getStep->ToNumber<double>();
85         if (GreatNotEqual(step, 0.0)) {
86             stepOpt = Dimension(step, DimensionUnit::VP).ConvertToPx();
87         }
88     }
89     MarqueeModel::GetInstance()->SetScrollAmount(stepOpt);
90 
91     auto getLoop = paramObject->GetProperty("loop");
92     std::optional<int32_t> loopOpt;
93     if (getLoop->IsNumber()) {
94         auto loopDouble = getLoop->ToNumber<double>();
95         int32_t loop = -1;
96         if (GreatNotEqual(loopDouble, 0.0)) {
97             loop = static_cast<int32_t>(loopDouble);
98             if (loop == std::numeric_limits<int32_t>::max() || loop < 0) {
99                 loop = -1;
100             }
101         }
102         loopOpt = loop;
103     }
104     MarqueeModel::GetInstance()->SetLoop(loopOpt);
105 
106     auto getFromStart = paramObject->GetProperty("fromStart");
107     bool fromStart = getFromStart->IsBoolean() ? getFromStart->ToBoolean() : true;
108     std::optional<MarqueeDirection> directionOpt;
109     if (fromStart) {
110         directionOpt = MarqueeDirection::LEFT;
111     } else {
112         directionOpt = MarqueeDirection::RIGHT;
113     }
114     MarqueeModel::GetInstance()->SetDirection(directionOpt);
115 }
116 
JSBind(BindingTarget globalObj)117 void JSMarquee::JSBind(BindingTarget globalObj)
118 {
119     JSClass<JSMarquee>::Declare("Marquee");
120     MethodOptions opt = MethodOptions::NONE;
121     JSClass<JSMarquee>::StaticMethod("create", &JSMarquee::Create, opt);
122     JSClass<JSMarquee>::StaticMethod("allowScale", &JSMarquee::SetAllowScale);
123     JSClass<JSMarquee>::StaticMethod("fontColor", &JSMarquee::SetTextColor);
124     JSClass<JSMarquee>::StaticMethod("fontSize", &JSMarquee::SetFontSize);
125     JSClass<JSMarquee>::StaticMethod("fontWeight", &JSMarquee::SetFontWeight);
126     JSClass<JSMarquee>::StaticMethod("fontFamily", &JSMarquee::SetFontFamily);
127     JSClass<JSMarquee>::StaticMethod("marqueeUpdateStrategy", &JSMarquee::SetMarqueeUpdateStrategy);
128     JSClass<JSMarquee>::StaticMethod("onStart", &JSMarquee::OnStart);
129     JSClass<JSMarquee>::StaticMethod("onBounce", &JSMarquee::OnBounce);
130     JSClass<JSMarquee>::StaticMethod("onFinish", &JSMarquee::OnFinish);
131     JSClass<JSMarquee>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
132     JSClass<JSMarquee>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
133     JSClass<JSMarquee>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
134     JSClass<JSMarquee>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
135     JSClass<JSMarquee>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
136     JSClass<JSMarquee>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
137     JSClass<JSMarquee>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
138     JSClass<JSMarquee>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
139     JSClass<JSMarquee>::InheritAndBind<JSViewAbstract>(globalObj);
140 }
141 
SetTextColor(const JSCallbackInfo & info)142 void JSMarquee::SetTextColor(const JSCallbackInfo& info)
143 {
144     if (info.Length() < 1) {
145         return;
146     }
147     std::optional<Color> colorOpt;
148     Color color;
149     if (ParseJsColor(info[0], color)) {
150         colorOpt = color;
151     }
152     MarqueeModel::GetInstance()->SetTextColor(colorOpt);
153 }
154 
SetFontSize(const JSCallbackInfo & info)155 void JSMarquee::SetFontSize(const JSCallbackInfo& info)
156 {
157     if (info.Length() < 1) {
158         return;
159     }
160     std::optional<Dimension> fontSizeOpt;
161     CalcDimension fontSize;
162     if (ParseJsDimensionFp(info[0], fontSize)) {
163         if (!fontSize.IsNegative() && fontSize.Unit() != DimensionUnit::PERCENT) {
164             fontSizeOpt = fontSize;
165         }
166     }
167     MarqueeModel::GetInstance()->SetFontSize(fontSizeOpt);
168 }
169 
SetAllowScale(const JSCallbackInfo & info)170 void JSMarquee::SetAllowScale(const JSCallbackInfo& info)
171 {
172     if (info.Length() < 1) {
173         return;
174     }
175     std::optional<bool> allowScaleOpt;
176     if (info[0]->IsBoolean()) {
177         allowScaleOpt = info[0]->ToBoolean();
178     }
179     MarqueeModel::GetInstance()->SetAllowScale(allowScaleOpt);
180 }
181 
SetFontWeight(const std::string & value)182 void JSMarquee::SetFontWeight(const std::string& value)
183 {
184     std::optional<FontWeight> fontWeightOpt = ConvertStrToFontWeight(value);
185     MarqueeModel::GetInstance()->SetFontWeight(fontWeightOpt);
186 }
187 
SetFontFamily(const JSCallbackInfo & info)188 void JSMarquee::SetFontFamily(const JSCallbackInfo& info)
189 {
190     if (info.Length() < 1) {
191         return;
192     }
193     std::optional<std::vector<std::string>> fontFamiliesOpt;
194     std::vector<std::string> fontFamilies;
195     if (ParseJsFontFamilies(info[0], fontFamilies)) {
196         fontFamiliesOpt = fontFamilies;
197     }
198     MarqueeModel::GetInstance()->SetFontFamily(fontFamiliesOpt);
199 }
200 
SetMarqueeUpdateStrategy(const std::string & value)201 void JSMarquee::SetMarqueeUpdateStrategy(const std::string& value)
202 {
203     static const LinearMapNode<MarqueeUpdateStrategy> marqueeUpdateStrategyTable[] = {
204         { "default", MarqueeUpdateStrategy::DEFAULT },
205         { "preserve_position", MarqueeUpdateStrategy::PRESERVE_POSITION },
206     };
207     auto marqueeUpdateStrategyIter = BinarySearchFindIndex(marqueeUpdateStrategyTable,
208         ArraySize(marqueeUpdateStrategyTable), value.c_str());
209     auto marqueeUpdateStrategyValue = marqueeUpdateStrategyIter != -1 ?
210         std::make_optional(MARQUEE_UPDATE_STRATEGYS[marqueeUpdateStrategyIter]) :
211         std::make_optional(MarqueeUpdateStrategy::DEFAULT);
212     MarqueeModel::GetInstance()->SetMarqueeUpdateStrategy(marqueeUpdateStrategyValue);
213 }
214 
OnStart(const JSCallbackInfo & info)215 void JSMarquee::OnStart(const JSCallbackInfo& info)
216 {
217     if (!info[0]->IsFunction()) {
218         return;
219     }
220 
221     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
222     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
223     auto onChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
224         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
225         ACE_SCORING_EVENT("Marquee.onStart");
226         PipelineContext::SetCallBackNode(node);
227         func->ExecuteJS();
228     };
229     MarqueeModel::GetInstance()->SetOnStart(std::move(onChange));
230 }
231 
OnBounce(const JSCallbackInfo & info)232 void JSMarquee::OnBounce(const JSCallbackInfo& info)
233 {
234     if (!info[0]->IsFunction()) {
235         return;
236     }
237 
238     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
239     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
240     auto onChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
241         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
242         ACE_SCORING_EVENT("Marquee.onBounce");
243         PipelineContext::SetCallBackNode(node);
244         func->ExecuteJS();
245     };
246     MarqueeModel::GetInstance()->SetOnBounce(std::move(onChange));
247 }
248 
OnFinish(const JSCallbackInfo & info)249 void JSMarquee::OnFinish(const JSCallbackInfo& info)
250 {
251     if (!info[0]->IsFunction()) {
252         return;
253     }
254 
255     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
256     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
257     auto onChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
258         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
259         ACE_SCORING_EVENT("Marquee.onFinish");
260         PipelineContext::SetCallBackNode(node);
261         func->ExecuteJS();
262     };
263     MarqueeModel::GetInstance()->SetOnFinish(std::move(onChange));
264 }
265 
266 } // namespace OHOS::Ace::Framework
267