• 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_text_clock.h"
17 
18 #include <regex>
19 #include <string>
20 
21 #include "base/log/ace_scoring_log.h"
22 #include "bridge/declarative_frontend/jsview/js_text.h"
23 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
24 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
25 #include "bridge/declarative_frontend/jsview/models/text_clock_model_impl.h"
26 #include "core/components_ng/pattern/text_clock/text_clock_model.h"
27 #include "core/components_ng/pattern/text_clock/text_clock_model_ng.h"
28 
29 namespace OHOS::Ace {
30 
31 std::unique_ptr<TextClockModel> TextClockModel::instance_ = nullptr;
32 
GetInstance()33 TextClockModel* TextClockModel::GetInstance()
34 {
35     if (!instance_) {
36 #ifdef NG_BUILD
37         instance_.reset(new NG::TextClockModelNG());
38 #else
39         if (Container::IsCurrentUseNewPipeline()) {
40             instance_.reset(new NG::TextClockModelNG());
41         } else {
42             instance_.reset(new Framework::TextClockModelImpl());
43         }
44 #endif
45     }
46     return instance_.get();
47 }
48 } // namespace OHOS::Ace
49 
50 namespace OHOS::Ace::Framework {
51 
52 namespace {
53 const std::vector<FontStyle> FONT_STYLES = { FontStyle::NORMAL, FontStyle::ITALIC };
54 const int32_t TWENTY_FOUR_HOUR_BASE = 24;
55 constexpr int32_t HOURS_WEST_LOWER_LIMIT = -14;
56 constexpr int32_t HOURS_WEST_UPPER_LIMIT = 12;
57 constexpr int32_t HOURS_WEST_GEOGRAPHICAL_LOWER_LIMIT = -12;
58 
HoursWestIsValid(int32_t hoursWest)59 bool HoursWestIsValid(int32_t hoursWest)
60 {
61     if (hoursWest < HOURS_WEST_LOWER_LIMIT || hoursWest > HOURS_WEST_UPPER_LIMIT) {
62         return false;
63     }
64     if (hoursWest < HOURS_WEST_GEOGRAPHICAL_LOWER_LIMIT) {
65         hoursWest += TWENTY_FOUR_HOUR_BASE;
66     }
67     return true;
68 }
69 } // namespace
70 
Create(const JSCallbackInfo & info)71 void JSTextClock::Create(const JSCallbackInfo& info)
72 {
73     auto controller = TextClockModel::GetInstance()->Create();
74     if (info.Length() < 1 || !info[0]->IsObject()) {
75         LOGD("TextClock Info is non-valid");
76         return;
77     }
78     JSRef<JSObject> optionsObject = JSRef<JSObject>::Cast(info[0]);
79     JSRef<JSVal> hourWestVal = optionsObject->GetProperty("timeZoneOffset");
80     if (hourWestVal->IsNumber() && HoursWestIsValid(hourWestVal->ToNumber<int32_t>())) {
81         TextClockModel::GetInstance()->SetHoursWest(hourWestVal->ToNumber<int32_t>());
82     } else {
83         TextClockModel::GetInstance()->SetHoursWest(INT_MAX);
84         LOGE("hourWest args is invalid");
85     }
86     auto controllerObj = optionsObject->GetProperty("controller");
87     if (!controllerObj->IsUndefined() && !controllerObj->IsNull()) {
88         auto* jsController = JSRef<JSObject>::Cast(controllerObj)->Unwrap<JSTextClockController>();
89         if (jsController != nullptr) {
90             if (controller) {
91                 jsController->SetController(controller);
92             } else {
93                 LOGE("TextClockController is nullptr");
94             }
95         }
96         return;
97     }
98     LOGE("controllerObj is nullptr or undefined");
99 }
100 
JSBind(BindingTarget globalObj)101 void JSTextClock::JSBind(BindingTarget globalObj)
102 {
103     JSClass<JSTextClock>::Declare("TextClock");
104     MethodOptions opt = MethodOptions::NONE;
105     JSClass<JSTextClock>::StaticMethod("create", &JSTextClock::Create, opt);
106     JSClass<JSTextClock>::StaticMethod("format", &JSTextClock::SetFormat, opt);
107     JSClass<JSTextClock>::StaticMethod("onDateChange", &JSTextClock::JsOnDateChange, opt);
108     JSClass<JSTextClock>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
109     JSClass<JSTextClock>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
110     JSClass<JSTextClock>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
111     JSClass<JSTextClock>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
112     JSClass<JSTextClock>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
113     JSClass<JSTextClock>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
114     JSClass<JSTextClock>::StaticMethod("fontColor", &JSText::SetTextColor, opt);
115     JSClass<JSTextClock>::StaticMethod("fontSize", &JSText::SetFontSize, opt);
116     JSClass<JSTextClock>::StaticMethod("fontStyle", &JSText::SetFontStyle, opt);
117     JSClass<JSTextClock>::StaticMethod("fontWeight", &JSText::SetFontWeight, opt);
118     JSClass<JSTextClock>::StaticMethod("fontFamily", &JSText::SetFontFamily, opt);
119     JSClass<JSTextClock>::Inherit<JSViewAbstract>();
120     JSClass<JSTextClock>::Bind<>(globalObj);
121 }
122 
SetFormat(const JSCallbackInfo & info)123 void JSTextClock::SetFormat(const JSCallbackInfo& info)
124 {
125     if (info.Length() < 1) {
126         LOGE("The arg is wrong, it is supposed to have atleast 1 argument.");
127         return;
128     }
129     std::string value;
130     if (!ParseJsString(info[0], value)) {
131         return;
132     }
133     std::regex pattern(
134         R"(^([Yy]*[_|\W\s]*[M]*[_|\W\s]*[d]*[_|\W\s]*[D]*[_|\W\s]*[Hh]*[_|\W\s]*[m]*[_|\W\s]*[s]*[_|\W\s]*[S]*)$)");
135     if (!std::regex_match(value, pattern)) {
136         LOGE("The arg is wrong, because of format matching error.");
137         TextClockModel::GetInstance()->SetFormat("hms");
138         return;
139     }
140     TextClockModel::GetInstance()->SetFormat(value);
141 }
142 
JsOnDateChange(const JSCallbackInfo & info)143 void JSTextClock::JsOnDateChange(const JSCallbackInfo& info)
144 {
145     if (!info[0]->IsFunction()) {
146         return;
147     }
148 
149     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
150     auto onChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& value) {
151         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
152         ACE_SCORING_EVENT("TextClock.onDateChange");
153         auto newJSVal = JSRef<JSVal>::Make(ToJSValue(value));
154         func->ExecuteJS(1, &newJSVal);
155     };
156     TextClockModel::GetInstance()->SetOnDateChange(std::move(onChange));
157 }
158 
JSBind(BindingTarget globalObj)159 void JSTextClockController::JSBind(BindingTarget globalObj)
160 {
161     JSClass<JSTextClockController>::Declare("TextClockController");
162     JSClass<JSTextClockController>::Method("start", &JSTextClockController::Start);
163     JSClass<JSTextClockController>::Method("stop", &JSTextClockController::Stop);
164     JSClass<JSTextClockController>::Bind(
165         globalObj, JSTextClockController::Constructor, JSTextClockController::Destructor);
166 }
167 
Constructor(const JSCallbackInfo & args)168 void JSTextClockController::Constructor(const JSCallbackInfo& args)
169 {
170     auto scroller = Referenced::MakeRefPtr<JSTextClockController>();
171     scroller->IncRefCount();
172     args.SetReturnValue(Referenced::RawPtr(scroller));
173 }
174 
Destructor(JSTextClockController * scroller)175 void JSTextClockController::Destructor(JSTextClockController* scroller)
176 {
177     if (scroller != nullptr) {
178         scroller->DecRefCount();
179     }
180 }
181 
Start()182 void JSTextClockController::Start()
183 {
184     if (controller_) {
185         controller_->Start();
186     }
187 }
188 
Stop()189 void JSTextClockController::Stop()
190 {
191     if (controller_) {
192         controller_->Stop();
193     }
194 }
195 } // namespace OHOS::Ace::Framework
196