• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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/style_string/js_span_object.h"
17 
18 #include <numeric>
19 #include <string>
20 
21 #include "canvas_napi/js_canvas.h"
22 
23 #include "base/geometry/calc_dimension.h"
24 #include "base/geometry/dimension.h"
25 #include "base/log/ace_scoring_log.h"
26 #include "base/memory/ace_type.h"
27 #include "bridge/common/utils/engine_helper.h"
28 #include "bridge/declarative_frontend/engine/functions/js_click_function.h"
29 #include "bridge/declarative_frontend/engine/js_converter.h"
30 #include "bridge/declarative_frontend/engine/js_types.h"
31 #include "bridge/declarative_frontend/jsview/js_richeditor.h"
32 #include "bridge/declarative_frontend/jsview/js_utils.h"
33 #include "core/components/common/layout/constants.h"
34 #include "core/components/common/properties/text_style.h"
35 #include "core/components/text/text_theme.h"
36 #include "core/components_ng/pattern/text/span/span_object.h"
37 #include "core/components_ng/pattern/text/span/span_string.h"
38 #include "core/components_ng/render/paragraph.h"
39 #include "frameworks/bridge/common/utils/utils.h"
40 #include "frameworks/bridge/declarative_frontend/jsview/js_container_span.h"
41 #include "frameworks/bridge/declarative_frontend/jsview/js_image.h"
42 #include "frameworks/bridge/declarative_frontend/jsview/js_view_abstract.h"
43 
44 namespace OHOS::Ace::Framework {
45 namespace {
46 const std::vector<TextAlign> TEXT_ALIGNS = { TextAlign::START, TextAlign::CENTER, TextAlign::END, TextAlign::JUSTIFY };
47 const std::vector<TextOverflow> TEXT_OVERFLOWS = { TextOverflow::NONE, TextOverflow::CLIP, TextOverflow::ELLIPSIS,
48     TextOverflow::MARQUEE };
49 const int32_t WORD_BREAK_TYPES_DEFAULT = 2;
50 const std::vector<float> DEFAULT_COLORFILTER_MATRIX = {
51     1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
52     0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f
53 };
54 } // namespace
55 
ParseLengthMetrics(const JSRef<JSObject> & obj,bool withoutPercent=true)56 CalcDimension ParseLengthMetrics(const JSRef<JSObject>& obj, bool withoutPercent = true)
57 {
58     auto value = 0.0;
59     auto valueObj = obj->GetProperty("value");
60     if (!valueObj->IsNull() && valueObj->IsNumber()) {
61         value = valueObj->ToNumber<float>();
62     }
63     auto unit = DimensionUnit::VP;
64     auto unitObj = obj->GetProperty("unit");
65     if (!unitObj->IsNull() && unitObj->IsNumber()) {
66         unit = static_cast<DimensionUnit>(unitObj->ToNumber<int32_t>());
67     }
68     CalcDimension size = CalcDimension(value, unit);
69     if (withoutPercent && unit == DimensionUnit::PERCENT) {
70         size = CalcDimension(0, DimensionUnit::VP);
71     }
72     return size;
73 }
74 
JSBind(BindingTarget globalObj)75 void JSFontSpan::JSBind(BindingTarget globalObj)
76 {
77     JSClass<JSFontSpan>::Declare("TextStyle");
78     JSClass<JSFontSpan>::CustomProperty("fontColor", &JSFontSpan::GetFontColor, &JSFontSpan::SetFontColor);
79     JSClass<JSFontSpan>::CustomProperty("fontSize", &JSFontSpan::GetFontSize, &JSFontSpan::SetFontSize);
80     JSClass<JSFontSpan>::CustomProperty("fontStyle", &JSFontSpan::GetFontStyle, &JSFontSpan::SetFontStyle);
81     JSClass<JSFontSpan>::CustomProperty("fontWeight", &JSFontSpan::GetFontWeight, &JSFontSpan::SetFontWeight);
82     JSClass<JSFontSpan>::CustomProperty("fontFamily", &JSFontSpan::GetFontFamily, &JSFontSpan::SetFontFamily);
83     JSClass<JSFontSpan>::Bind(globalObj, JSFontSpan::Constructor, JSFontSpan::Destructor);
84 }
85 
Constructor(const JSCallbackInfo & args)86 void JSFontSpan::Constructor(const JSCallbackInfo& args)
87 {
88     auto fontSpan = Referenced::MakeRefPtr<JSFontSpan>();
89     fontSpan->IncRefCount();
90 
91     RefPtr<FontSpan> span;
92     if (args.Length() <= 0) {
93         Font font;
94         span = AceType::MakeRefPtr<FontSpan>(font);
95     } else {
96         if (!args[0]->IsObject()) {
97             return;
98         }
99         span = JSFontSpan::ParseJsFontSpan(JSRef<JSObject>::Cast(args[0]));
100     }
101     fontSpan->fontSpan_ = span;
102     args.SetReturnValue(Referenced::RawPtr(fontSpan));
103 }
104 
Destructor(JSFontSpan * fontSpan)105 void JSFontSpan::Destructor(JSFontSpan* fontSpan)
106 {
107     if (fontSpan != nullptr) {
108         fontSpan->DecRefCount();
109     }
110 }
111 
ParseJsFontSpan(const JSRef<JSObject> & obj)112 RefPtr<FontSpan> JSFontSpan::ParseJsFontSpan(const JSRef<JSObject>& obj)
113 {
114     Font font;
115     ParseJsFontColor(obj, font);
116     ParseJsFontSize(obj, font);
117     ParseJsFontWeight(obj, font);
118     ParseJsFontFamily(obj, font);
119     ParseJsFontStyle(obj, font);
120     return AceType::MakeRefPtr<FontSpan>(font);
121 }
122 
ParseJsFontColor(const JSRef<JSObject> & obj,Font & font)123 void JSFontSpan::ParseJsFontColor(const JSRef<JSObject>& obj, Font& font)
124 {
125     if (obj->HasProperty("fontColor")) {
126         JSRef<JSVal> colorObj = JSRef<JSVal>::Cast(obj->GetProperty("fontColor"));
127         Color color;
128         if (!colorObj->IsNull() && !JSViewAbstract::ParseJsColor(colorObj, color)) {
129             auto context = PipelineBase::GetCurrentContextSafely();
130             CHECK_NULL_VOID(context);
131             auto theme = context->GetTheme<TextTheme>();
132             CHECK_NULL_VOID(theme);
133             color = theme->GetTextStyle().GetTextColor();
134         }
135         font.fontColor = color;
136     }
137 }
138 
ParseJsFontSize(const JSRef<JSObject> & obj,Font & font)139 void JSFontSpan::ParseJsFontSize(const JSRef<JSObject>& obj, Font& font)
140 {
141     if (obj->HasProperty("fontSize")) {
142         auto context = PipelineBase::GetCurrentContextSafely();
143         CHECK_NULL_VOID(context);
144         auto theme = context->GetTheme<TextTheme>();
145         CHECK_NULL_VOID(theme);
146         auto fontSize = obj->GetProperty("fontSize");
147         CalcDimension size = theme->GetTextStyle().GetFontSize();
148         if (!fontSize->IsNull() && fontSize->IsObject()) {
149             auto sizeTmp = ParseLengthMetrics(fontSize, false);
150             if (sizeTmp.Value() >= 0 && sizeTmp.Unit() != DimensionUnit::PERCENT) {
151                 size = sizeTmp;
152             }
153         }
154         font.fontSize = size;
155     }
156 }
157 
ParseJsFontWeight(const JSRef<JSObject> & obj,Font & font)158 void JSFontSpan::ParseJsFontWeight(const JSRef<JSObject>& obj, Font& font)
159 {
160     if (obj->HasProperty("fontWeight")) {
161         auto fontWeight = obj->GetProperty("fontWeight");
162         std::string weight = "";
163         if (fontWeight->IsNumber()) {
164             weight = std::to_string(fontWeight->ToNumber<int32_t>());
165         } else {
166             JSViewAbstract::ParseJsString(fontWeight, weight);
167         }
168         if (weight != "") {
169             font.fontWeight = ConvertStrToFontWeight(weight);
170         } else {
171             auto context = PipelineBase::GetCurrentContextSafely();
172             CHECK_NULL_VOID(context);
173             auto theme = context->GetTheme<TextTheme>();
174             CHECK_NULL_VOID(theme);
175             font.fontWeight = theme->GetTextStyle().GetFontWeight();
176         }
177     }
178 }
179 
ParseJsFontFamily(const JSRef<JSObject> & obj,Font & font)180 void JSFontSpan::ParseJsFontFamily(const JSRef<JSObject>& obj, Font& font)
181 {
182     if (obj->HasProperty("fontFamily")) {
183         auto fontFamily = obj->GetProperty("fontFamily");
184         std::vector<std::string> fontFamilies;
185         if (JSViewAbstract::ParseJsFontFamilies(fontFamily, fontFamilies)) {
186             font.fontFamiliesNG = fontFamilies;
187         } else {
188             auto context = PipelineBase::GetCurrentContextSafely();
189             CHECK_NULL_VOID(context);
190             auto theme = context->GetTheme<TextTheme>();
191             CHECK_NULL_VOID(theme);
192             font.fontFamiliesNG = theme->GetTextStyle().GetFontFamilies();
193         }
194     }
195 }
196 
ParseJsFontStyle(const JSRef<JSObject> & obj,Font & font)197 void JSFontSpan::ParseJsFontStyle(const JSRef<JSObject>& obj, Font& font)
198 {
199     if (obj->HasProperty("fontStyle")) {
200         auto style = obj->GetProperty("fontStyle");
201         OHOS::Ace::FontStyle fontStyle = FontStyle::NORMAL;
202         if (!style->IsNull() && style->IsNumber()) {
203             auto value = style->ToNumber<int32_t>();
204             if (value >= 0 && value < static_cast<int32_t>(FontStyle::NONE)) {
205                 fontStyle = static_cast<FontStyle>(value);
206             }
207         }
208         font.fontStyle = fontStyle;
209     }
210 }
211 
GetFontColor(const JSCallbackInfo & info)212 void JSFontSpan::GetFontColor(const JSCallbackInfo& info)
213 {
214     CHECK_NULL_VOID(fontSpan_);
215     if (!fontSpan_->GetFont().fontColor.has_value()) {
216         return;
217     }
218     auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(fontSpan_->GetFont().fontColor.value().ColorToString())));
219     info.SetReturnValue(ret);
220 }
221 
SetFontColor(const JSCallbackInfo & info)222 void JSFontSpan::SetFontColor(const JSCallbackInfo& info) {}
223 
GetFontSize(const JSCallbackInfo & info)224 void JSFontSpan::GetFontSize(const JSCallbackInfo& info)
225 {
226     CHECK_NULL_VOID(fontSpan_);
227     if (!fontSpan_->GetFont().fontSize.has_value()) {
228         return;
229     }
230     auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(fontSpan_->GetFont().fontSize.value().ConvertToVp())));
231     info.SetReturnValue(ret);
232 }
233 
SetFontSize(const JSCallbackInfo & info)234 void JSFontSpan::SetFontSize(const JSCallbackInfo& info) {}
235 
GetFontStyle(const JSCallbackInfo & info)236 void JSFontSpan::GetFontStyle(const JSCallbackInfo& info)
237 {
238     CHECK_NULL_VOID(fontSpan_);
239     if (!fontSpan_->GetFont().fontStyle.has_value()) {
240         return;
241     }
242     auto ret = JSRef<JSVal>::Make(
243         JSVal(ToJSValue(std::to_string(static_cast<int32_t>(fontSpan_->GetFont().fontStyle.value())))));
244     info.SetReturnValue(ret);
245 }
246 
SetFontStyle(const JSCallbackInfo & info)247 void JSFontSpan::SetFontStyle(const JSCallbackInfo& info) {}
248 
GetFontWeight(const JSCallbackInfo & info)249 void JSFontSpan::GetFontWeight(const JSCallbackInfo& info)
250 {
251     CHECK_NULL_VOID(fontSpan_);
252     if (!fontSpan_->GetFont().fontWeight.has_value()) {
253         return;
254     }
255     auto ret = JSRef<JSVal>::Make(
256         JSVal(ToJSValue(std::to_string(static_cast<int32_t>(fontSpan_->GetFont().fontWeight.value())))));
257     info.SetReturnValue(ret);
258 }
259 
SetFontWeight(const JSCallbackInfo & info)260 void JSFontSpan::SetFontWeight(const JSCallbackInfo& info) {}
261 
GetFontFamily(const JSCallbackInfo & info)262 void JSFontSpan::GetFontFamily(const JSCallbackInfo& info)
263 {
264     CHECK_NULL_VOID(fontSpan_);
265     if (!fontSpan_->GetFont().fontFamiliesNG.has_value()) {
266         return;
267     }
268     auto fontFamilies = fontSpan_->GetFont().fontFamiliesNG.value();
269     auto retStr = std::accumulate(fontFamilies.begin(), fontFamilies.end(), std::string());
270     auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(retStr)));
271     info.SetReturnValue(ret);
272 }
273 
SetFontFamily(const JSCallbackInfo & info)274 void JSFontSpan::SetFontFamily(const JSCallbackInfo& info) {}
275 
GetFontSpan()276 const RefPtr<FontSpan>& JSFontSpan::GetFontSpan()
277 {
278     return fontSpan_;
279 }
280 
SetFontSpan(const RefPtr<FontSpan> & fontSpan)281 void JSFontSpan::SetFontSpan(const RefPtr<FontSpan>& fontSpan)
282 {
283     fontSpan_ = fontSpan;
284 }
285 
JSBind(BindingTarget globalObj)286 void JSDecorationSpan::JSBind(BindingTarget globalObj)
287 {
288     JSClass<JSDecorationSpan>::Declare("DecorationStyle");
289     JSClass<JSDecorationSpan>::CustomProperty(
290         "type", &JSDecorationSpan::GetTextDecorationType, &JSDecorationSpan::SetTextDecorationType);
291     JSClass<JSDecorationSpan>::CustomProperty(
292         "color", &JSDecorationSpan::GetTextDecorationColor, &JSDecorationSpan::SetTextDecorationColor);
293     JSClass<JSDecorationSpan>::CustomProperty(
294         "style", &JSDecorationSpan::GetTextDecorationStyle, &JSDecorationSpan::SetTextDecorationStyle);
295     JSClass<JSDecorationSpan>::Bind(globalObj, JSDecorationSpan::Constructor, JSDecorationSpan::Destructor);
296 }
297 
Constructor(const JSCallbackInfo & args)298 void JSDecorationSpan::Constructor(const JSCallbackInfo& args)
299 {
300     auto decorationSpan = Referenced::MakeRefPtr<JSDecorationSpan>();
301     decorationSpan->IncRefCount();
302 
303     RefPtr<DecorationSpan> span;
304     if (args.Length() <= 0 || !args[0]->IsObject()) {
305         span = AceType::MakeRefPtr<DecorationSpan>();
306     } else {
307         span = JSDecorationSpan::ParseJsDecorationSpan(JSRef<JSObject>::Cast(args[0]));
308     }
309     decorationSpan->decorationSpan_ = span;
310     args.SetReturnValue(Referenced::RawPtr(decorationSpan));
311 }
312 
Destructor(JSDecorationSpan * decorationSpan)313 void JSDecorationSpan::Destructor(JSDecorationSpan* decorationSpan)
314 {
315     if (decorationSpan != nullptr) {
316         decorationSpan->DecRefCount();
317     }
318 }
319 
ParseJsDecorationSpan(const JSRef<JSObject> & obj)320 RefPtr<DecorationSpan> JSDecorationSpan::ParseJsDecorationSpan(const JSRef<JSObject>& obj)
321 {
322     std::optional<Color> colorOption;
323     Color color;
324     JSRef<JSVal> colorObj = JSRef<JSVal>::Cast(obj->GetProperty("color"));
325     if (!colorObj->IsNull() && JSViewAbstract::ParseJsColor(colorObj, color)) {
326         colorOption = color;
327     }
328     std::optional<TextDecorationStyle> styleOption;
329     JSRef<JSVal> styleObj = JSRef<JSVal>::Cast(obj->GetProperty("style"));
330     if (!styleObj->IsNull() && styleObj->IsNumber()) {
331         styleOption = static_cast<TextDecorationStyle>(styleObj->ToNumber<int32_t>());
332     }
333     TextDecoration type = TextDecoration::NONE;
334     JSRef<JSVal> typeObj = JSRef<JSVal>::Cast(obj->GetProperty("type"));
335     if (!typeObj->IsNull() && typeObj->IsNumber()) {
336         type = static_cast<TextDecoration>(typeObj->ToNumber<int32_t>());
337     }
338     return AceType::MakeRefPtr<DecorationSpan>(type, colorOption, styleOption);
339 }
340 
GetTextDecorationType(const JSCallbackInfo & info)341 void JSDecorationSpan::GetTextDecorationType(const JSCallbackInfo& info)
342 {
343     CHECK_NULL_VOID(decorationSpan_);
344     auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(static_cast<int32_t>(decorationSpan_->GetTextDecorationType()))));
345     info.SetReturnValue(ret);
346 }
347 
SetTextDecorationType(const JSCallbackInfo & info)348 void JSDecorationSpan::SetTextDecorationType(const JSCallbackInfo& info) {}
349 
GetTextDecorationColor(const JSCallbackInfo & info)350 void JSDecorationSpan::GetTextDecorationColor(const JSCallbackInfo& info)
351 {
352     CHECK_NULL_VOID(decorationSpan_);
353     if (!decorationSpan_->GetColor().has_value()) {
354         return;
355     }
356     auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(decorationSpan_->GetColor()->ColorToString())));
357     info.SetReturnValue(ret);
358 }
359 
SetTextDecorationColor(const JSCallbackInfo & info)360 void JSDecorationSpan::SetTextDecorationColor(const JSCallbackInfo& info) {}
361 
GetTextDecorationStyle(const JSCallbackInfo & info)362 void JSDecorationSpan::GetTextDecorationStyle(const JSCallbackInfo& info)
363 {
364     CHECK_NULL_VOID(decorationSpan_);
365     if (!decorationSpan_->GetTextDecorationStyle().has_value()) {
366         return;
367     }
368     auto ret =
369         JSRef<JSVal>::Make(JSVal(ToJSValue(static_cast<int32_t>(decorationSpan_->GetTextDecorationStyle().value()))));
370     info.SetReturnValue(ret);
371 }
372 
SetTextDecorationStyle(const JSCallbackInfo & info)373 void JSDecorationSpan::SetTextDecorationStyle(const JSCallbackInfo& info) {}
374 
GetDecorationSpan()375 RefPtr<DecorationSpan>& JSDecorationSpan::GetDecorationSpan()
376 {
377     return decorationSpan_;
378 }
379 
SetDecorationSpan(const RefPtr<DecorationSpan> & decorationSpan)380 void JSDecorationSpan::SetDecorationSpan(const RefPtr<DecorationSpan>& decorationSpan)
381 {
382     decorationSpan_ = decorationSpan;
383 }
384 
JSBind(BindingTarget globalObj)385 void JSBaselineOffsetSpan::JSBind(BindingTarget globalObj)
386 {
387     JSClass<JSBaselineOffsetSpan>::Declare("BaselineOffsetStyle");
388     JSClass<JSBaselineOffsetSpan>::CustomProperty(
389         "baselineOffset", &JSBaselineOffsetSpan::GetBaselineOffset, &JSBaselineOffsetSpan::SetBaselineOffset);
390     JSClass<JSBaselineOffsetSpan>::Bind(globalObj, JSBaselineOffsetSpan::Constructor, JSBaselineOffsetSpan::Destructor);
391 }
392 
Constructor(const JSCallbackInfo & args)393 void JSBaselineOffsetSpan::Constructor(const JSCallbackInfo& args)
394 {
395     auto baselineOffsetSpan = Referenced::MakeRefPtr<JSBaselineOffsetSpan>();
396     baselineOffsetSpan->IncRefCount();
397     RefPtr<BaselineOffsetSpan> span;
398     if (args.Length() <= 0 || !args[0]->IsObject()) {
399         span = AceType::MakeRefPtr<BaselineOffsetSpan>();
400     } else {
401         span = JSBaselineOffsetSpan::ParseJSBaselineOffsetSpan(JSRef<JSObject>::Cast(args[0]));
402     }
403     baselineOffsetSpan->baselineOffsetSpan_ = span;
404     args.SetReturnValue(Referenced::RawPtr(baselineOffsetSpan));
405 }
406 
Destructor(JSBaselineOffsetSpan * baselineOffsetSpan)407 void JSBaselineOffsetSpan::Destructor(JSBaselineOffsetSpan* baselineOffsetSpan)
408 {
409     if (baselineOffsetSpan != nullptr) {
410         baselineOffsetSpan->DecRefCount();
411     }
412 }
413 
ParseJSBaselineOffsetSpan(const JSRef<JSObject> & obj)414 RefPtr<BaselineOffsetSpan> JSBaselineOffsetSpan::ParseJSBaselineOffsetSpan(const JSRef<JSObject>& obj)
415 {
416     if (obj->IsUndefined()) {
417         return AceType::MakeRefPtr<BaselineOffsetSpan>(CalcDimension(0, DimensionUnit::VP));
418     }
419     return AceType::MakeRefPtr<BaselineOffsetSpan>(ParseLengthMetrics(obj));
420 }
421 
GetBaselineOffset(const JSCallbackInfo & info)422 void JSBaselineOffsetSpan::GetBaselineOffset(const JSCallbackInfo& info)
423 {
424     CHECK_NULL_VOID(baselineOffsetSpan_);
425     auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(baselineOffsetSpan_->GetBaselineOffset().ConvertToVp())));
426     info.SetReturnValue(ret);
427 }
428 
SetBaselineOffset(const JSCallbackInfo & info)429 void JSBaselineOffsetSpan::SetBaselineOffset(const JSCallbackInfo& info) {}
430 
GetBaselineOffsetSpan()431 RefPtr<BaselineOffsetSpan>& JSBaselineOffsetSpan::GetBaselineOffsetSpan()
432 {
433     return baselineOffsetSpan_;
434 }
435 
SetBaselineOffsetSpan(const RefPtr<BaselineOffsetSpan> & baselineOffsetSpan)436 void JSBaselineOffsetSpan::SetBaselineOffsetSpan(const RefPtr<BaselineOffsetSpan>& baselineOffsetSpan)
437 {
438     baselineOffsetSpan_ = baselineOffsetSpan;
439 }
440 
JSBind(BindingTarget globalObj)441 void JSLetterSpacingSpan::JSBind(BindingTarget globalObj)
442 {
443     JSClass<JSLetterSpacingSpan>::Declare("LetterSpacingStyle");
444     JSClass<JSLetterSpacingSpan>::CustomProperty(
445         "letterSpacing", &JSLetterSpacingSpan::GetLetterSpacing, &JSLetterSpacingSpan::SetLetterSpacing);
446     JSClass<JSLetterSpacingSpan>::Bind(globalObj, JSLetterSpacingSpan::Constructor, JSLetterSpacingSpan::Destructor);
447 }
448 
Constructor(const JSCallbackInfo & args)449 void JSLetterSpacingSpan::Constructor(const JSCallbackInfo& args)
450 {
451     auto letterSpacingSpan = Referenced::MakeRefPtr<JSLetterSpacingSpan>();
452     letterSpacingSpan->IncRefCount();
453 
454     RefPtr<LetterSpacingSpan> span;
455     if (args.Length() <= 0 || !args[0]->IsObject()) {
456         span = AceType::MakeRefPtr<LetterSpacingSpan>();
457     } else {
458         span = JSLetterSpacingSpan::ParseJSLetterSpacingSpan(JSRef<JSObject>::Cast(args[0]));
459     }
460     letterSpacingSpan->letterSpacingSpan_ = span;
461     args.SetReturnValue(Referenced::RawPtr(letterSpacingSpan));
462 }
463 
Destructor(JSLetterSpacingSpan * letterSpacingSpan)464 void JSLetterSpacingSpan::Destructor(JSLetterSpacingSpan* letterSpacingSpan)
465 {
466     if (letterSpacingSpan != nullptr) {
467         letterSpacingSpan->DecRefCount();
468     }
469 }
470 
ParseJSLetterSpacingSpan(const JSRef<JSObject> & obj)471 RefPtr<LetterSpacingSpan> JSLetterSpacingSpan::ParseJSLetterSpacingSpan(const JSRef<JSObject>& obj)
472 {
473     if (obj->IsUndefined()) {
474         return AceType::MakeRefPtr<LetterSpacingSpan>(CalcDimension(0, DimensionUnit::VP));
475     }
476     return AceType::MakeRefPtr<LetterSpacingSpan>(ParseLengthMetrics(obj));
477 }
478 
GetLetterSpacing(const JSCallbackInfo & info)479 void JSLetterSpacingSpan::GetLetterSpacing(const JSCallbackInfo& info)
480 {
481     CHECK_NULL_VOID(letterSpacingSpan_);
482     auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(letterSpacingSpan_->GetLetterSpacing().ConvertToVp())));
483     info.SetReturnValue(ret);
484 }
485 
SetLetterSpacing(const JSCallbackInfo & info)486 void JSLetterSpacingSpan::SetLetterSpacing(const JSCallbackInfo& info) {}
487 
GetLetterSpacingSpan()488 RefPtr<LetterSpacingSpan>& JSLetterSpacingSpan::GetLetterSpacingSpan()
489 {
490     return letterSpacingSpan_;
491 }
492 
SetLetterSpacingSpan(const RefPtr<LetterSpacingSpan> & letterSpacingSpan)493 void JSLetterSpacingSpan::SetLetterSpacingSpan(const RefPtr<LetterSpacingSpan>& letterSpacingSpan)
494 {
495     letterSpacingSpan_ = letterSpacingSpan;
496 }
497 
Constructor(const JSCallbackInfo & args)498 void JSGestureSpan::Constructor(const JSCallbackInfo& args)
499 {
500     auto gestureSpan = Referenced::MakeRefPtr<JSGestureSpan>();
501     gestureSpan->IncRefCount();
502 
503     RefPtr<GestureSpan> span;
504     if (args.Length() <= 0) {
505         GestureStyle gestureInfo;
506         span = AceType::MakeRefPtr<GestureSpan>(gestureInfo);
507     } else {
508         span = JSGestureSpan::ParseJSGestureSpan(args);
509     }
510     gestureSpan->gestureSpan_ = span;
511     args.SetReturnValue(Referenced::RawPtr(gestureSpan));
512 }
513 
Destructor(JSGestureSpan * gestureSpan)514 void JSGestureSpan::Destructor(JSGestureSpan* gestureSpan)
515 {
516     if (gestureSpan != nullptr) {
517         gestureSpan->DecRefCount();
518     }
519 }
520 
JSBind(BindingTarget globalObj)521 void JSGestureSpan::JSBind(BindingTarget globalObj)
522 {
523     JSClass<JSGestureSpan>::Declare("NativeGestureStyle");
524     JSClass<JSGestureSpan>::Bind(globalObj, JSGestureSpan::Constructor, JSGestureSpan::Destructor);
525 }
526 
ParseJSGestureSpan(const JSCallbackInfo & args)527 RefPtr<GestureSpan> JSGestureSpan::ParseJSGestureSpan(const JSCallbackInfo& args)
528 {
529     GestureStyle gestureInfo;
530     if (args.Length() <= 0 || !args[0]->IsObject()) {
531         gestureInfo.onClick = std::nullopt;
532         gestureInfo.onLongPress = std::nullopt;
533         return AceType::MakeRefPtr<GestureSpan>(gestureInfo);
534     }
535     JSRef<JSObject> object = JSRef<JSObject>::Cast(args[0]);
536 
537     auto clickFunc = object->GetProperty("onClick");
538     if (!clickFunc->IsFunction() || clickFunc->IsUndefined()) {
539         gestureInfo.onClick = std::nullopt;
540     } else {
541         auto jsOnClickFunc = AceType::MakeRefPtr<JsWeakClickFunction>(JSRef<JSFunc>::Cast(clickFunc));
542         auto onClick = [execCtx = args.GetExecutionContext(), func = jsOnClickFunc](BaseEventInfo* info) {
543             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
544             auto* clickInfo = TypeInfoHelper::DynamicCast<GestureEvent>(info);
545             ACE_SCORING_EVENT("SpanString.onClick");
546             func->Execute(*clickInfo);
547         };
548         auto tmpClickFunc = [func = std::move(onClick)](GestureEvent& info) { func(&info); };
549         gestureInfo.onClick = std::move(tmpClickFunc);
550     }
551 
552     auto longPressFunc = object->GetProperty("onLongPress");
553     if (!longPressFunc->IsFunction() || longPressFunc->IsUndefined()) {
554         gestureInfo.onLongPress = std::nullopt;
555     } else {
556         auto jsOnLongPressFunc = AceType::MakeRefPtr<JsWeakClickFunction>(JSRef<JSFunc>::Cast(longPressFunc));
557         auto onLongPress = [execCtx = args.GetExecutionContext(), func = jsOnLongPressFunc](BaseEventInfo* info) {
558             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
559             auto* longPressInfo = TypeInfoHelper::DynamicCast<GestureEvent>(info);
560             ACE_SCORING_EVENT("SpanString.onLongPress");
561             func->Execute(*longPressInfo);
562         };
563         auto tmpLongPressFunc = [func = std::move(onLongPress)](GestureEvent& info) { func(&info); };
564         gestureInfo.onLongPress = std::move(tmpLongPressFunc);
565     }
566 
567     return AceType::MakeRefPtr<GestureSpan>(gestureInfo);
568 }
569 
GetGestureSpan()570 RefPtr<GestureSpan>& JSGestureSpan::GetGestureSpan()
571 {
572     return gestureSpan_;
573 }
574 
SetGestureSpan(const RefPtr<GestureSpan> & gestureSpan)575 void JSGestureSpan::SetGestureSpan(const RefPtr<GestureSpan>& gestureSpan)
576 {
577     gestureSpan_ = gestureSpan;
578 }
JSBind(BindingTarget globalObj)579 void JSTextShadowSpan::JSBind(BindingTarget globalObj)
580 {
581     JSClass<JSTextShadowSpan>::Declare("TextShadowStyle");
582     JSClass<JSTextShadowSpan>::CustomProperty(
583         "textShadow", &JSTextShadowSpan::GetTextShadow, &JSTextShadowSpan::SetTextShadow);
584     JSClass<JSTextShadowSpan>::Bind(globalObj, JSTextShadowSpan::Constructor, JSTextShadowSpan::Destructor);
585 }
586 
Constructor(const JSCallbackInfo & args)587 void JSTextShadowSpan::Constructor(const JSCallbackInfo& args)
588 {
589     auto textShadowSpan = Referenced::MakeRefPtr<JSTextShadowSpan>();
590     textShadowSpan->IncRefCount();
591 
592     RefPtr<TextShadowSpan> span;
593     if (args.Length() <= 0 || !args[0]->IsObject()) {
594         std::vector<Shadow> shadows;
595         span = AceType::MakeRefPtr<TextShadowSpan>(shadows);
596     } else {
597         span = JSTextShadowSpan::ParseJSTextShadowSpan(JSRef<JSObject>::Cast(args[0]));
598     }
599     textShadowSpan->textShadowSpan_ = span;
600     args.SetReturnValue(Referenced::RawPtr(textShadowSpan));
601 }
602 
Destructor(JSTextShadowSpan * textShadowSpan)603 void JSTextShadowSpan::Destructor(JSTextShadowSpan* textShadowSpan)
604 {
605     if (textShadowSpan != nullptr) {
606         textShadowSpan->DecRefCount();
607     }
608 }
609 
ParseJSTextShadowSpan(const JSRef<JSObject> & obj)610 RefPtr<TextShadowSpan> JSTextShadowSpan::ParseJSTextShadowSpan(const JSRef<JSObject>& obj)
611 {
612     std::vector<Shadow> shadows;
613     ParseTextShadowFromShadowObject(obj, shadows);
614     return AceType::MakeRefPtr<TextShadowSpan>(shadows);
615 }
616 
GetTextShadow(const JSCallbackInfo & info)617 void JSTextShadowSpan::GetTextShadow(const JSCallbackInfo& info)
618 {
619     CHECK_NULL_VOID(textShadowSpan_);
620     auto shadows = textShadowSpan_->GetTextShadow();
621 
622     JSRef<JSArray> result = JSRef<JSArray>::New();
623     uint32_t index = 0;
624     for (auto iterator = shadows.begin(); iterator != shadows.end(); ++iterator) {
625         auto shadow = *iterator;
626         JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
627         objectTemplate->SetInternalFieldCount(1);
628         JSRef<JSObject> shadowObj = objectTemplate->NewInstance();
629         shadowObj->SetProperty<double>("radius", shadow.GetBlurRadius());
630         shadowObj->SetProperty<double>("offsetX", shadow.GetOffset().GetX());
631         shadowObj->SetProperty<double>("offsetY", shadow.GetOffset().GetY());
632         shadowObj->SetProperty<std::string>("color", shadow.GetColor().ColorToString());
633         shadowObj->SetProperty<int32_t>("type", static_cast<int32_t>(shadow.GetShadowType()));
634         result->SetValueAt(index++, shadowObj);
635     }
636     info.SetReturnValue(result);
637 }
638 
SetTextShadow(const JSCallbackInfo & info)639 void JSTextShadowSpan::SetTextShadow(const JSCallbackInfo& info) {}
640 
GetTextShadowSpan()641 RefPtr<TextShadowSpan>& JSTextShadowSpan::GetTextShadowSpan()
642 {
643     return textShadowSpan_;
644 }
645 
SetTextShadowSpan(const RefPtr<TextShadowSpan> & textShadowSpan)646 void JSTextShadowSpan::SetTextShadowSpan(const RefPtr<TextShadowSpan>& textShadowSpan)
647 {
648     textShadowSpan_ = textShadowSpan;
649 }
650 
651 // JSImageAttachment
Constructor(const JSCallbackInfo & args)652 void JSImageAttachment::Constructor(const JSCallbackInfo& args)
653 {
654     auto imageAttachment = Referenced::MakeRefPtr<JSImageAttachment>();
655     imageAttachment->IncRefCount();
656 
657     RefPtr<ImageSpan> span;
658     if (args.Length() <= 0 || !args[0]->IsObject()) {
659         ImageSpanOptions imageOption;
660         span = AceType::MakeRefPtr<ImageSpan>(imageOption);
661     } else {
662         span = JSImageAttachment::ParseJsImageSpan(JSRef<JSObject>::Cast(args[0]));
663     }
664     imageAttachment->imageSpan_ = span;
665     args.SetReturnValue(Referenced::RawPtr(imageAttachment));
666 }
667 
Destructor(JSImageAttachment * imageSpan)668 void JSImageAttachment::Destructor(JSImageAttachment* imageSpan)
669 {
670     if (imageSpan != nullptr) {
671         imageSpan->DecRefCount();
672     }
673 }
674 
JSBind(BindingTarget globalObj)675 void JSImageAttachment::JSBind(BindingTarget globalObj)
676 {
677     JSClass<JSImageAttachment>::Declare("ImageAttachment");
678     JSClass<JSImageAttachment>::CustomProperty(
679         "value", &JSImageAttachment::GetImageSrc, &JSImageAttachment::SetImageSrc);
680     JSClass<JSImageAttachment>::CustomProperty(
681         "size", &JSImageAttachment::GetImageSize, &JSImageAttachment::SetImageSize);
682     JSClass<JSImageAttachment>::CustomProperty(
683         "verticalAlign", &JSImageAttachment::GetImageVerticalAlign, &JSImageAttachment::SetImageVerticalAlign);
684     JSClass<JSImageAttachment>::CustomProperty(
685         "objectFit", &JSImageAttachment::GetImageObjectFit, &JSImageAttachment::SetImageObjectFit);
686     JSClass<JSImageAttachment>::CustomProperty(
687         "layoutStyle", &JSImageAttachment::GetImageLayoutStyle, &JSImageAttachment::SetImageLayoutStyle);
688     JSClass<JSImageAttachment>::CustomProperty(
689         "colorFilter", &JSImageAttachment::GetImageColorFilter, &JSImageAttachment::SetImageColorFilter);
690     JSClass<JSImageAttachment>::Bind(globalObj, JSImageAttachment::Constructor, JSImageAttachment::Destructor);
691 }
692 
ParseJsImageSpan(const JSRef<JSObject> & obj)693 RefPtr<ImageSpan> JSImageAttachment::ParseJsImageSpan(const JSRef<JSObject>& obj)
694 {
695     auto imageOptions = JSImageAttachment::CreateImageOptions(obj);
696     auto imageAttribute = JSImageAttachment::ParseJsImageSpanAttribute(obj);
697     imageOptions.imageAttribute = imageAttribute;
698     auto imageSpan = MakeRefPtr<ImageSpan>(imageOptions);
699     return imageSpan;
700 }
701 
CreateImageOptions(const JSRef<JSObject> & obj)702 ImageSpanOptions JSImageAttachment::CreateImageOptions(const JSRef<JSObject>& obj)
703 {
704     ImageSpanOptions options;
705     auto container = Container::CurrentSafely();
706     CHECK_NULL_RETURN(container, options);
707     auto context = PipelineBase::GetCurrentContextSafely();
708     CHECK_NULL_RETURN(context, options);
709     bool isCard = context->IsFormRender() && !container->IsDynamicRender();
710 
711     std::string imageSrc;
712     std::string bundleName;
713     std::string moduleName;
714     int32_t resId = 0;
715     auto srcValid = obj->HasProperty("resourceValue");
716     auto imageValue = srcValid ? obj->GetProperty("resourceValue") : obj->GetProperty("value");
717     JSViewAbstract::ParseJsMediaWithBundleName(imageValue, imageSrc, bundleName, moduleName, resId);
718     if (isCard && imageValue->IsString()) {
719         SrcType srcType = ImageSourceInfo::ResolveURIType(imageSrc);
720         bool notSupport = (srcType == SrcType::NETWORK || srcType == SrcType::FILE || srcType == SrcType::DATA_ABILITY);
721         if (notSupport) {
722             imageSrc.clear();
723         }
724     }
725     options.image = imageSrc;
726     options.bundleName = bundleName;
727     options.moduleName = moduleName;
728     options.isUriPureNumber = (resId == -1);
729     if (!srcValid) {
730 #if defined(PIXEL_MAP_SUPPORTED)
731         if (!isCard) {
732             if (JSImage::IsDrawable(imageValue)) {
733                 options.imagePixelMap = GetDrawablePixmap(imageValue);
734             } else {
735                 options.imagePixelMap = CreatePixelMapFromNapiValue(imageValue);
736             }
737         }
738 #endif
739     }
740     return options;
741 }
742 
ParseJsImageSpanAttribute(const JSRef<JSObject> & obj)743 ImageSpanAttribute JSImageAttachment::ParseJsImageSpanAttribute(const JSRef<JSObject>& obj)
744 {
745     ImageSpanAttribute imageStyle;
746     ParseJsImageSpanSizeAttribute(obj, imageStyle);
747     JSRef<JSVal> verticalAlign = obj->GetProperty("verticalAlign");
748     if (!verticalAlign->IsNull()) {
749         auto align = static_cast<VerticalAlign>(verticalAlign->ToNumber<int32_t>());
750         if (align < VerticalAlign::TOP || align > VerticalAlign::NONE) {
751             align = VerticalAlign::BOTTOM;
752         }
753         imageStyle.verticalAlign = align;
754     }
755     JSRef<JSVal> objectFit = obj->GetProperty("objectFit");
756     if (!objectFit->IsNull() && objectFit->IsNumber()) {
757         auto fit = static_cast<ImageFit>(objectFit->ToNumber<int32_t>());
758         if (fit < ImageFit::FILL || fit > ImageFit::BOTTOM_END) {
759             fit = ImageFit::COVER;
760         }
761         imageStyle.objectFit = fit;
762     } else {
763         imageStyle.objectFit = ImageFit::COVER;
764     }
765     auto layoutStyleObj = obj->GetProperty("layoutStyle");
766     if (layoutStyleObj->IsObject()) {
767         auto layoutStyleObject = JSRef<JSObject>::Cast(layoutStyleObj);
768         if (!layoutStyleObject->IsUndefined()) {
769             auto marginAttr = layoutStyleObject->GetProperty("margin");
770             imageStyle.marginProp = JSRichEditor::ParseMarginAttr(marginAttr);
771             auto paddingAttr = layoutStyleObject->GetProperty("padding");
772             imageStyle.paddingProp = JSRichEditor::ParseMarginAttr(paddingAttr);
773             auto borderRadiusAttr = layoutStyleObject->GetProperty("borderRadius");
774             imageStyle.borderRadius = JSRichEditor::ParseBorderRadiusAttr(borderRadiusAttr);
775         }
776     }
777 
778     auto syncLoadObj = obj->GetProperty("syncLoad");
779     if (!syncLoadObj->IsNull() && syncLoadObj->IsBoolean()) {
780         imageStyle.syncLoad = syncLoadObj->ToBoolean();
781     }
782 
783     ParseJsImageSpanColorFilterAttribute(obj, imageStyle);
784     return imageStyle;
785 }
786 
ParseJsImageSpanColorFilterAttribute(const JSRef<JSObject> & obj,ImageSpanAttribute & imageStyle)787 void JSImageAttachment::ParseJsImageSpanColorFilterAttribute(const JSRef<JSObject>& obj, ImageSpanAttribute& imageStyle)
788 {
789     auto colorFilterObj = obj->GetProperty("colorFilter");
790     if (colorFilterObj->IsNull()) {
791         return;
792     }
793     if (!colorFilterObj->IsArray() && !colorFilterObj->IsObject()) {
794         SetImageSpanColorFilterAttribute(imageStyle, DEFAULT_COLORFILTER_MATRIX);
795         return;
796     }
797     if (colorFilterObj->IsObject() && !colorFilterObj->IsArray()) {
798         auto drawingColorFilter = CreateDrawingColorFilter(colorFilterObj);
799         if (drawingColorFilter) {
800             imageStyle.colorFilterMatrix = std::nullopt;
801             imageStyle.drawingColorFilter = drawingColorFilter;
802             return;
803         }
804         JSColorFilter* colorFilter;
805         if (!colorFilterObj->IsUndefined() && !colorFilterObj->IsNull()) {
806             colorFilter = JSRef<JSObject>::Cast(colorFilterObj)->Unwrap<JSColorFilter>();
807         } else {
808             SetImageSpanColorFilterAttribute(imageStyle, DEFAULT_COLORFILTER_MATRIX);
809             return;
810         }
811         if (colorFilter && colorFilter->GetColorFilterMatrix().size() == COLOR_FILTER_MATRIX_SIZE) {
812             SetImageSpanColorFilterAttribute(imageStyle, colorFilter->GetColorFilterMatrix());
813             return;
814         }
815         SetImageSpanColorFilterAttribute(imageStyle, DEFAULT_COLORFILTER_MATRIX);
816         return;
817     }
818     JSRef<JSArray> array = JSRef<JSArray>::Cast(colorFilterObj);
819     if (array->Length() != COLOR_FILTER_MATRIX_SIZE) {
820         SetImageSpanColorFilterAttribute(imageStyle, DEFAULT_COLORFILTER_MATRIX);
821         return;
822     }
823     std::vector<float> colorfilter;
824     for (size_t i = 0; i < array->Length(); i++) {
825         JSRef<JSVal> value = array->GetValueAt(i);
826         if (!value->IsNumber()) {
827             SetImageSpanColorFilterAttribute(imageStyle, DEFAULT_COLORFILTER_MATRIX);
828             return;
829         }
830         colorfilter.emplace_back(value->ToNumber<float>());
831     }
832     SetImageSpanColorFilterAttribute(imageStyle, colorfilter);
833 }
834 
SetImageSpanColorFilterAttribute(ImageSpanAttribute & imageStyle,const std::vector<float> & matrix)835 void JSImageAttachment::SetImageSpanColorFilterAttribute(ImageSpanAttribute& imageStyle,
836     const std::vector<float>& matrix)
837 {
838     imageStyle.colorFilterMatrix = matrix;
839     imageStyle.drawingColorFilter = std::nullopt;
840 }
841 
ParseJsImageSpanSizeAttribute(const JSRef<JSObject> & obj,ImageSpanAttribute & imageStyle)842 void JSImageAttachment::ParseJsImageSpanSizeAttribute(const JSRef<JSObject>& obj, ImageSpanAttribute& imageStyle)
843 {
844     auto sizeObj = obj->GetProperty("size");
845     if (sizeObj->IsObject()) {
846         ImageSpanSize imageSize;
847         auto size = JSRef<JSObject>::Cast(sizeObj);
848         JSRef<JSVal> width = size->GetProperty("width");
849         CalcDimension imageSpanWidth;
850         if (!width->IsNull() && JSContainerBase::ParseJsDimensionVpNG(width, imageSpanWidth, false) &&
851             GreatNotEqual(imageSpanWidth.Value(), 0.0)) {
852             imageSize.width = imageSpanWidth;
853         }
854         JSRef<JSVal> height = size->GetProperty("height");
855         CalcDimension imageSpanHeight;
856         if (!height->IsNull() && JSContainerBase::ParseJsDimensionVpNG(height, imageSpanHeight, false) &&
857             GreatNotEqual(imageSpanHeight.Value(), 0.0)) {
858             imageSize.height = imageSpanHeight;
859         }
860         imageStyle.size = imageSize;
861     }
862 }
863 
GetImageSrc(const JSCallbackInfo & info)864 void JSImageAttachment::GetImageSrc(const JSCallbackInfo& info)
865 {
866     CHECK_NULL_VOID(imageSpan_);
867     auto imageOptions = imageSpan_->GetImageSpanOptions();
868     JSRef<JSVal> ret;
869     if (imageOptions.image.has_value()) {
870         ret = JSRef<JSVal>::Make(ToJSValue(imageOptions.image.value()));
871     }
872     if (imageOptions.imagePixelMap.has_value()) {
873 #ifdef PIXEL_MAP_SUPPORTED
874         ret = ConvertPixmap(imageOptions.imagePixelMap.value());
875 #endif
876     }
877     info.SetReturnValue(ret);
878 }
879 
GetImageSize(const JSCallbackInfo & info)880 void JSImageAttachment::GetImageSize(const JSCallbackInfo& info)
881 {
882     CHECK_NULL_VOID(imageSpan_);
883     auto imageAttr = imageSpan_->GetImageAttribute();
884     if (!imageAttr.has_value() || !imageAttr->size.has_value()) {
885         return;
886     }
887     auto imageSize = JSRef<JSObject>::New();
888     auto size = imageAttr->size;
889     if (size->width.has_value()) {
890         imageSize->SetProperty<float>("width", size->width->ConvertToVp());
891     } else {
892         imageSize->SetProperty<float>("width", 0.0);
893     }
894 
895     if (size->height.has_value()) {
896         imageSize->SetProperty<float>("height", size->height->ConvertToVp());
897     } else {
898         imageSize->SetProperty<float>("height", 0.0);
899     }
900     info.SetReturnValue(imageSize);
901 }
902 
GetImageVerticalAlign(const JSCallbackInfo & info)903 void JSImageAttachment::GetImageVerticalAlign(const JSCallbackInfo& info)
904 {
905     CHECK_NULL_VOID(imageSpan_);
906     auto imageAttr = imageSpan_->GetImageAttribute();
907     if (!imageAttr.has_value() || !imageAttr->verticalAlign.has_value()) {
908         return;
909     }
910     info.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(static_cast<int32_t>(imageAttr->verticalAlign.value()))));
911 }
912 
GetImageObjectFit(const JSCallbackInfo & info)913 void JSImageAttachment::GetImageObjectFit(const JSCallbackInfo& info)
914 {
915     CHECK_NULL_VOID(imageSpan_);
916     auto imageAttr = imageSpan_->GetImageAttribute();
917     if (!imageAttr.has_value() || !imageAttr->objectFit.has_value()) {
918         return;
919     }
920     info.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(static_cast<int32_t>(imageAttr->objectFit.value()))));
921 }
922 
CreateEdge(const NG::PaddingPropertyT<NG::CalcLength> & edge)923 JSRef<JSObject> JSImageAttachment::CreateEdge(const NG::PaddingPropertyT<NG::CalcLength>& edge)
924 {
925     auto obj = JSRef<JSObject>::New();
926     if (edge.top.has_value()) {
927         obj->SetProperty("top", edge.top->GetDimension().ConvertToVp());
928     }
929     if (edge.bottom.has_value()) {
930         obj->SetProperty("bottom", edge.bottom->GetDimension().ConvertToVp());
931     }
932     if (edge.left.has_value()) {
933         obj->SetProperty("left", edge.left->GetDimension().ConvertToVp());
934     }
935     if (edge.right.has_value()) {
936         obj->SetProperty("right", edge.right->GetDimension().ConvertToVp());
937     }
938     return obj;
939 }
940 
CreateBorderRadius(const NG::BorderRadiusProperty & borderRadius)941 JSRef<JSObject> JSImageAttachment::CreateBorderRadius(const NG::BorderRadiusProperty& borderRadius)
942 {
943     auto jsBorderRadius = JSRef<JSObject>::New();
944     if (borderRadius.radiusTopLeft.has_value()) {
945         jsBorderRadius->SetProperty("topLeft", borderRadius.radiusTopLeft->ConvertToVp());
946     }
947     if (borderRadius.radiusTopRight.has_value()) {
948         jsBorderRadius->SetProperty("topRight", borderRadius.radiusTopRight->ConvertToVp());
949     }
950     if (borderRadius.radiusBottomLeft.has_value()) {
951         jsBorderRadius->SetProperty("bottomLeft", borderRadius.radiusBottomLeft->ConvertToVp());
952     }
953     if (borderRadius.radiusBottomRight.has_value()) {
954         jsBorderRadius->SetProperty("bottomRight", borderRadius.radiusBottomRight->ConvertToVp());
955     }
956     return jsBorderRadius;
957 }
958 
GetImageLayoutStyle(const JSCallbackInfo & info)959 void JSImageAttachment::GetImageLayoutStyle(const JSCallbackInfo& info)
960 {
961     CHECK_NULL_VOID(imageSpan_);
962     auto imageAttr = imageSpan_->GetImageAttribute();
963     if (!imageAttr.has_value()) {
964         return;
965     }
966     auto layoutStyle = JSRef<JSObject>::New();
967     if (imageAttr->marginProp.has_value()) {
968         layoutStyle->SetPropertyObject("margin", CreateEdge(imageAttr->marginProp.value()));
969     }
970     if (imageAttr->paddingProp.has_value()) {
971         layoutStyle->SetPropertyObject("padding", CreateEdge(imageAttr->paddingProp.value()));
972     }
973     if (imageAttr->borderRadius.has_value()) {
974         layoutStyle->SetPropertyObject("borderRadius", CreateBorderRadius(imageAttr->borderRadius.value()));
975     }
976     info.SetReturnValue(layoutStyle);
977 }
978 
GetImageColorFilter(const JSCallbackInfo & info)979 void JSImageAttachment::GetImageColorFilter(const JSCallbackInfo& info)
980 {
981     CHECK_NULL_VOID(imageSpan_);
982     auto imageAttr = imageSpan_->GetImageAttribute();
983     if (!imageAttr.has_value()) {
984         return;
985     }
986     if (imageAttr->colorFilterMatrix.has_value()) {
987         JSRef<JSArray> colorFilterArr = JSRef<JSArray>::New();
988         uint32_t othersIdx = 0;
989         for (auto filterFloat : imageAttr->colorFilterMatrix.value()) {
990             colorFilterArr->SetValueAt(othersIdx++, JSRef<JSVal>::Make(ToJSValue(filterFloat)));
991         }
992         info.SetReturnValue(colorFilterArr);
993         return;
994     }
995     if (imageAttr->drawingColorFilter.has_value()) {
996         auto engine = EngineHelper::GetCurrentEngine();
997         CHECK_NULL_VOID(engine);
998         NativeEngine* nativeEngine = engine->GetNativeEngine();
999         CHECK_NULL_VOID(nativeEngine);
1000         auto jsColorFilter = imageAttr->drawingColorFilter.value()->GetDrawingColorFilterNapiValue(nativeEngine);
1001         CHECK_NULL_VOID(jsColorFilter);
1002         auto colorFilterJsVal = JsConverter::ConvertNapiValueToJsVal(jsColorFilter);
1003         CHECK_NULL_VOID(colorFilterJsVal->IsObject());
1004         info.SetReturnValue(JSRef<JSObject>::Cast(colorFilterJsVal));
1005     }
1006 }
1007 
GetImageSpan()1008 const RefPtr<ImageSpan>& JSImageAttachment::GetImageSpan()
1009 {
1010     return imageSpan_;
1011 }
1012 
SetImageSpan(const RefPtr<ImageSpan> & imageSpan)1013 void JSImageAttachment::SetImageSpan(const RefPtr<ImageSpan>& imageSpan)
1014 {
1015     imageSpan_ = imageSpan;
1016 }
1017 
GetImageOptions() const1018 const ImageSpanOptions& JSImageAttachment::GetImageOptions() const
1019 {
1020     return imageSpan_->GetImageSpanOptions();
1021 }
1022 
1023 // JSNativeCustomSpan
Constructor(const JSCallbackInfo & args)1024 void JSNativeCustomSpan::Constructor(const JSCallbackInfo& args)
1025 {
1026     auto customSpan = Referenced::MakeRefPtr<JSNativeCustomSpan>();
1027     customSpan->IncRefCount();
1028     args.SetReturnValue(Referenced::RawPtr(customSpan));
1029 }
1030 
Destructor(JSNativeCustomSpan * customSpan)1031 void JSNativeCustomSpan::Destructor(JSNativeCustomSpan* customSpan)
1032 {
1033     if (customSpan != nullptr) {
1034         customSpan->DecRefCount();
1035     }
1036 }
1037 
Invalidate(const JSCallbackInfo & info)1038 void JSNativeCustomSpan::Invalidate(const JSCallbackInfo& info)
1039 {
1040     for (const auto& styledStringWeakPtr : spanStringBaseSet_) {
1041         auto styledString = AceType::DynamicCast<SpanString>(styledStringWeakPtr.Upgrade());
1042         if (!styledString) {
1043             continue;
1044         }
1045         styledString->MarkDirtyFrameNode();
1046     }
1047 }
1048 
JSBind(BindingTarget globalObj)1049 void JSNativeCustomSpan::JSBind(BindingTarget globalObj)
1050 {
1051     JSClass<JSNativeCustomSpan>::Declare("NativeCustomSpan");
1052     JSClass<JSNativeCustomSpan>::CustomMethod("invalidate", &JSNativeCustomSpan::Invalidate);
1053     JSClass<JSNativeCustomSpan>::Bind(globalObj, JSNativeCustomSpan::Constructor, JSNativeCustomSpan::Destructor);
1054 }
1055 
AddStyledString(const WeakPtr<SpanStringBase> & spanString)1056 void JSNativeCustomSpan::AddStyledString(const WeakPtr<SpanStringBase>& spanString)
1057 {
1058     spanStringBaseSet_.insert(spanString);
1059 }
1060 
RemoveStyledString(const WeakPtr<SpanStringBase> & spanString)1061 void JSNativeCustomSpan::RemoveStyledString(const WeakPtr<SpanStringBase>& spanString)
1062 {
1063     spanStringBaseSet_.erase(spanString);
1064 }
1065 
1066 // JSCustomSpan
AddStyledString(const WeakPtr<SpanStringBase> & spanString)1067 void JSCustomSpan::AddStyledString(const WeakPtr<SpanStringBase>& spanString)
1068 {
1069     CHECK_NULL_VOID(customSpan_);
1070     customSpan_->AddStyledString(spanString);
1071 }
1072 
RemoveStyledString(const WeakPtr<SpanStringBase> & spanString)1073 void JSCustomSpan::RemoveStyledString(const WeakPtr<SpanStringBase>& spanString)
1074 {
1075     CHECK_NULL_VOID(customSpan_);
1076     customSpan_->RemoveStyledString(spanString);
1077 }
1078 
JSCustomSpan(JSRef<JSObject> customSpanObj,const JSCallbackInfo & args)1079 JSCustomSpan::JSCustomSpan(JSRef<JSObject> customSpanObj, const JSCallbackInfo& args) : customSpanObj_(customSpanObj)
1080 {
1081     auto obj = JSRef<JSObject>::Cast(customSpanObj);
1082     if (obj->IsUndefined()) {
1083         return;
1084     }
1085     JSRef<JSVal> onMeasure = obj->GetProperty("onMeasure");
1086     if (onMeasure->IsFunction()) {
1087         auto jsDrawFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(obj), JSRef<JSFunc>::Cast(onMeasure));
1088         auto onMeasureFunc = JSCustomSpan::ParseOnMeasureFunc(jsDrawFunc, args.GetExecutionContext());
1089         CustomSpan::SetOnMeasure(onMeasureFunc);
1090     }
1091     JSRef<JSVal> onDraw = obj->GetProperty("onDraw");
1092     if (onDraw->IsFunction()) {
1093         auto jsDrawFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(obj), JSRef<JSFunc>::Cast(onDraw));
1094         auto onDrawFunc = JSCustomSpan::ParseOnDrawFunc(jsDrawFunc, args.GetExecutionContext());
1095         CustomSpan::SetOnDraw(onDrawFunc);
1096     }
1097     auto type = customSpanObj->Unwrap<AceType>();
1098     CHECK_NULL_VOID(type);
1099     auto* nativeCustomSpan = AceType::DynamicCast<JSNativeCustomSpan>(type);
1100     customSpan_ = nativeCustomSpan;
1101 }
1102 
JSCustomSpan(JSRef<JSObject> customSpanObj,std::optional<std::function<CustomSpanMetrics (CustomSpanMeasureInfo)>> onMeasure,std::optional<std::function<void (NG::DrawingContext &,CustomSpanOptions)>> onDraw,int32_t start,int32_t end)1103 JSCustomSpan::JSCustomSpan(JSRef<JSObject> customSpanObj,
1104     std::optional<std::function<CustomSpanMetrics(CustomSpanMeasureInfo)>> onMeasure,
1105     std::optional<std::function<void(NG::DrawingContext&, CustomSpanOptions)>> onDraw, int32_t start, int32_t end)
1106     : CustomSpan(onMeasure, onDraw, start, end), customSpanObj_(customSpanObj)
1107 {
1108     auto type = customSpanObj->Unwrap<AceType>();
1109     CHECK_NULL_VOID(type);
1110     auto* nativeCustomSpan = AceType::DynamicCast<JSNativeCustomSpan>(type);
1111     customSpan_ = nativeCustomSpan;
1112 }
1113 
SetJsCustomSpanObject(const JSRef<JSObject> & customSpanObj)1114 void JSCustomSpan::SetJsCustomSpanObject(const JSRef<JSObject>& customSpanObj)
1115 {
1116     customSpanObj_ = customSpanObj;
1117 }
1118 
GetJsCustomSpanObject()1119 JSRef<JSObject>& JSCustomSpan::GetJsCustomSpanObject()
1120 {
1121     return customSpanObj_;
1122 }
GetSubSpan(int32_t start,int32_t end)1123 RefPtr<SpanBase> JSCustomSpan::GetSubSpan(int32_t start, int32_t end)
1124 {
1125     if (end - start > 1) {
1126         return nullptr;
1127     }
1128     RefPtr<SpanBase> spanBase = MakeRefPtr<JSCustomSpan>(customSpanObj_, GetOnMeasure(), GetOnDraw(), start, end);
1129     return spanBase;
1130 }
1131 
IsAttributesEqual(const RefPtr<SpanBase> & other) const1132 bool JSCustomSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
1133 {
1134     auto customSpan = DynamicCast<JSCustomSpan>(other);
1135     if (!customSpan) {
1136         return false;
1137     }
1138     return (customSpan->customSpanObj_)
1139         ->GetLocalHandle()
1140         ->IsStrictEquals(customSpanObj_->GetEcmaVM(), customSpanObj_->GetLocalHandle());
1141 }
1142 
ParseOnMeasureFunc(const RefPtr<JsFunction> & jsDraw,const JSExecutionContext & execCtx)1143 std::function<CustomSpanMetrics(CustomSpanMeasureInfo)> JSCustomSpan::ParseOnMeasureFunc(
1144     const RefPtr<JsFunction>& jsDraw, const JSExecutionContext& execCtx)
1145 {
1146     std::function<CustomSpanMetrics(CustomSpanMeasureInfo)> drawCallback =
1147         [func = std::move(jsDraw), execCtx](CustomSpanMeasureInfo customSpanMeasureInfo) -> CustomSpanMetrics {
1148         JAVASCRIPT_EXECUTION_SCOPE(execCtx);
1149         JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
1150         objectTemplate->SetInternalFieldCount(1);
1151         JSRef<JSObject> contextObj = objectTemplate->NewInstance();
1152         contextObj->SetProperty<float>("fontSize", customSpanMeasureInfo.fontSize);
1153         auto jsVal = JSRef<JSVal>::Cast(contextObj);
1154         auto obj = func->ExecuteJS(1, &jsVal);
1155         if (obj->IsObject()) {
1156             JSRef<JSObject> result = JSRef<JSObject>::Cast(obj);
1157             float width = 0;
1158             if (result->HasProperty("width")) {
1159                 auto widthObj = result->GetProperty("width");
1160                 width = widthObj->ToNumber<float>();
1161                 if (LessNotEqual(width, 0.0)) {
1162                     width = 0;
1163                 }
1164             }
1165             std::optional<float> heightOpt;
1166             if (result->HasProperty("height")) {
1167                 auto heightObj = result->GetProperty("height");
1168                 auto height = heightObj->ToNumber<float>();
1169                 if (GreatOrEqual(height, 0.0)) {
1170                     heightOpt = height;
1171                 }
1172             }
1173             return { width, heightOpt };
1174         }
1175         return { 0, 0 };
1176     };
1177     return drawCallback;
1178 }
1179 
ParseOnDrawFunc(const RefPtr<JsFunction> & jsDraw,const JSExecutionContext & execCtx)1180 std::function<void(NG::DrawingContext&, CustomSpanOptions)> JSCustomSpan::ParseOnDrawFunc(
1181     const RefPtr<JsFunction>& jsDraw, const JSExecutionContext& execCtx)
1182 {
1183     std::function<void(NG::DrawingContext&, CustomSpanOptions)> drawCallback =
1184         [func = std::move(jsDraw), execCtx](NG::DrawingContext& context, CustomSpanOptions customSpanOptions) -> void {
1185         JAVASCRIPT_EXECUTION_SCOPE(execCtx);
1186 
1187         JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
1188         objectTemplate->SetInternalFieldCount(1);
1189         JSRef<JSObject> contextObj = objectTemplate->NewInstance();
1190         JSRef<JSObject> sizeObj = objectTemplate->NewInstance();
1191         sizeObj->SetProperty<float>("height", PipelineBase::Px2VpWithCurrentDensity(context.height));
1192         sizeObj->SetProperty<float>("width", PipelineBase::Px2VpWithCurrentDensity(context.width));
1193         contextObj->SetPropertyObject("size", sizeObj);
1194 
1195         JSRef<JSObject> sizeInPxObj = objectTemplate->NewInstance();
1196         sizeInPxObj->SetProperty<float>("height", context.height);
1197         sizeInPxObj->SetProperty<float>("width", context.width);
1198         contextObj->SetPropertyObject("sizeInPixel", sizeInPxObj);
1199 
1200         auto engine = EngineHelper::GetCurrentEngine();
1201         CHECK_NULL_VOID(engine);
1202         NativeEngine* nativeEngine = engine->GetNativeEngine();
1203         napi_env env = reinterpret_cast<napi_env>(nativeEngine);
1204         ScopeRAII scope(env);
1205         auto jsCanvas = OHOS::Rosen::Drawing::JsCanvas::CreateJsCanvas(env, &context.canvas);
1206         OHOS::Rosen::Drawing::JsCanvas* unwrapCanvas = nullptr;
1207         napi_unwrap(env, jsCanvas, reinterpret_cast<void**>(&unwrapCanvas));
1208         if (unwrapCanvas) {
1209             unwrapCanvas->SaveCanvas();
1210             unwrapCanvas->ClipCanvas(context.width, context.height);
1211         }
1212         JsiRef<JsiValue> jsCanvasVal = JsConverter::ConvertNapiValueToJsVal(jsCanvas);
1213         contextObj->SetPropertyObject("canvas", jsCanvasVal);
1214 
1215         auto jsVal = JSRef<JSVal>::Cast(contextObj);
1216         panda::Local<JsiValue> value = jsVal.Get().GetLocalHandle();
1217         JSValueWrapper valueWrapper = value;
1218         napi_value nativeValue = nativeEngine->ValueToNapiValue(valueWrapper);
1219 
1220         napi_wrap(env, nativeValue, &context.canvas, [](napi_env, void*, void*) {}, nullptr, nullptr);
1221         JSRef<JSObject> customSpanOptionsObj = objectTemplate->NewInstance();
1222         customSpanOptionsObj->SetProperty<float>("x", customSpanOptions.x);
1223         customSpanOptionsObj->SetProperty<float>("lineTop", customSpanOptions.lineTop);
1224         customSpanOptionsObj->SetProperty<float>("lineBottom", customSpanOptions.lineBottom);
1225         customSpanOptionsObj->SetProperty<float>("baseline", customSpanOptions.baseline);
1226         auto customSpanOptionsVal = JSRef<JSVal>::Cast(customSpanOptionsObj);
1227         JSRef<JSVal> params[] = { jsVal, customSpanOptionsVal };
1228         func->ExecuteJS(2, params);
1229         if (unwrapCanvas) {
1230             unwrapCanvas->RestoreCanvas();
1231             unwrapCanvas->ResetCanvas();
1232         }
1233     };
1234     return drawCallback;
1235 }
1236 
JSBind(BindingTarget globalObj)1237 void JSLineHeightSpan::JSBind(BindingTarget globalObj)
1238 {
1239     JSClass<JSLineHeightSpan>::Declare("LineHeightStyle");
1240     JSClass<JSLineHeightSpan>::CustomProperty(
1241         "lineHeight", &JSLineHeightSpan::GetLineHeight, &JSLineHeightSpan::SetLineHeight);
1242     JSClass<JSLineHeightSpan>::Bind(globalObj, JSLineHeightSpan::Constructor, JSLineHeightSpan::Destructor);
1243 }
1244 
Constructor(const JSCallbackInfo & args)1245 void JSLineHeightSpan::Constructor(const JSCallbackInfo& args)
1246 {
1247     auto lineHeightSpan = Referenced::MakeRefPtr<JSLineHeightSpan>();
1248     lineHeightSpan->IncRefCount();
1249 
1250     RefPtr<LineHeightSpan> span;
1251     if (args.Length() <= 0 || !args[0]->IsObject()) {
1252         span = AceType::MakeRefPtr<LineHeightSpan>();
1253     } else {
1254         span = JSLineHeightSpan::ParseJSLineHeightSpan(JSRef<JSObject>::Cast(args[0]));
1255     }
1256     lineHeightSpan->lineHeightSpan_ = span;
1257     args.SetReturnValue(Referenced::RawPtr(lineHeightSpan));
1258 }
1259 
Destructor(JSLineHeightSpan * lineHeightSpan)1260 void JSLineHeightSpan::Destructor(JSLineHeightSpan* lineHeightSpan)
1261 {
1262     if (lineHeightSpan != nullptr) {
1263         lineHeightSpan->DecRefCount();
1264     }
1265 }
1266 
ParseJSLineHeightSpan(const JSRef<JSObject> & obj)1267 RefPtr<LineHeightSpan> JSLineHeightSpan::ParseJSLineHeightSpan(const JSRef<JSObject>& obj)
1268 {
1269     if (obj->IsUndefined()) {
1270         return AceType::MakeRefPtr<LineHeightSpan>(CalcDimension(0, DimensionUnit::VP));
1271     }
1272     return AceType::MakeRefPtr<LineHeightSpan>(ParseLengthMetrics(obj));
1273 }
1274 
GetLineHeight(const JSCallbackInfo & info)1275 void JSLineHeightSpan::GetLineHeight(const JSCallbackInfo& info)
1276 {
1277     CHECK_NULL_VOID(lineHeightSpan_);
1278     auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(lineHeightSpan_->GetLineHeight().ConvertToVp())));
1279     info.SetReturnValue(ret);
1280 }
1281 
SetLineHeight(const JSCallbackInfo & info)1282 void JSLineHeightSpan::SetLineHeight(const JSCallbackInfo& info) {}
1283 
GetLineHeightSpan()1284 RefPtr<LineHeightSpan>& JSLineHeightSpan::GetLineHeightSpan()
1285 {
1286     return lineHeightSpan_;
1287 }
1288 
SetLineHeightSpan(const RefPtr<LineHeightSpan> & lineHeightSpan)1289 void JSLineHeightSpan::SetLineHeightSpan(const RefPtr<LineHeightSpan>& lineHeightSpan)
1290 {
1291     lineHeightSpan_ = lineHeightSpan;
1292 }
1293 
JSBind(BindingTarget globalObj)1294 void JSParagraphStyleSpan::JSBind(BindingTarget globalObj)
1295 {
1296     JSClass<JSParagraphStyleSpan>::Declare("ParagraphStyle");
1297     JSClass<JSParagraphStyleSpan>::CustomProperty(
1298         "textAlign", &JSParagraphStyleSpan::GetTextAlign, &JSParagraphStyleSpan::SetTextAlign);
1299     JSClass<JSParagraphStyleSpan>::CustomProperty(
1300         "textIndent", &JSParagraphStyleSpan::GetTextIndent, &JSParagraphStyleSpan::SetTextIndent);
1301     JSClass<JSParagraphStyleSpan>::CustomProperty(
1302         "maxLines", &JSParagraphStyleSpan::GetMaxLines, &JSParagraphStyleSpan::SetMaxLines);
1303     JSClass<JSParagraphStyleSpan>::CustomProperty(
1304         "overflow", &JSParagraphStyleSpan::GetOverflow, &JSParagraphStyleSpan::SetOverflow);
1305     JSClass<JSParagraphStyleSpan>::CustomProperty(
1306         "wordBreak", &JSParagraphStyleSpan::GetWordBreak, &JSParagraphStyleSpan::SetWordBreak);
1307     JSClass<JSParagraphStyleSpan>::CustomProperty(
1308         "leadingMargin", &JSParagraphStyleSpan::GetLeadingMargin, &JSParagraphStyleSpan::SetLeadingMargin);
1309     JSClass<JSParagraphStyleSpan>::CustomProperty(
1310         "paragraphSpacing", &JSParagraphStyleSpan::GetParagraphSpacing, &JSParagraphStyleSpan::SetParagraphSpacing);
1311     JSClass<JSParagraphStyleSpan>::Bind(globalObj, JSParagraphStyleSpan::Constructor, JSParagraphStyleSpan::Destructor);
1312 }
1313 
Constructor(const JSCallbackInfo & args)1314 void JSParagraphStyleSpan::Constructor(const JSCallbackInfo& args)
1315 {
1316     auto paragraphSpan = Referenced::MakeRefPtr<JSParagraphStyleSpan>();
1317     paragraphSpan->IncRefCount();
1318 
1319     RefPtr<ParagraphStyleSpan> span;
1320     if (args.Length() <= 0 || !args[0]->IsObject()) {
1321         SpanParagraphStyle paragraphStyle;
1322         span = AceType::MakeRefPtr<ParagraphStyleSpan>(paragraphStyle);
1323     } else {
1324         span = JSParagraphStyleSpan::ParseJsParagraphStyleSpan(JSRef<JSObject>::Cast(args[0]));
1325     }
1326     paragraphSpan->paragraphStyleSpan_ = span;
1327     args.SetReturnValue(Referenced::RawPtr(paragraphSpan));
1328 }
1329 
Destructor(JSParagraphStyleSpan * paragragrahSpan)1330 void JSParagraphStyleSpan::Destructor(JSParagraphStyleSpan* paragragrahSpan)
1331 {
1332     if (paragragrahSpan != nullptr) {
1333         paragragrahSpan->DecRefCount();
1334     }
1335 }
1336 
ParseJsParagraphStyleSpan(const JSRef<JSObject> & obj)1337 RefPtr<ParagraphStyleSpan> JSParagraphStyleSpan::ParseJsParagraphStyleSpan(const JSRef<JSObject>& obj)
1338 {
1339     SpanParagraphStyle paragraphStyle;
1340     ParseJsTextAlign(obj, paragraphStyle);
1341     ParseJsTextIndent(obj, paragraphStyle);
1342     ParseJsMaxLines(obj, paragraphStyle);
1343     ParseJsTextOverflow(obj, paragraphStyle);
1344     ParseJsWordBreak(obj, paragraphStyle);
1345     ParseJsLeadingMargin(obj, paragraphStyle);
1346     ParseParagraphSpacing(obj, paragraphStyle);
1347     return AceType::MakeRefPtr<ParagraphStyleSpan>(paragraphStyle);
1348 }
1349 
ParseJsTextAlign(const JSRef<JSObject> & obj,SpanParagraphStyle & paragraphStyle)1350 void JSParagraphStyleSpan::ParseJsTextAlign(const JSRef<JSObject>& obj, SpanParagraphStyle& paragraphStyle)
1351 {
1352     if (!obj->HasProperty("textAlign")) {
1353         return;
1354     }
1355     auto textAlignObj = obj->GetProperty("textAlign");
1356     int32_t value = 0;
1357     if (!textAlignObj->IsNull() && textAlignObj->IsNumber()) {
1358         value = textAlignObj->ToNumber<int32_t>();
1359     }
1360     if (value < 0 || value >= static_cast<int32_t>(TEXT_ALIGNS.size())) {
1361         value = 0;
1362     }
1363     paragraphStyle.align = TEXT_ALIGNS[value];
1364 }
1365 
ParseJsTextIndent(const JSRef<JSObject> & obj,SpanParagraphStyle & paragraphStyle)1366 void JSParagraphStyleSpan::ParseJsTextIndent(const JSRef<JSObject>& obj, SpanParagraphStyle& paragraphStyle)
1367 {
1368     if (!obj->HasProperty("textIndent")) {
1369         return;
1370     }
1371     auto textIndent = obj->GetProperty("textIndent");
1372     CalcDimension size;
1373     if (!textIndent->IsNull() && textIndent->IsObject()) {
1374         auto textIndentObj = JSRef<JSObject>::Cast(textIndent);
1375         auto value = 0.0;
1376         auto textIndentVal = textIndentObj->GetProperty("value");
1377         if (!textIndentVal->IsNull() && textIndentVal->IsNumber()) {
1378             value = textIndentVal->ToNumber<float>();
1379         }
1380         auto unit = DimensionUnit::VP;
1381         auto textIndentUnit = textIndentObj->GetProperty("unit");
1382         if (!textIndentUnit->IsNull() && textIndentUnit->IsNumber()) {
1383             unit = static_cast<DimensionUnit>(textIndentUnit->ToNumber<int32_t>());
1384         }
1385         if (value >= 0 && unit != DimensionUnit::PERCENT) {
1386             size = CalcDimension(value, unit);
1387         }
1388     }
1389     paragraphStyle.textIndent = size;
1390 }
1391 
ParseJsMaxLines(const JSRef<JSObject> & obj,SpanParagraphStyle & paragraphStyle)1392 void JSParagraphStyleSpan::ParseJsMaxLines(const JSRef<JSObject>& obj, SpanParagraphStyle& paragraphStyle)
1393 {
1394     if (!obj->HasProperty("maxLines")) {
1395         return;
1396     }
1397     JSRef<JSVal> args = obj->GetProperty("maxLines");
1398     int32_t value = Infinity<int32_t>();
1399     if (args->ToString() != "Infinity") {
1400         JSContainerBase::ParseJsInt32(args, value);
1401     }
1402     if (!args->IsUndefined()) {
1403         paragraphStyle.maxLines = value;
1404     }
1405 }
1406 
ParseJsTextOverflow(const JSRef<JSObject> & obj,SpanParagraphStyle & paragraphStyle)1407 void JSParagraphStyleSpan::ParseJsTextOverflow(const JSRef<JSObject>& obj, SpanParagraphStyle& paragraphStyle)
1408 {
1409     if (!obj->HasProperty("overflow")) {
1410         return;
1411     }
1412     int32_t overflow = 0;
1413     JSRef<JSVal> overflowValue = obj->GetProperty("overflow");
1414     if (overflowValue->IsNumber()) {
1415         overflow = overflowValue->ToNumber<int32_t>();
1416     }
1417     if (overflowValue->IsUndefined() || overflow < 0 || overflow >= static_cast<int32_t>(TEXT_OVERFLOWS.size())) {
1418         overflow = 0;
1419     }
1420     paragraphStyle.textOverflow = TEXT_OVERFLOWS[overflow];
1421 }
ParseJsWordBreak(const JSRef<JSObject> & obj,SpanParagraphStyle & paragraphStyle)1422 void JSParagraphStyleSpan::ParseJsWordBreak(const JSRef<JSObject>& obj, SpanParagraphStyle& paragraphStyle)
1423 {
1424     if (!obj->HasProperty("wordBreak")) {
1425         return;
1426     }
1427     JSRef<JSVal> args = obj->GetProperty("wordBreak");
1428     int32_t index = WORD_BREAK_TYPES_DEFAULT;
1429     if (args->IsNumber()) {
1430         index = args->ToNumber<int32_t>();
1431     }
1432     if (index < 0 || index >= static_cast<int32_t>(WORD_BREAK_TYPES.size())) {
1433         index = 0;
1434     }
1435     paragraphStyle.wordBreak = WORD_BREAK_TYPES[index];
1436 }
1437 
IsPixelMap(const JSRef<JSVal> & jsValue)1438 bool JSParagraphStyleSpan::IsPixelMap(const JSRef<JSVal>& jsValue)
1439 {
1440     if (!jsValue->IsObject()) {
1441         return false;
1442     }
1443     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
1444     if (jsObj->IsUndefined()) {
1445         return false;
1446     }
1447     JSRef<JSVal> func = jsObj->GetProperty("readPixelsToBuffer");
1448     return (!func->IsNull() && func->IsFunction());
1449 }
1450 
ParseJsLeadingMargin(const JSRef<JSObject> & obj,SpanParagraphStyle & paragraphStyle)1451 void JSParagraphStyleSpan::ParseJsLeadingMargin(const JSRef<JSObject>& obj, SpanParagraphStyle& paragraphStyle)
1452 {
1453     if (!obj->HasProperty("leadingMargin")) {
1454         return;
1455     }
1456     auto margin = std::make_optional<NG::LeadingMargin>();
1457     auto leadingMargin = obj->GetProperty("leadingMargin");
1458     if (!leadingMargin->IsNull() && leadingMargin->IsObject()) {
1459         JSRef<JSObject> leadingMarginObject = JSRef<JSObject>::Cast(leadingMargin);
1460         // LeadingMarginPlaceholder
1461         if (leadingMarginObject->HasProperty("pixelMap")) {
1462             ParseLeadingMarginPixelMap(leadingMarginObject, margin, leadingMargin);
1463         } else { // LengthMetrics
1464             CalcDimension width;
1465             auto value = 0.0;
1466             auto widthVal = leadingMarginObject->GetProperty("value");
1467             if (!widthVal->IsNull() && widthVal->IsNumber()) {
1468                 value = widthVal->ToNumber<float>();
1469             }
1470             auto unit = DimensionUnit::VP;
1471             auto widthUnit = leadingMarginObject->GetProperty("unit");
1472             if (!widthUnit->IsNull() && widthUnit->IsNumber()) {
1473                 unit = static_cast<DimensionUnit>(widthUnit->ToNumber<int32_t>());
1474             }
1475             if (value >= 0 && unit != DimensionUnit::PERCENT) {
1476                 width = CalcDimension(value, unit);
1477             }
1478             margin->size = NG::LeadingMarginSize(width, Dimension(0.0, width.Unit()));
1479         }
1480     }
1481     paragraphStyle.leadingMargin = margin;
1482 }
1483 
ParseParagraphSpacing(const JSRef<JSObject> & obj,SpanParagraphStyle & paragraphStyle)1484 void JSParagraphStyleSpan::ParseParagraphSpacing(const JSRef<JSObject>& obj, SpanParagraphStyle& paragraphStyle)
1485 {
1486     if (!obj->HasProperty("paragraphSpacing")) {
1487         return;
1488     }
1489     auto paragraphSpacing = obj->GetProperty("paragraphSpacing");
1490     CalcDimension size;
1491     if (!paragraphSpacing->IsNull() && paragraphSpacing->IsObject()) {
1492         auto paragraphSpacingObj = JSRef<JSObject>::Cast(paragraphSpacing);
1493         auto value = 0.0;
1494         auto paragraphSpacingVal = paragraphSpacingObj->GetProperty("value");
1495         if (!paragraphSpacingVal->IsNull() && paragraphSpacingVal->IsNumber()) {
1496             value = paragraphSpacingVal->ToNumber<float>();
1497         }
1498         auto unit = DimensionUnit::VP;
1499         auto paragraphSpacingUnit = paragraphSpacingObj->GetProperty("unit");
1500         if (!paragraphSpacingUnit->IsNull() && paragraphSpacingUnit->IsNumber()) {
1501             unit = static_cast<DimensionUnit>(paragraphSpacingUnit->ToNumber<int32_t>());
1502         }
1503         if (value >= 0 && unit != DimensionUnit::PERCENT) {
1504             size = CalcDimension(value, unit);
1505         }
1506     }
1507     paragraphStyle.paragraphSpacing = size;
1508 }
1509 
ParseLeadingMarginPixelMap(const JSRef<JSObject> & leadingMarginObject,std::optional<NG::LeadingMargin> & margin,const JsiRef<JsiValue> & leadingMargin)1510 void JSParagraphStyleSpan::ParseLeadingMarginPixelMap(const JSRef<JSObject>& leadingMarginObject,
1511     std::optional<NG::LeadingMargin>& margin, const JsiRef<JsiValue>& leadingMargin)
1512 {
1513     JSRef<JSVal> placeholder = leadingMarginObject->GetProperty("pixelMap");
1514     if (IsPixelMap(placeholder)) {
1515 #if defined(PIXEL_MAP_SUPPORTED)
1516         auto pixelMap = CreatePixelMapFromNapiValue(placeholder);
1517         margin->pixmap = pixelMap;
1518 #endif
1519     }
1520     JSRef<JSVal> sizeVal = leadingMarginObject->GetProperty("size");
1521     if (!sizeVal->IsUndefined() && sizeVal->IsArray()) {
1522         auto rangeArray = JSRef<JSArray>::Cast(sizeVal);
1523         JSRef<JSVal> widthVal = rangeArray->GetValueAt(0);
1524         JSRef<JSVal> heightVal = rangeArray->GetValueAt(1);
1525         CalcDimension width;
1526         CalcDimension height;
1527         JSContainerBase::ParseJsDimensionVp(widthVal, width);
1528         JSContainerBase::ParseJsDimensionVp(heightVal, height);
1529         if (LessNotEqual(width.Value(), 0.0)) {
1530             width = Dimension(0.0, width.Unit());
1531         }
1532         if (LessNotEqual(height.Value(), 0.0)) {
1533             height = Dimension(0.0, height.Unit());
1534         }
1535         margin->size = NG::LeadingMarginSize(width, height);
1536     } else if (sizeVal->IsUndefined()) {
1537         std::string resWidthStr;
1538         if (JSContainerBase::ParseJsString(leadingMargin, resWidthStr)) {
1539             CalcDimension width;
1540             JSContainerBase::ParseJsDimensionVp(leadingMargin, width);
1541             margin->size = NG::LeadingMarginSize(width, Dimension(0.0, width.Unit()));
1542         }
1543     }
1544 }
1545 
GetTextAlign(const JSCallbackInfo & info)1546 void JSParagraphStyleSpan::GetTextAlign(const JSCallbackInfo& info)
1547 {
1548     CHECK_NULL_VOID(paragraphStyleSpan_);
1549     if (!paragraphStyleSpan_->GetParagraphStyle().align.has_value()) {
1550         return;
1551     }
1552     auto ret = JSRef<JSVal>::Make(
1553         JSVal(ToJSValue(static_cast<int32_t>(paragraphStyleSpan_->GetParagraphStyle().align.value()))));
1554     info.SetReturnValue(ret);
1555 }
1556 
SetTextAlign(const JSCallbackInfo & info)1557 void JSParagraphStyleSpan::SetTextAlign(const JSCallbackInfo& info) {}
1558 
GetTextIndent(const JSCallbackInfo & info)1559 void JSParagraphStyleSpan::GetTextIndent(const JSCallbackInfo& info)
1560 {
1561     CHECK_NULL_VOID(paragraphStyleSpan_);
1562     if (!paragraphStyleSpan_->GetParagraphStyle().textIndent.has_value()) {
1563         return;
1564     }
1565     auto ret =
1566         JSRef<JSVal>::Make(JSVal(ToJSValue(paragraphStyleSpan_->GetParagraphStyle().textIndent.value().ConvertToVp())));
1567     info.SetReturnValue(ret);
1568 }
1569 
SetTextIndent(const JSCallbackInfo & info)1570 void JSParagraphStyleSpan::SetTextIndent(const JSCallbackInfo& info) {}
1571 
GetMaxLines(const JSCallbackInfo & info)1572 void JSParagraphStyleSpan::GetMaxLines(const JSCallbackInfo& info)
1573 {
1574     CHECK_NULL_VOID(paragraphStyleSpan_);
1575     if (!paragraphStyleSpan_->GetParagraphStyle().maxLines.has_value()) {
1576         return;
1577     }
1578     auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(paragraphStyleSpan_->GetParagraphStyle().maxLines.value())));
1579     info.SetReturnValue(ret);
1580 }
SetMaxLines(const JSCallbackInfo & info)1581 void JSParagraphStyleSpan::SetMaxLines(const JSCallbackInfo& info) {}
1582 
GetOverflow(const JSCallbackInfo & info)1583 void JSParagraphStyleSpan::GetOverflow(const JSCallbackInfo& info)
1584 {
1585     CHECK_NULL_VOID(paragraphStyleSpan_);
1586     if (!paragraphStyleSpan_->GetParagraphStyle().textOverflow.has_value()) {
1587         return;
1588     }
1589     auto ret = JSRef<JSVal>::Make(
1590         JSVal(ToJSValue(static_cast<int32_t>(paragraphStyleSpan_->GetParagraphStyle().textOverflow.value()))));
1591     info.SetReturnValue(ret);
1592 }
SetOverflow(const JSCallbackInfo & info)1593 void JSParagraphStyleSpan::SetOverflow(const JSCallbackInfo& info) {}
1594 
GetWordBreak(const JSCallbackInfo & info)1595 void JSParagraphStyleSpan::GetWordBreak(const JSCallbackInfo& info)
1596 {
1597     CHECK_NULL_VOID(paragraphStyleSpan_);
1598     if (!paragraphStyleSpan_->GetParagraphStyle().wordBreak.has_value()) {
1599         return;
1600     }
1601     auto ret = JSRef<JSVal>::Make(
1602         JSVal(ToJSValue(static_cast<int32_t>(paragraphStyleSpan_->GetParagraphStyle().wordBreak.value()))));
1603     info.SetReturnValue(ret);
1604 }
SetWordBreak(const JSCallbackInfo & info)1605 void JSParagraphStyleSpan::SetWordBreak(const JSCallbackInfo& info) {}
1606 
GetLeadingMargin(const JSCallbackInfo & info)1607 void JSParagraphStyleSpan::GetLeadingMargin(const JSCallbackInfo& info)
1608 {
1609     CHECK_NULL_VOID(paragraphStyleSpan_);
1610     if (!paragraphStyleSpan_->GetParagraphStyle().leadingMargin.has_value()) {
1611         return;
1612     }
1613     auto leadingMargin = paragraphStyleSpan_->GetParagraphStyle().leadingMargin.value();
1614     JSRef<JSVal> ret;
1615 #ifdef PIXEL_MAP_SUPPORTED
1616     if (leadingMargin.pixmap) {
1617         auto lmObj = JSRef<JSObject>::New();
1618         auto size = JSRef<JSArray>::New();
1619         size->SetValueAt(0, JSRef<JSVal>::Make(ToJSValue(Dimension(leadingMargin.size.Width()).ConvertToVp())));
1620         size->SetValueAt(1, JSRef<JSVal>::Make(ToJSValue(Dimension(leadingMargin.size.Height()).ConvertToVp())));
1621         lmObj->SetPropertyObject("pixelMap", ConvertPixmap(leadingMargin.pixmap));
1622         lmObj->SetPropertyObject("size", size);
1623         ret = JSRef<JSVal>::Cast(lmObj);
1624     } else {
1625         ret = JSRef<JSVal>::Make(JSVal(ToJSValue(Dimension(leadingMargin.size.Width()).ConvertToVp())));
1626     }
1627 #else
1628     ret = JSRef<JSVal>::Make(JSVal(ToJSValue(Dimension(leadingMargin.size.Width()).ConvertToVp())));
1629 #endif
1630     info.SetReturnValue(ret);
1631 }
1632 
SetLeadingMargin(const JSCallbackInfo & info)1633 void JSParagraphStyleSpan::SetLeadingMargin(const JSCallbackInfo& info) {}
1634 
GetParagraphSpacing(const JSCallbackInfo & info)1635 void JSParagraphStyleSpan::GetParagraphSpacing(const JSCallbackInfo& info)
1636 {
1637     CHECK_NULL_VOID(paragraphStyleSpan_);
1638     auto paragraphSpacing = paragraphStyleSpan_->GetParagraphStyle().paragraphSpacing;
1639     CHECK_EQUAL_VOID(paragraphSpacing.has_value(), false);
1640     auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(paragraphSpacing.value().ConvertToVp())));
1641     info.SetReturnValue(ret);
1642 }
1643 
SetParagraphSpacing(const JSCallbackInfo & info)1644 void JSParagraphStyleSpan::SetParagraphSpacing(const JSCallbackInfo& info) {}
1645 
GetParagraphStyleSpan()1646 RefPtr<ParagraphStyleSpan>& JSParagraphStyleSpan::GetParagraphStyleSpan()
1647 {
1648     return paragraphStyleSpan_;
1649 }
1650 
SetParagraphStyleSpan(const RefPtr<ParagraphStyleSpan> & paragraphStyleSpan)1651 void JSParagraphStyleSpan::SetParagraphStyleSpan(const RefPtr<ParagraphStyleSpan>& paragraphStyleSpan)
1652 {
1653     paragraphStyleSpan_ = paragraphStyleSpan;
1654 }
1655 
1656 // JSExtSpan
JSExtSpan(JSRef<JSObject> extSpanObj)1657 JSExtSpan::JSExtSpan(JSRef<JSObject> extSpanObj) : extSpanObj_(extSpanObj) {}
1658 
JSExtSpan(JSRef<JSObject> extSpanObj,int32_t start,int32_t end)1659 JSExtSpan::JSExtSpan(JSRef<JSObject> extSpanObj, int32_t start, int32_t end)
1660     : ExtSpan(start, end), extSpanObj_(extSpanObj)
1661 {}
1662 
GetSubSpan(int32_t start,int32_t end)1663 RefPtr<SpanBase> JSExtSpan::GetSubSpan(int32_t start, int32_t end)
1664 {
1665     RefPtr<SpanBase> spanBase = MakeRefPtr<JSExtSpan>(extSpanObj_, start, end);
1666     return spanBase;
1667 }
1668 
IsAttributesEqual(const RefPtr<SpanBase> & other) const1669 bool JSExtSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
1670 {
1671     auto extSpan = DynamicCast<JSExtSpan>(other);
1672     if (!extSpan) {
1673         return false;
1674     }
1675     return (extSpan->extSpanObj_)
1676         ->GetLocalHandle()
1677         ->IsStrictEquals(extSpanObj_->GetEcmaVM(), extSpanObj_->GetLocalHandle());
1678 }
1679 
SetJsExtSpanObject(const JSRef<JSObject> & extSpanObj)1680 void JSExtSpan::SetJsExtSpanObject(const JSRef<JSObject>& extSpanObj)
1681 {
1682     extSpanObj_ = extSpanObj;
1683 }
1684 
GetJsExtSpanObject()1685 JSRef<JSObject>& JSExtSpan::GetJsExtSpanObject()
1686 {
1687     return extSpanObj_;
1688 }
1689 
JSBind(BindingTarget globalObj)1690 void JSBackgroundColorSpan::JSBind(BindingTarget globalObj)
1691 {
1692     JSClass<JSBackgroundColorSpan>::Declare("BackgroundColorStyle");
1693     JSClass<JSBackgroundColorSpan>::CustomProperty(
1694         "textBackgroundStyle", &JSBackgroundColorSpan::GetBackgroundColor, &JSBackgroundColorSpan::SetBackgroundColor);
1695     JSClass<JSBackgroundColorSpan>::Bind(
1696         globalObj, JSBackgroundColorSpan::Constructor, JSBackgroundColorSpan::Destructor);
1697 }
1698 
Constructor(const JSCallbackInfo & args)1699 void JSBackgroundColorSpan::Constructor(const JSCallbackInfo& args)
1700 {
1701     auto backgroundColor = Referenced::MakeRefPtr<JSBackgroundColorSpan>();
1702     CHECK_NULL_VOID(backgroundColor);
1703     backgroundColor->IncRefCount();
1704     RefPtr<BackgroundColorSpan> span;
1705     if (args.Length() <= 0 || !args[0]->IsObject()) {
1706         span = AceType::MakeRefPtr<BackgroundColorSpan>();
1707     } else {
1708         span = JSBackgroundColorSpan::ParseJSBackgroundColorSpan(args);
1709     }
1710     CHECK_NULL_VOID(span);
1711     backgroundColor->backgroundColorSpan_ = span;
1712     args.SetReturnValue(Referenced::RawPtr(backgroundColor));
1713 }
1714 
Destructor(JSBackgroundColorSpan * backgroundColor)1715 void JSBackgroundColorSpan::Destructor(JSBackgroundColorSpan* backgroundColor)
1716 {
1717     if (backgroundColor != nullptr) {
1718         backgroundColor->DecRefCount();
1719     }
1720 }
1721 
ParseJSBackgroundColorSpan(const JSCallbackInfo & info)1722 RefPtr<BackgroundColorSpan> JSBackgroundColorSpan::ParseJSBackgroundColorSpan(const JSCallbackInfo& info)
1723 {
1724     auto textBackgroundValue = JSContainerSpan::ParseTextBackgroundStyle(info);
1725     return AceType::MakeRefPtr<BackgroundColorSpan>(textBackgroundValue);
1726 }
1727 
GetBackgroundColor(const JSCallbackInfo & info)1728 void JSBackgroundColorSpan::GetBackgroundColor(const JSCallbackInfo& info)
1729 {
1730     CHECK_NULL_VOID(backgroundColorSpan_);
1731     auto backgroundColorStyle = backgroundColorSpan_->GetBackgroundColor();
1732     JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
1733     objectTemplate->SetInternalFieldCount(1);
1734     JSRef<JSObject> backgroundColorObj = objectTemplate->NewInstance();
1735     backgroundColorObj->SetProperty<std::string>("color", backgroundColorStyle.backgroundColor->ColorToString());
1736     backgroundColorObj->SetProperty<std::string>(
1737         "BorderRadiusProperty", backgroundColorStyle.backgroundRadius->ToString());
1738     info.SetReturnValue(backgroundColorObj);
1739 }
1740 
SetBackgroundColor(const JSCallbackInfo & info)1741 void JSBackgroundColorSpan::SetBackgroundColor(const JSCallbackInfo& info) {};
1742 
GetBackgroundColorSpan()1743 RefPtr<BackgroundColorSpan>& JSBackgroundColorSpan::GetBackgroundColorSpan()
1744 {
1745     return backgroundColorSpan_;
1746 }
1747 
SetBackgroundColorSpan(const RefPtr<BackgroundColorSpan> & backgroundColorSpan)1748 void JSBackgroundColorSpan::SetBackgroundColorSpan(const RefPtr<BackgroundColorSpan>& backgroundColorSpan)
1749 {
1750     backgroundColorSpan_ = backgroundColorSpan;
1751 }
1752 
1753 // JSUrlSpan
JSBind(BindingTarget globalObj)1754 void JSUrlSpan::JSBind(BindingTarget globalObj)
1755 {
1756     JSClass<JSUrlSpan>::Declare("UrlStyle");
1757     JSClass<JSUrlSpan>::CustomProperty(
1758         "url", &JSUrlSpan::GetUrlContext, &JSUrlSpan::SetUrlContext);
1759     JSClass<JSUrlSpan>::Bind(globalObj, JSUrlSpan::Constructor, JSUrlSpan::Destructor);
1760 }
1761 
Constructor(const JSCallbackInfo & args)1762 void JSUrlSpan::Constructor(const JSCallbackInfo& args)
1763 {
1764     auto urlSpan = Referenced::MakeRefPtr<JSUrlSpan>();
1765     urlSpan->IncRefCount();
1766     RefPtr<UrlSpan> span;
1767     if (args.Length() > 0 && args[0]->IsString()) {
1768         auto address = args[0]->ToString();
1769         span = AceType::MakeRefPtr<UrlSpan>(address);
1770     } else {
1771         span = AceType::MakeRefPtr<UrlSpan>();
1772     }
1773     CHECK_NULL_VOID(span);
1774     urlSpan->urlContextSpan_ = span;
1775     args.SetReturnValue(Referenced::RawPtr(urlSpan));
1776 }
1777 
Destructor(JSUrlSpan * urlSpan)1778 void JSUrlSpan::Destructor(JSUrlSpan* urlSpan)
1779 {
1780     if (urlSpan != nullptr) {
1781         urlSpan->DecRefCount();
1782     }
1783 }
1784 
GetUrlContext(const JSCallbackInfo & info)1785 void JSUrlSpan::GetUrlContext(const JSCallbackInfo& info)
1786 {
1787     CHECK_NULL_VOID(urlContextSpan_);
1788     auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(urlContextSpan_->GetUrlSpanAddress())));
1789     info.SetReturnValue(ret);
1790 }
1791 
SetUrlContext(const JSCallbackInfo & info)1792 void JSUrlSpan::SetUrlContext(const JSCallbackInfo& info) {}
1793 
GetUrlSpan()1794 const RefPtr<UrlSpan>& JSUrlSpan::GetUrlSpan()
1795 {
1796     return urlContextSpan_;
1797 }
1798 
SetUrlSpan(const RefPtr<UrlSpan> & urlSpan)1799 void JSUrlSpan::SetUrlSpan(const RefPtr<UrlSpan>& urlSpan)
1800 {
1801     urlContextSpan_ = urlSpan;
1802 }
1803 } // namespace OHOS::Ace::Framework