• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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.h"
17 
18 #include <sstream>
19 #include <string>
20 #include <vector>
21 
22 #include "base/geometry/dimension.h"
23 #include "base/log/ace_scoring_log.h"
24 #include "base/log/ace_trace.h"
25 #include "base/utils/utils.h"
26 #include "bridge/common/utils/utils.h"
27 #include "bridge/declarative_frontend/engine/functions/js_click_function.h"
28 #include "bridge/declarative_frontend/engine/functions/js_drag_function.h"
29 #include "bridge/declarative_frontend/jsview/js_interactable_view.h"
30 #include "bridge/declarative_frontend/jsview/js_text.h"
31 #include "bridge/declarative_frontend/jsview/js_utils.h"
32 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
33 #include "bridge/declarative_frontend/jsview/models/text_model_impl.h"
34 #include "bridge/declarative_frontend/view_stack_processor.h"
35 #include "core/common/container.h"
36 #include "core/components/text/text_theme.h"
37 #include "core/components_ng/event/gesture_event_hub.h"
38 #include "core/components_ng/pattern/text/text_model.h"
39 #include "core/components_ng/pattern/text/text_model_ng.h"
40 #include "core/event/ace_event_handler.h"
41 #include "core/pipeline/pipeline_base.h"
42 
43 namespace OHOS::Ace {
44 
45 std::unique_ptr<TextModel> TextModel::instance_ = nullptr;
46 std::mutex TextModel::mutex_;
47 
GetInstance()48 TextModel* TextModel::GetInstance()
49 {
50     if (!instance_) {
51         std::lock_guard<std::mutex> lock(mutex_);
52         if (!instance_) {
53 #ifdef NG_BUILD
54             instance_.reset(new NG::TextModelNG());
55 #else
56             if (Container::IsCurrentUseNewPipeline()) {
57                 instance_.reset(new NG::TextModelNG());
58             } else {
59                 instance_.reset(new Framework::TextModelImpl());
60             }
61 #endif
62         }
63     }
64     return instance_.get();
65 }
66 
67 } // namespace OHOS::Ace
68 
69 namespace OHOS::Ace::Framework {
70 namespace {
71 
72 const std::vector<TextCase> TEXT_CASES = { TextCase::NORMAL, TextCase::LOWERCASE, TextCase::UPPERCASE };
73 const std::vector<TextOverflow> TEXT_OVERFLOWS = { TextOverflow::NONE, TextOverflow::CLIP, TextOverflow::ELLIPSIS,
74     TextOverflow::MARQUEE };
75 const std::vector<FontStyle> FONT_STYLES = { FontStyle::NORMAL, FontStyle::ITALIC };
76 const std::vector<TextAlign> TEXT_ALIGNS = { TextAlign::START, TextAlign::CENTER, TextAlign::END, TextAlign::JUSTIFY,
77     TextAlign::LEFT, TextAlign::RIGHT };
78 const std::vector<TextHeightAdaptivePolicy> HEIGHT_ADAPTIVE_POLICY = { TextHeightAdaptivePolicy::MAX_LINES_FIRST,
79     TextHeightAdaptivePolicy::MIN_FONT_SIZE_FIRST, TextHeightAdaptivePolicy::LAYOUT_CONSTRAINT_FIRST };
80 }; // namespace
81 
SetWidth(const JSCallbackInfo & info)82 void JSText::SetWidth(const JSCallbackInfo& info)
83 {
84     JSViewAbstract::JsWidth(info);
85     TextModel::GetInstance()->OnSetWidth();
86 }
87 
SetHeight(const JSCallbackInfo & info)88 void JSText::SetHeight(const JSCallbackInfo& info)
89 {
90     JSViewAbstract::JsHeight(info);
91     TextModel::GetInstance()->OnSetHeight();
92 }
93 
SetFont(const JSCallbackInfo & info)94 void JSText::SetFont(const JSCallbackInfo& info)
95 {
96     Font font;
97     GetFontInfo(info, font);
98     TextModel::GetInstance()->SetFont(font);
99 }
100 
GetFontInfo(const JSCallbackInfo & info,Font & font)101 void JSText::GetFontInfo(const JSCallbackInfo& info, Font& font)
102 {
103     auto tmpInfo = info[0];
104     if (!tmpInfo->IsObject()) {
105         return;
106     }
107     auto paramObject = JSRef<JSObject>::Cast(tmpInfo);
108     auto fontSize = paramObject->GetProperty("size");
109     CalcDimension size;
110     if (!JSContainerBase::ParseJsDimensionFp(fontSize, size) || fontSize->IsNull()) {
111         font.fontSize = std::nullopt;
112     } else {
113         if (fontSize->IsUndefined() || size.IsNegative() || size.Unit() == DimensionUnit::PERCENT) {
114             auto pipelineContext = PipelineContext::GetCurrentContext();
115             CHECK_NULL_VOID_NOLOG(pipelineContext);
116             auto theme = pipelineContext->GetTheme<TextTheme>();
117             CHECK_NULL_VOID_NOLOG(theme);
118             font.fontSize = theme->GetTextStyle().GetFontSize();
119         } else {
120             font.fontSize = size;
121         }
122     }
123     std::string weight;
124     auto fontWeight = paramObject->GetProperty("weight");
125     if (!fontWeight->IsNull()) {
126         if (fontWeight->IsNumber()) {
127             weight = std::to_string(fontWeight->ToNumber<int32_t>());
128         } else {
129             JSContainerBase::ParseJsString(fontWeight, weight);
130         }
131         font.fontWeight = ConvertStrToFontWeight(weight);
132     }
133     auto fontFamily = paramObject->GetProperty("family");
134     if (!fontFamily->IsNull()) {
135         std::vector<std::string> fontFamilies;
136         if (JSContainerBase::ParseJsFontFamilies(fontFamily, fontFamilies)) {
137             font.fontFamilies = fontFamilies;
138         }
139     }
140     auto style = paramObject->GetProperty("style");
141     if (!style->IsNull() || style->IsNumber()) {
142         font.fontStyle = static_cast<FontStyle>(style->ToNumber<int32_t>());
143     }
144 }
145 
SetFontSize(const JSCallbackInfo & info)146 void JSText::SetFontSize(const JSCallbackInfo& info)
147 {
148     if (info.Length() < 1) {
149         LOGI("The argv is wrong, it is supposed to have at least 1 argument");
150         return;
151     }
152     auto pipelineContext = PipelineBase::GetCurrentContext();
153     CHECK_NULL_VOID_NOLOG(pipelineContext);
154     auto theme = pipelineContext->GetTheme<TextTheme>();
155     CHECK_NULL_VOID_NOLOG(theme);
156     CalcDimension fontSize = theme->GetTextStyle().GetFontSize();
157     ParseJsDimensionFp(info[0], fontSize);
158     if (fontSize.IsNegative() || fontSize.Unit() == DimensionUnit::PERCENT) {
159         fontSize = theme->GetTextStyle().GetFontSize();
160     }
161     TextModel::GetInstance()->SetFontSize(fontSize);
162 }
163 
SetFontWeight(const std::string & value)164 void JSText::SetFontWeight(const std::string& value)
165 {
166     TextModel::GetInstance()->SetFontWeight(ConvertStrToFontWeight(value));
167 }
168 
SetTextColor(const JSCallbackInfo & info)169 void JSText::SetTextColor(const JSCallbackInfo& info)
170 {
171     if (info.Length() < 1) {
172         LOGI("The argv is wrong, it is supposed to have at least 1 argument");
173         return;
174     }
175     Color textColor;
176     if (!ParseJsColor(info[0], textColor)) {
177         auto pipelineContext = PipelineBase::GetCurrentContext();
178         CHECK_NULL_VOID_NOLOG(pipelineContext);
179         auto theme = pipelineContext->GetTheme<TextTheme>();
180         CHECK_NULL_VOID_NOLOG(theme);
181         textColor = theme->GetTextStyle().GetTextColor();
182     }
183     TextModel::GetInstance()->SetTextColor(textColor);
184 }
185 
SetTextShadow(const JSCallbackInfo & info)186 void JSText::SetTextShadow(const JSCallbackInfo& info)
187 {
188     if (info.Length() < 1) {
189         LOGW("The argv is wrong, it is supposed to have at least 1 argument");
190         return;
191     }
192     if (!info[0]->IsNumber() && !info[0]->IsObject()) {
193         LOGW("info[0] not is Object or Number");
194         return;
195     }
196     int32_t shadowStyle = 0;
197     if (ParseJsInteger<int32_t>(info[0], shadowStyle)) {
198         auto style = static_cast<ShadowStyle>(shadowStyle);
199         Shadow shadow = Shadow::CreateShadow(style);
200         TextModel::GetInstance()->SetTextShadow(shadow);
201         return;
202     }
203 
204     auto jsObject = JSRef<JSObject>::Cast(info[0]);
205     Shadow shadow;
206     double radius = 0.0;
207     if (ParseJsDouble(jsObject->GetProperty("radius"), radius)) {
208         if (LessNotEqual(radius, 0.0)) {
209             radius = 0.0;
210         }
211         shadow.SetBlurRadius(radius);
212         CalcDimension offsetX;
213         if (ParseJsDimensionVp(jsObject->GetProperty("offsetX"), offsetX)) {
214             shadow.SetOffsetX(offsetX.Value());
215         }
216         CalcDimension offsetY;
217         if (ParseJsDimensionVp(jsObject->GetProperty("offsetY"), offsetY)) {
218             shadow.SetOffsetY(offsetY.Value());
219         }
220         Color color;
221         if (ParseJsColor(jsObject->GetProperty("color"), color)) {
222             shadow.SetColor(color);
223         }
224     }
225     TextModel::GetInstance()->SetTextShadow(shadow);
226 }
227 
SetTextOverflow(const JSCallbackInfo & info)228 void JSText::SetTextOverflow(const JSCallbackInfo& info)
229 {
230     do {
231         auto tmpInfo = info[0];
232         if (!tmpInfo->IsObject()) {
233             break;
234         }
235         JSRef<JSObject> obj = JSRef<JSObject>::Cast(tmpInfo);
236         JSRef<JSVal> overflowValue = obj->GetProperty("overflow");
237         if (!overflowValue->IsNumber()) {
238             break;
239         }
240         auto overflow = overflowValue->ToNumber<int32_t>();
241         if (overflow < 0 || overflow >= static_cast<int32_t>(TEXT_OVERFLOWS.size())) {
242             LOGI("Text: textOverflow(%{public}d) illegal value", overflow);
243             break;
244         }
245         TextModel::GetInstance()->SetTextOverflow(TEXT_OVERFLOWS[overflow]);
246     } while (false);
247 
248     info.SetReturnValue(info.This());
249 }
250 
SetMaxLines(const JSCallbackInfo & info)251 void JSText::SetMaxLines(const JSCallbackInfo& info)
252 {
253     int32_t value = Infinity<uint32_t>();
254     if (info[0]->ToString() != "Infinity") {
255         ParseJsInt32(info[0], value);
256     }
257     TextModel::GetInstance()->SetMaxLines(value);
258 }
259 
SetTextIndent(const JSCallbackInfo & info)260 void JSText::SetTextIndent(const JSCallbackInfo& info)
261 {
262     if (info.Length() < 1) {
263         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
264         return;
265     }
266     CalcDimension value;
267     if (!ParseJsDimensionFp(info[0], value)) {
268         TextModel::GetInstance()->SetTextIndent(value);
269         return;
270     }
271     TextModel::GetInstance()->SetTextIndent(value);
272 }
273 
SetFontStyle(int32_t value)274 void JSText::SetFontStyle(int32_t value)
275 {
276     if (value < 0 || value >= static_cast<int32_t>(FONT_STYLES.size())) {
277         LOGI("Text fontStyle(%{public}d) illegal value", value);
278         return;
279     }
280     TextModel::GetInstance()->SetItalicFontStyle(FONT_STYLES[value]);
281 }
282 
SetTextAlign(int32_t value)283 void JSText::SetTextAlign(int32_t value)
284 {
285     if (value < 0 || value >= static_cast<int32_t>(TEXT_ALIGNS.size())) {
286         LOGI("Text: TextAlign(%d) expected positive number", value);
287         return;
288     }
289     TextModel::GetInstance()->SetTextAlign(TEXT_ALIGNS[value]);
290 }
291 
SetAlign(const JSCallbackInfo & info)292 void JSText::SetAlign(const JSCallbackInfo& info)
293 {
294     JSViewAbstract::JsAlign(info);
295     if (!info[0]->IsNumber()) {
296         return;
297     }
298     TextModel::GetInstance()->OnSetAlign();
299 }
300 
SetLineHeight(const JSCallbackInfo & info)301 void JSText::SetLineHeight(const JSCallbackInfo& info)
302 {
303     if (info.Length() < 1) {
304         LOGI("The argv is wrong, it is supposed to have at least 1 argument");
305         return;
306     }
307     CalcDimension value;
308     ParseJsDimensionFp(info[0], value);
309     if (value.IsNegative()) {
310         value.Reset();
311     }
312     TextModel::GetInstance()->SetLineHeight(value);
313 }
314 
SetFontFamily(const JSCallbackInfo & info)315 void JSText::SetFontFamily(const JSCallbackInfo& info)
316 {
317     if (info.Length() < 1) {
318         LOGI("The argv is wrong, it is supposed to have at least 1 argument");
319         return;
320     }
321     std::vector<std::string> fontFamilies;
322     if (!ParseJsFontFamilies(info[0], fontFamilies)) {
323         LOGI("Parse FontFamilies failed");
324         return;
325     }
326     TextModel::GetInstance()->SetFontFamily(fontFamilies);
327 }
328 
SetMinFontSize(const JSCallbackInfo & info)329 void JSText::SetMinFontSize(const JSCallbackInfo& info)
330 {
331     if (info.Length() < 1) {
332         LOGI("The argv is wrong, it is supposed to have at least 1 argument");
333         return;
334     }
335     CalcDimension fontSize;
336     ParseJsDimensionFp(info[0], fontSize);
337     TextModel::GetInstance()->SetAdaptMinFontSize(fontSize);
338 }
339 
SetMaxFontSize(const JSCallbackInfo & info)340 void JSText::SetMaxFontSize(const JSCallbackInfo& info)
341 {
342     if (info.Length() < 1) {
343         LOGI("The argv is wrong, it is supposed to have at least 1 argument");
344         return;
345     }
346     CalcDimension fontSize;
347     ParseJsDimensionFp(info[0], fontSize);
348     TextModel::GetInstance()->SetAdaptMaxFontSize(fontSize);
349 }
350 
SetLetterSpacing(const JSCallbackInfo & info)351 void JSText::SetLetterSpacing(const JSCallbackInfo& info)
352 {
353     if (info.Length() < 1) {
354         LOGI("The argv is wrong, it is supposed to have at least 1 argument");
355         return;
356     }
357     if (info[0]->IsString()) {
358         auto value = info[0]->ToString();
359         if (!value.empty() && value.back() == '%') {
360             auto pipelineContext = PipelineBase::GetCurrentContext();
361             CHECK_NULL_VOID_NOLOG(pipelineContext);
362             auto theme = pipelineContext->GetTheme<TextTheme>();
363             CHECK_NULL_VOID_NOLOG(theme);
364             CalcDimension defaultValue = theme->GetTextStyle().GetLetterSpacing();
365             TextModel::GetInstance()->SetLetterSpacing(defaultValue);
366             return;
367         }
368     }
369     CalcDimension value;
370     if (!ParseJsDimensionFp(info[0], value)) {
371         return;
372     }
373     TextModel::GetInstance()->SetLetterSpacing(value);
374 }
375 
SetTextCase(int32_t value)376 void JSText::SetTextCase(int32_t value)
377 {
378     if (value < 0 || value >= static_cast<int32_t>(TEXT_CASES.size())) {
379         LOGI("Text textCase(%{public}d) illegal value", value);
380         return;
381     }
382     TextModel::GetInstance()->SetTextCase(TEXT_CASES[value]);
383 }
384 
SetBaselineOffset(const JSCallbackInfo & info)385 void JSText::SetBaselineOffset(const JSCallbackInfo& info)
386 {
387     if (info.Length() < 1) {
388         LOGI("The argv is wrong, it is supposed to have at least 1 argument");
389         return;
390     }
391     CalcDimension value;
392     if (!ParseJsDimensionFp(info[0], value)) {
393         return;
394     }
395     TextModel::GetInstance()->SetBaselineOffset(value);
396 }
397 
SetDecoration(const JSCallbackInfo & info)398 void JSText::SetDecoration(const JSCallbackInfo& info)
399 {
400     do {
401         auto tmpInfo = info[0];
402         if (!tmpInfo->IsObject()) {
403             break;
404         }
405         JSRef<JSObject> obj = JSRef<JSObject>::Cast(tmpInfo);
406         JSRef<JSVal> typeValue = obj->GetProperty("type");
407         JSRef<JSVal> colorValue = obj->GetProperty("color");
408         auto pipelineContext = PipelineBase::GetCurrentContext();
409         CHECK_NULL_VOID_NOLOG(pipelineContext);
410         auto theme = pipelineContext->GetTheme<TextTheme>();
411         CHECK_NULL_VOID_NOLOG(theme);
412         TextDecoration textDecoration = theme->GetTextStyle().GetTextDecoration();
413         if (typeValue->IsNumber()) {
414             textDecoration = static_cast<TextDecoration>(typeValue->ToNumber<int32_t>());
415         }
416         Color result = theme->GetTextStyle().GetTextDecorationColor();
417         ParseJsColor(colorValue, result);
418         TextModel::GetInstance()->SetTextDecoration(textDecoration);
419         TextModel::GetInstance()->SetTextDecorationColor(result);
420     } while (false);
421     info.SetReturnValue(info.This());
422 }
423 
SetHeightAdaptivePolicy(int32_t value)424 void JSText::SetHeightAdaptivePolicy(int32_t value)
425 {
426     if (value < 0 || value >= static_cast<int32_t>(HEIGHT_ADAPTIVE_POLICY.size())) {
427         LOGW("Text: HeightAdaptivePolicy(%d) expected positive number", value);
428         return;
429     }
430     TextModel::GetInstance()->SetHeightAdaptivePolicy(HEIGHT_ADAPTIVE_POLICY[value]);
431 }
432 
JsOnClick(const JSCallbackInfo & info)433 void JSText::JsOnClick(const JSCallbackInfo& info)
434 {
435     if (Container::IsCurrentUseNewPipeline()) {
436         if (info[0]->IsUndefined() && IsDisableEventVersion()) {
437             LOGD("JsOnClick callback is undefined");
438             TextModel::GetInstance()->ClearOnClick();
439             return;
440         }
441         if (!info[0]->IsFunction()) {
442             LOGW("the info is not click function");
443             return;
444         }
445         auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
446         auto onClick = [execCtx = info.GetExecutionContext(), func = jsOnClickFunc](const BaseEventInfo* info) {
447             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
448             LOGD("About to call onclick method on js");
449             const auto* clickInfo = TypeInfoHelper::DynamicCast<GestureEvent>(info);
450             ACE_SCORING_EVENT("Text.onClick");
451             func->Execute(*clickInfo);
452         };
453         TextModel::GetInstance()->SetOnClick(std::move(onClick));
454     } else {
455 #ifndef NG_BUILD
456         if (info[0]->IsFunction()) {
457             auto inspector = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
458             auto impl = inspector ? inspector->GetInspectorFunctionImpl() : nullptr;
459             RefPtr<JsClickFunction> jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
460             auto onClickId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc), impl](
461                                  const BaseEventInfo* info) {
462                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
463                 LOGD("About to call onclick method on js");
464                 const auto* clickInfo = TypeInfoHelper::DynamicCast<ClickInfo>(info);
465                 auto newInfo = *clickInfo;
466                 if (impl) {
467                     impl->UpdateEventInfo(newInfo);
468                 }
469                 ACE_SCORING_EVENT("Text.onClick");
470                 func->Execute(newInfo);
471             };
472             TextModel::GetInstance()->SetOnClick(std::move(onClickId));
473         }
474 #endif
475     }
476 }
477 
JsRemoteMessage(const JSCallbackInfo & info)478 void JSText::JsRemoteMessage(const JSCallbackInfo& info)
479 {
480     JSInteractableView::JsCommonRemoteMessage(info);
481     auto callback = JSInteractableView::GetRemoteMessageEventCallback(info);
482     TextModel::GetInstance()->SetRemoteMessage(std::move(callback));
483 }
484 
Create(const JSCallbackInfo & info)485 void JSText::Create(const JSCallbackInfo& info)
486 {
487     std::string data;
488     if (info.Length() > 0) {
489         ParseJsString(info[0], data);
490     }
491 
492     TextModel::GetInstance()->Create(data);
493 }
494 
SetCopyOption(const JSCallbackInfo & info)495 void JSText::SetCopyOption(const JSCallbackInfo& info)
496 {
497     if (info.Length() == 0) {
498         return;
499     }
500     auto copyOptions = CopyOptions::None;
501     auto tmpInfo = info[0];
502     if (tmpInfo->IsNumber()) {
503         auto emunNumber = tmpInfo->ToNumber<int>();
504         copyOptions = static_cast<CopyOptions>(emunNumber);
505     }
506     TextModel::GetInstance()->SetCopyOption(copyOptions);
507 }
508 
JsOnDragStart(const JSCallbackInfo & info)509 void JSText::JsOnDragStart(const JSCallbackInfo& info)
510 {
511     CHECK_NULL_VOID(info[0]->IsFunction());
512     RefPtr<JsDragFunction> jsOnDragStartFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
513     auto onDragStart = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragStartFunc)](
514                            const RefPtr<DragEvent>& info, const std::string& extraParams) -> NG::DragDropBaseInfo {
515         NG::DragDropBaseInfo itemInfo;
516         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, itemInfo);
517 
518         auto ret = func->Execute(info, extraParams);
519         if (!ret->IsObject()) {
520             LOGI("builder param is not an object.");
521             return itemInfo;
522         }
523         auto node = ParseDragNode(ret);
524         if (node) {
525             LOGI("use custom builder param.");
526             itemInfo.node = node;
527             return itemInfo;
528         }
529 
530         auto builderObj = JSRef<JSObject>::Cast(ret);
531 #if defined(PIXEL_MAP_SUPPORTED)
532         auto pixmap = builderObj->GetProperty("pixelMap");
533         itemInfo.pixelMap = CreatePixelMapFromNapiValue(pixmap);
534 #endif
535         auto extraInfo = builderObj->GetProperty("extraInfo");
536         ParseJsString(extraInfo, itemInfo.extraInfo);
537         node = ParseDragNode(builderObj->GetProperty("builder"));
538         itemInfo.node = node;
539         return itemInfo;
540     };
541 
542     TextModel::GetInstance()->SetOnDragStart(std::move(onDragStart));
543 }
544 
JsOnDragEnter(const JSCallbackInfo & info)545 void JSText::JsOnDragEnter(const JSCallbackInfo& info)
546 {
547     CHECK_NULL_VOID(info[0]->IsFunction());
548     RefPtr<JsDragFunction> jsOnDragEnterFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
549     auto onDragEnterId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEnterFunc)](
550                              const RefPtr<DragEvent>& info, const std::string& extraParams) {
551         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
552         ACE_SCORING_EVENT("onDragEnter");
553         func->Execute(info, extraParams);
554     };
555     TextModel::GetInstance()->SetOnDragEnter(std::move(onDragEnterId));
556 }
557 
JsOnDragMove(const JSCallbackInfo & info)558 void JSText::JsOnDragMove(const JSCallbackInfo& info)
559 {
560     CHECK_NULL_VOID(info[0]->IsFunction());
561     RefPtr<JsDragFunction> jsOnDragMoveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
562     auto onDragMoveId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragMoveFunc)](
563                             const RefPtr<DragEvent>& info, const std::string& extraParams) {
564         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
565         ACE_SCORING_EVENT("onDragMove");
566         func->Execute(info, extraParams);
567     };
568     TextModel::GetInstance()->SetOnDragMove(std::move(onDragMoveId));
569 }
570 
JsOnDragLeave(const JSCallbackInfo & info)571 void JSText::JsOnDragLeave(const JSCallbackInfo& info)
572 {
573     CHECK_NULL_VOID(info[0]->IsFunction());
574     RefPtr<JsDragFunction> jsOnDragLeaveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
575     auto onDragLeaveId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragLeaveFunc)](
576                              const RefPtr<DragEvent>& info, const std::string& extraParams) {
577         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
578         ACE_SCORING_EVENT("onDragLeave");
579         func->Execute(info, extraParams);
580     };
581     TextModel::GetInstance()->SetOnDragLeave(std::move(onDragLeaveId));
582 }
583 
JsOnDrop(const JSCallbackInfo & info)584 void JSText::JsOnDrop(const JSCallbackInfo& info)
585 {
586     CHECK_NULL_VOID(info[0]->IsFunction());
587     RefPtr<JsDragFunction> jsOnDropFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
588     auto onDropId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDropFunc)](
589                         const RefPtr<DragEvent>& info, const std::string& extraParams) {
590         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
591         ACE_SCORING_EVENT("onDrop");
592         func->Execute(info, extraParams);
593     };
594     TextModel::GetInstance()->SetOnDrop(std::move(onDropId));
595 }
596 
JsFocusable(const JSCallbackInfo & info)597 void JSText::JsFocusable(const JSCallbackInfo& info)
598 {
599     auto tmpInfo = info[0];
600     if (!tmpInfo->IsBoolean()) {
601         LOGI("The info is wrong, it is supposed to be an boolean");
602         return;
603     }
604     JSInteractableView::SetFocusable(tmpInfo->ToBoolean());
605     JSInteractableView::SetFocusNode(false);
606 }
607 
JsDraggable(const JSCallbackInfo & info)608 void JSText::JsDraggable(const JSCallbackInfo& info)
609 {
610     auto tmpInfo = info[0];
611     if (!tmpInfo->IsBoolean()) {
612         LOGI("The info is wrong, it is supposed to be an boolean");
613         return;
614     }
615     TextModel::GetInstance()->SetDraggable(tmpInfo->ToBoolean());
616 }
617 
JsMenuOptionsExtension(const JSCallbackInfo & info)618 void JSText::JsMenuOptionsExtension(const JSCallbackInfo& info)
619 {
620     if (Container::IsCurrentUseNewPipeline()) {
621         auto tmpInfo = info[0];
622         if (tmpInfo->IsArray()) {
623             std::vector<NG::MenuOptionsParam> menuOptionsItems;
624             JSViewAbstract::ParseMenuOptions(info, JSRef<JSArray>::Cast(tmpInfo), menuOptionsItems);
625             TextModel::GetInstance()->SetMenuOptionItems(std::move(menuOptionsItems));
626         }
627     } else {
628         LOGI("only newPipeline supply");
629     }
630 }
631 
JSBind(BindingTarget globalObj)632 void JSText::JSBind(BindingTarget globalObj)
633 {
634     JSClass<JSText>::Declare("Text");
635     MethodOptions opt = MethodOptions::NONE;
636     JSClass<JSText>::StaticMethod("create", &JSText::Create, opt);
637     JSClass<JSText>::StaticMethod("width", &JSText::SetWidth);
638     JSClass<JSText>::StaticMethod("height", &JSText::SetHeight);
639     JSClass<JSText>::StaticMethod("font", &JSText::SetFont, opt);
640     JSClass<JSText>::StaticMethod("fontColor", &JSText::SetTextColor, opt);
641     JSClass<JSText>::StaticMethod("textShadow", &JSText::SetTextShadow, opt);
642     JSClass<JSText>::StaticMethod("fontSize", &JSText::SetFontSize, opt);
643     JSClass<JSText>::StaticMethod("fontWeight", &JSText::SetFontWeight, opt);
644     JSClass<JSText>::StaticMethod("maxLines", &JSText::SetMaxLines, opt);
645     JSClass<JSText>::StaticMethod("textIndent", &JSText::SetTextIndent);
646     JSClass<JSText>::StaticMethod("textOverflow", &JSText::SetTextOverflow, opt);
647     JSClass<JSText>::StaticMethod("fontStyle", &JSText::SetFontStyle, opt);
648     JSClass<JSText>::StaticMethod("align", &JSText::SetAlign, opt);
649     JSClass<JSText>::StaticMethod("textAlign", &JSText::SetTextAlign, opt);
650     JSClass<JSText>::StaticMethod("lineHeight", &JSText::SetLineHeight, opt);
651     JSClass<JSText>::StaticMethod("fontFamily", &JSText::SetFontFamily, opt);
652     JSClass<JSText>::StaticMethod("minFontSize", &JSText::SetMinFontSize, opt);
653     JSClass<JSText>::StaticMethod("maxFontSize", &JSText::SetMaxFontSize, opt);
654     JSClass<JSText>::StaticMethod("letterSpacing", &JSText::SetLetterSpacing, opt);
655     JSClass<JSText>::StaticMethod("textCase", &JSText::SetTextCase, opt);
656     JSClass<JSText>::StaticMethod("baselineOffset", &JSText::SetBaselineOffset, opt);
657     JSClass<JSText>::StaticMethod("decoration", &JSText::SetDecoration);
658     JSClass<JSText>::StaticMethod("heightAdaptivePolicy", &JSText::SetHeightAdaptivePolicy);
659     JSClass<JSText>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
660     JSClass<JSText>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
661     JSClass<JSText>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
662     JSClass<JSText>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
663     JSClass<JSText>::StaticMethod("remoteMessage", &JSText::JsRemoteMessage);
664     JSClass<JSText>::StaticMethod("copyOption", &JSText::SetCopyOption);
665     JSClass<JSText>::StaticMethod("onClick", &JSText::JsOnClick);
666     JSClass<JSText>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
667     JSClass<JSText>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
668     JSClass<JSText>::StaticMethod("onDragStart", &JSText::JsOnDragStart);
669     JSClass<JSText>::StaticMethod("onDragEnter", &JSText::JsOnDragEnter);
670     JSClass<JSText>::StaticMethod("onDragMove", &JSText::JsOnDragMove);
671     JSClass<JSText>::StaticMethod("onDragLeave", &JSText::JsOnDragLeave);
672     JSClass<JSText>::StaticMethod("onDrop", &JSText::JsOnDrop);
673     JSClass<JSText>::StaticMethod("focusable", &JSText::JsFocusable);
674     JSClass<JSText>::StaticMethod("draggable", &JSText::JsDraggable);
675     JSClass<JSText>::StaticMethod("textMenuOptions", &JSText::JsMenuOptionsExtension);
676     JSClass<JSText>::InheritAndBind<JSContainerBase>(globalObj);
677 }
678 
679 } // namespace OHOS::Ace::Framework
680