• 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_span.h"
17 #include "frameworks/bridge/declarative_frontend/jsview/js_container_span.h"
18 
19 #include <optional>
20 #include <sstream>
21 #include <string>
22 #include <vector>
23 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
24 
25 #include "base/geometry/dimension.h"
26 #include "base/log/ace_scoring_log.h"
27 #include "base/log/ace_trace.h"
28 #include "base/utils/utils.h"
29 #include "bridge/common/utils/utils.h"
30 #include "bridge/declarative_frontend/engine/functions/js_click_function.h"
31 #include "bridge/declarative_frontend/engine/functions/js_hover_function.h"
32 #include "bridge/declarative_frontend/engine/jsi/js_ui_index.h"
33 #include "bridge/declarative_frontend/jsview/js_interactable_view.h"
34 #include "bridge/declarative_frontend/jsview/js_utils.h"
35 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
36 #include "bridge/declarative_frontend/jsview/models/span_model_impl.h"
37 #include "bridge/declarative_frontend/jsview/models/text_model_impl.h"
38 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
39 #ifndef NG_BUILD
40 #include "bridge/declarative_frontend/view_stack_processor.h"
41 #endif
42 #include "bridge/declarative_frontend/jsview/js_text.h"
43 #include "core/common/container.h"
44 #include "core/components_ng/pattern/text/span_model.h"
45 #include "core/components_ng/pattern/text/span_model_ng.h"
46 #include "core/components_ng/pattern/text/span_node.h"
47 #include "core/components_ng/pattern/text/text_model.h"
48 
49 namespace OHOS::Ace {
50 
51 std::unique_ptr<SpanModel> SpanModel::instance_ = nullptr;
52 std::mutex SpanModel::mutex_;
53 
GetInstance()54 SpanModel* SpanModel::GetInstance()
55 {
56 #ifdef NG_BUILD
57     static NG::SpanModelNG instance;
58     return &instance;
59 #else
60     if (Container::IsCurrentUseNewPipeline()) {
61         static NG::SpanModelNG instance;
62         return &instance;
63     } else {
64         static Framework::SpanModelImpl instance;
65         return &instance;
66     }
67 #endif
68 }
69 
70 } // namespace OHOS::Ace
71 
72 namespace OHOS::Ace::Framework {
73 namespace {
74 
75 const std::vector<FontStyle> FONT_STYLES = { FontStyle::NORMAL, FontStyle::ITALIC };
76 const std::vector<TextCase> TEXT_CASES = { TextCase::NORMAL, TextCase::LOWERCASE, TextCase::UPPERCASE };
77 constexpr TextDecorationStyle DEFAULT_TEXT_DECORATION_STYLE = TextDecorationStyle::SOLID;
78 const int32_t DEFAULT_VARIABLE_FONT_WEIGHT = 400;
79 
80 } // namespace
81 
RegisterSpanFontInfo(const JSCallbackInfo & info,Font & font)82 void JSSpan::RegisterSpanFontInfo(const JSCallbackInfo& info, Font& font)
83 {
84     auto tmpInfo = info[0];
85     if (!tmpInfo->IsObject()) {
86         return;
87     }
88     auto paramObject = JSRef<JSObject>::Cast(tmpInfo);
89 
90     auto fontSize = paramObject->GetProperty(static_cast<int32_t>(ArkUIIndex::SIZE));
91     CalcDimension size;
92     RefPtr<ResourceObject> fontSizeResObj;
93     UnregisterSpanResource("fontSize");
94     bool ret = ParseJsDimensionFpNG(fontSize, size, fontSizeResObj, false);
95     if (ret && size.IsNonNegative()) {
96         font.fontSize = size;
97     }
98     if (fontSizeResObj) {
99         RegisterSpanResource<CalcDimension>("fontSize", fontSizeResObj, size);
100     }
101 
102     std::string weight;
103     auto fontWeight = paramObject->GetProperty(static_cast<int32_t>(ArkUIIndex::WEIGHT));
104     if (!fontWeight->IsNull()) {
105         int32_t variableFontWeight = DEFAULT_VARIABLE_FONT_WEIGHT;
106         ParseJsInt32(fontWeight, variableFontWeight);
107         if (fontWeight->IsNumber()) {
108             weight = std::to_string(fontWeight->ToNumber<int32_t>());
109         } else {
110             JSContainerBase::ParseJsString(fontWeight, weight);
111         }
112         font.fontWeight = ConvertStrToFontWeight(weight);
113     }
114 
115     UnregisterSpanResource("fontFamily");
116     auto fontFamily = paramObject->GetProperty(static_cast<int32_t>(ArkUIIndex::FAMILY));
117     if (!fontFamily->IsNull()) {
118         std::vector<std::string> fontFamilies;
119         RefPtr<ResourceObject> fontFamiliesResObj;
120         bool ret = ParseJsFontFamilies(fontFamily, fontFamilies, fontFamiliesResObj);
121         if (ret) {
122             font.fontFamilies = fontFamilies;
123         }
124         if (fontFamiliesResObj) {
125             RegisterSpanResource<std::vector<std::string>>("fontFamily",
126                 fontFamiliesResObj, font.fontFamilies);
127         }
128     }
129 
130     auto style = paramObject->GetProperty(static_cast<int32_t>(ArkUIIndex::STYLE));
131     if (!style->IsNull() || style->IsNumber()) {
132         font.fontStyle = static_cast<FontStyle>(style->ToNumber<int32_t>());
133     }
134 }
135 
SetFont(const JSCallbackInfo & info)136 void JSSpan::SetFont(const JSCallbackInfo& info)
137 {
138     Font font;
139     if (SystemProperties::ConfigChangePerform()) {
140         RegisterSpanFontInfo(info, font);
141     } else {
142         JSText::GetFontInfo(info, font);
143     }
144     SpanModel::GetInstance()->SetFont(font);
145 }
146 
SetFontSize(const JSCallbackInfo & info)147 void JSSpan::SetFontSize(const JSCallbackInfo& info)
148 {
149     if (info.Length() < 1) {
150         return;
151     }
152     CalcDimension fontSize;
153     RefPtr<ResourceObject> resObj;
154     UnregisterSpanResource("fontSize");
155     if (!ParseJsDimensionFpNG(info[0], fontSize, resObj, false) || fontSize.IsNegative()) {
156         auto pipelineContext = PipelineBase::GetCurrentContext();
157         CHECK_NULL_VOID(pipelineContext);
158         auto theme = pipelineContext->GetTheme<TextTheme>();
159         CHECK_NULL_VOID(theme);
160         fontSize = theme->GetTextStyle().GetFontSize();
161     }
162     if (SystemProperties::ConfigChangePerform() && resObj) {
163         RegisterSpanResource<CalcDimension>("fontSize", resObj, fontSize);
164     }
165 
166     SpanModel::GetInstance()->SetFontSize(fontSize);
167 }
168 
SetFontWeight(const JSCallbackInfo & info)169 void JSSpan::SetFontWeight(const JSCallbackInfo& info)
170 {
171     if (info.Length() < 1) {
172         return;
173     }
174     UnregisterSpanResource("fontWeight");
175     RefPtr<ResourceObject> resObj;
176     std::string fontWeight;
177     JSRef<JSVal> args = info[0];
178     if (args->IsNumber()) {
179         fontWeight = args->ToString();
180     } else {
181         ParseJsString(args, fontWeight, resObj);
182     }
183     if (SystemProperties::ConfigChangePerform() && resObj) {
184         RegisterSpanResource<FontWeight>("fontWeight", resObj, ConvertStrToFontWeight(fontWeight));
185     }
186     SpanModel::GetInstance()->SetFontWeight(ConvertStrToFontWeight(fontWeight));
187 }
188 
SetTextColor(const JSCallbackInfo & info)189 void JSSpan::SetTextColor(const JSCallbackInfo& info)
190 {
191     Color textColor;
192     RefPtr<ResourceObject> resObj;
193     UnregisterSpanResource("fontColor");
194     if (!ParseJsColor(info[0], textColor, resObj)) {
195         auto pipelineContext = PipelineBase::GetCurrentContext();
196         CHECK_NULL_VOID(pipelineContext);
197         auto theme = pipelineContext->GetTheme<TextTheme>();
198         CHECK_NULL_VOID(theme);
199         textColor = theme->GetTextStyle().GetTextColor();
200     }
201     if (SystemProperties::ConfigChangePerform() && resObj) {
202         RegisterSpanResource<Color>("fontColor", resObj, textColor);
203     }
204     SpanModel::GetInstance()->SetTextColor(textColor);
205 }
206 
SetFontStyle(int32_t value)207 void JSSpan::SetFontStyle(int32_t value)
208 {
209     if (value >= 0 && value < static_cast<int32_t>(FONT_STYLES.size())) {
210         auto style = FONT_STYLES[value];
211         SpanModel::GetInstance()->SetItalicFontStyle(style);
212     }
213 }
214 
SetFontFamily(const JSCallbackInfo & info)215 void JSSpan::SetFontFamily(const JSCallbackInfo& info)
216 {
217     if (info.Length() < 1) {
218         return;
219     }
220     RefPtr<ResourceObject> resObj;
221     std::vector<std::string> fontFamilies;
222     if (!ParseJsFontFamilies(info[0], fontFamilies, resObj)) {
223         return;
224     }
225     if (SystemProperties::ConfigChangePerform() && resObj) {
226         RegisterSpanResource<std::vector<std::string>>("fontFamily", resObj, fontFamilies);
227     } else {
228         UnregisterSpanResource("fontFamily");
229     }
230     SpanModel::GetInstance()->SetFontFamily(fontFamilies);
231 }
232 
SetLetterSpacing(const JSCallbackInfo & info)233 void JSSpan::SetLetterSpacing(const JSCallbackInfo& info)
234 {
235     if (info.Length() < 1) {
236         return;
237     }
238     CalcDimension value;
239     RefPtr<ResourceObject> resObj;
240     UnregisterSpanResource("letterSpacing");
241     if (!ParseJsDimensionFpNG(info[0], value, resObj, false)) {
242         value.Reset();
243         SpanModel::GetInstance()->SetLetterSpacing(value);
244         return;
245     }
246     if (SystemProperties::ConfigChangePerform() && resObj) {
247         RegisterSpanResource<CalcDimension>("letterSpacing", resObj, value);
248     }
249     SpanModel::GetInstance()->SetLetterSpacing(value);
250 }
251 
SetBaselineOffset(const JSCallbackInfo & info)252 void JSSpan::SetBaselineOffset(const JSCallbackInfo& info)
253 {
254     if (info.Length() < 1) {
255         return;
256     }
257     NG::CalcLength value;
258     RefPtr<ResourceObject> resObj;
259     UnRegisterResource("baselineOffset");
260     if (ConvertFromJSValueNG(info[0], value, resObj) &&
261         value.GetDimensionContainsNegative().Unit() != DimensionUnit::PERCENT) {
262         SpanModel::GetInstance()->SetBaselineOffset(value.GetDimensionContainsNegative());
263         if (SystemProperties::ConfigChangePerform() && resObj) {
264             RegisterSpanResource<CalcDimension>("baselineOffset", resObj,
265                 value.GetDimensionContainsNegative());
266         }
267         return;
268     }
269     value.Reset();
270     SpanModel::GetInstance()->SetBaselineOffset(value.GetDimensionContainsNegative());
271 }
272 
SetTextCase(int32_t value)273 void JSSpan::SetTextCase(int32_t value)
274 {
275     if (value >= 0 && value < static_cast<int32_t>(TEXT_CASES.size())) {
276         auto textCase = TEXT_CASES[value];
277         SpanModel::GetInstance()->SetTextCase(textCase);
278     }
279 }
280 
SetDecoration(const JSCallbackInfo & info)281 void JSSpan::SetDecoration(const JSCallbackInfo& info)
282 {
283     UnregisterSpanResource("decorationColor");
284     if (info[0]->IsUndefined()) {
285         SpanModel::GetInstance()->SetTextDecoration(TextDecoration::NONE);
286         return;
287     }
288     CHECK_NULL_VOID(info[0]->IsObject());
289     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
290     JSRef<JSVal> typeValue = obj->GetProperty("type");
291     JSRef<JSVal> colorValue = obj->GetProperty("color");
292     JSRef<JSVal> styleValue = obj->GetProperty("style");
293     JSRef<JSVal> thicknessScaleValue = obj->GetProperty("thicknessScale");
294 
295     std::optional<TextDecoration> textDecoration;
296     if (typeValue->IsNumber()) {
297         textDecoration = static_cast<TextDecoration>(typeValue->ToNumber<int32_t>());
298     } else {
299         auto theme = GetTheme<TextTheme>();
300         CHECK_NULL_VOID(theme);
301         textDecoration = theme->GetTextDecoration();
302     }
303     std::optional<TextDecorationStyle> textDecorationStyle;
304     if (styleValue->IsNumber()) {
305         textDecorationStyle = static_cast<TextDecorationStyle>(styleValue->ToNumber<int32_t>());
306     } else {
307         textDecorationStyle = DEFAULT_TEXT_DECORATION_STYLE;
308     }
309     std::optional<Color> colorVal;
310     Color result;
311 
312     RegisterDecorationColorResource(colorValue);
313 
314     if (ParseJsColor(colorValue, result)) {
315         colorVal = result;
316     } else {
317         auto theme = GetTheme<TextTheme>();
318         CHECK_NULL_VOID(theme);
319         if (Container::CurrentColorMode() == ColorMode::DARK) {
320             colorVal = theme->GetTextStyle().GetTextColor();
321         } else {
322             colorVal = Color::BLACK;
323         }
324     }
325     float lineThicknessScale = 1.0f;
326     if (thicknessScaleValue->IsNumber()) {
327         lineThicknessScale = thicknessScaleValue->ToNumber<float>();
328     }
329     lineThicknessScale = lineThicknessScale < 0 ? 1.0f : lineThicknessScale;
330     if (textDecoration) {
331         SpanModel::GetInstance()->SetTextDecoration(textDecoration.value());
332     }
333     if (colorVal) {
334         SpanModel::GetInstance()->SetTextDecorationColor(colorVal.value());
335     }
336     if (textDecorationStyle) {
337         SpanModel::GetInstance()->SetTextDecorationStyle(textDecorationStyle.value());
338     }
339     SpanModel::GetInstance()->SetLineThicknessScale(lineThicknessScale);
340 }
341 
RegisterDecorationColorResource(JSRef<JSVal> & colorValue)342 void JSSpan::RegisterDecorationColorResource(JSRef<JSVal>& colorValue)
343 {
344     if (!SystemProperties::ConfigChangePerform()) {
345         return;
346     }
347     Color result;
348     RefPtr<ResourceObject> resObj;
349     ParseJsColor(colorValue, result, resObj);
350     if (resObj) {
351         RegisterSpanResource<Color>("decorationColor", resObj, result);
352     }
353 }
354 
JsOnClick(const JSCallbackInfo & info)355 void JSSpan::JsOnClick(const JSCallbackInfo& info)
356 {
357     if (Container::IsCurrentUseNewPipeline()) {
358         if (info[0]->IsUndefined() && IsDisableEventVersion()) {
359             SpanModel::GetInstance()->ClearOnClick();
360             return;
361         }
362         if (!info[0]->IsFunction()) {
363             return;
364         }
365         auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
366         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
367         auto onClick = [execCtx = info.GetExecutionContext(), func = jsOnClickFunc, node = targetNode](
368                            BaseEventInfo* info) {
369             auto* clickInfo = TypeInfoHelper::DynamicCast<GestureEvent>(info);
370             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
371             ACE_SCORING_EVENT("onClick");
372             PipelineContext::SetCallBackNode(node);
373             func->Execute(*clickInfo);
374 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
375             JSInteractableView::ReportClickEvent(node);
376 #endif
377         };
378         SpanModel::GetInstance()->SetOnClick(std::move(onClick));
379         return;
380     }
381 #ifndef NG_BUILD
382     if (info[0]->IsFunction()) {
383         auto inspector = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
384         CHECK_NULL_VOID(inspector);
385         auto impl = inspector->GetInspectorFunctionImpl();
386         RefPtr<JsClickFunction> jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
387         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
388         auto clickFunc = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc), impl,
389                              node = targetNode](const BaseEventInfo* info) {
390             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
391             const auto* clickInfo = TypeInfoHelper::DynamicCast<ClickInfo>(info);
392             auto newInfo = *clickInfo;
393             if (impl) {
394                 impl->UpdateEventInfo(newInfo);
395             }
396             ACE_SCORING_EVENT("Span.onClick");
397             PipelineContext::SetCallBackNode(node);
398             func->Execute(newInfo);
399         };
400         SpanModel::GetInstance()->SetOnClick(std::move(clickFunc));
401     }
402 #endif
403 }
404 
JsRemoteMessage(const JSCallbackInfo & info)405 void JSSpan::JsRemoteMessage(const JSCallbackInfo& info)
406 {
407 #ifndef NG_BUILD
408     RemoteCallback remoteCallback;
409     JSInteractableView::JsRemoteMessage(info, remoteCallback);
410     EventMarker remoteMessageEventId(std::move(remoteCallback));
411     auto* stack = ViewStackProcessor::GetInstance();
412     auto textSpanComponent = AceType::DynamicCast<TextSpanComponent>(stack->GetMainComponent());
413     textSpanComponent->SetRemoteMessageEventId(remoteMessageEventId);
414 #endif
415 }
416 
SetLineHeight(const JSCallbackInfo & info)417 void JSSpan::SetLineHeight(const JSCallbackInfo& info)
418 {
419     CalcDimension value;
420     RefPtr<ResourceObject> resObj;
421     UnregisterSpanResource("lineHeight");
422     if (!ParseJsDimensionFpNG(info[0], value, resObj)) {
423         value.Reset();
424         SpanModel::GetInstance()->SetLineHeight(value);
425         return;
426     }
427     if (value.IsNegative()) {
428         value.Reset();
429     }
430     if (SystemProperties::ConfigChangePerform() && resObj) {
431         RegisterSpanResource<CalcDimension>("lineHeight", resObj, value);
432     }
433     SpanModel::GetInstance()->SetLineHeight(value);
434 }
435 
SetTextShadow(const JSCallbackInfo & info)436 void JSSpan::SetTextShadow(const JSCallbackInfo& info)
437 {
438     if (info.Length() < 1) {
439         return;
440     }
441     std::vector<Shadow> shadows;
442     ParseTextShadowFromShadowObject(info[0], shadows);
443     SpanModel::GetInstance()->SetTextShadow(shadows);
444 }
445 
446 
SetAccessibilityText(const JSCallbackInfo & info)447 void JSSpan::SetAccessibilityText(const JSCallbackInfo& info)
448 {
449     std::string text;
450     if ((info.Length() > 0) && info[0]->IsString()) {
451         text = info[0]->ToString();
452     }
453     SpanModel::GetInstance()->SetAccessibilityText(text);
454 }
455 
SetAccessibilityDescription(const JSCallbackInfo & info)456 void JSSpan::SetAccessibilityDescription(const JSCallbackInfo& info)
457 {
458     std::string description;
459     if ((info.Length() > 0) && info[0]->IsString()) {
460         description = info[0]->ToString();
461     }
462     SpanModel::GetInstance()->SetAccessibilityDescription(description);
463 }
464 
SetAccessibilityLevel(const JSCallbackInfo & info)465 void JSSpan::SetAccessibilityLevel(const JSCallbackInfo& info)
466 {
467     std::string level;
468     if ((info.Length() > 0) && info[0]->IsString()) {
469         level = info[0]->ToString();
470     }
471     SpanModel::GetInstance()->SetAccessibilityImportance(level);
472 }
473 
SetOnHover(const JSCallbackInfo & info)474 void JSSpan::SetOnHover(const JSCallbackInfo& info)
475 {
476     if (info[0]->IsUndefined() && IsDisableEventVersion()) {
477         SpanModel::GetInstance()->ResetOnHover();
478         return;
479     }
480     if (!info[0]->IsFunction()) {
481         return;
482     }
483     RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
484     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
485     auto onHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc), node = frameNode](
486         bool isHover, HoverInfo& hoverInfo) {
487         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
488         ACE_SCORING_EVENT("onHover");
489         PipelineContext::SetCallBackNode(node);
490         func->HoverExecute(isHover, hoverInfo);
491     };
492     SpanModel::GetInstance()->SetOnHover(std::move(onHover));
493 }
494 
JSBind(BindingTarget globalObj)495 void JSSpan::JSBind(BindingTarget globalObj)
496 {
497     JSClass<JSSpan>::Declare("Span");
498     MethodOptions opt = MethodOptions::NONE;
499     JSClass<JSSpan>::StaticMethod("create", &JSSpan::Create, opt);
500     JSClass<JSSpan>::StaticMethod("font", &JSSpan::SetFont, opt);
501     JSClass<JSSpan>::StaticMethod("fontColor", &JSSpan::SetTextColor, opt);
502     JSClass<JSSpan>::StaticMethod("fontSize", &JSSpan::SetFontSize, opt);
503     JSClass<JSSpan>::StaticMethod("fontWeight", &JSSpan::SetFontWeight, opt);
504     JSClass<JSSpan>::StaticMethod("fontStyle", &JSSpan::SetFontStyle, opt);
505     JSClass<JSSpan>::StaticMethod("fontFamily", &JSSpan::SetFontFamily, opt);
506     JSClass<JSSpan>::StaticMethod("letterSpacing", &JSSpan::SetLetterSpacing, opt);
507     JSClass<JSSpan>::StaticMethod("baselineOffset", &JSSpan::SetBaselineOffset, opt);
508     JSClass<JSSpan>::StaticMethod("textCase", &JSSpan::SetTextCase, opt);
509     JSClass<JSSpan>::StaticMethod("textShadow", &JSSpan::SetTextShadow, opt);
510     JSClass<JSSpan>::StaticMethod("decoration", &JSSpan::SetDecoration);
511     JSClass<JSSpan>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
512     JSClass<JSSpan>::StaticMethod("onHover", &JSSpan::SetOnHover);
513     JSClass<JSSpan>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
514     JSClass<JSSpan>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
515     JSClass<JSSpan>::StaticMethod("remoteMessage", &JSSpan::JsRemoteMessage);
516     JSClass<JSSpan>::StaticMethod("onClick", &JSSpan::JsOnClick);
517     JSClass<JSSpan>::StaticMethod("lineHeight", &JSSpan::SetLineHeight, opt);
518     JSClass<JSSpan>::StaticMethod("textBackgroundStyle", &JSContainerSpan::SetTextBackgroundStyle, opt);
519     JSClass<JSSpan>::StaticMethod("accessibilityText", &JSSpan::SetAccessibilityText, opt);
520     JSClass<JSSpan>::StaticMethod("accessibilityDescription", &JSSpan::SetAccessibilityDescription, opt);
521     JSClass<JSSpan>::StaticMethod("accessibilityLevel", &JSSpan::SetAccessibilityLevel, opt);
522     JSClass<JSSpan>::InheritAndBind<JSContainerBase>(globalObj);
523 }
524 
Create(const JSCallbackInfo & info)525 void JSSpan::Create(const JSCallbackInfo& info)
526 {
527     std::u16string label;
528     RefPtr<ResourceObject> resObj;
529     if (info.Length() > 0) {
530         ParseJsString(info[0], label, resObj);
531     }
532     if (SystemProperties::ConfigChangePerform() && resObj) {
533         SpanModel::GetInstance()->Create(label, resObj);
534         return;
535     } else {
536         UnregisterSpanResource("value");
537     }
538     SpanModel::GetInstance()->Create(label);
539 }
540 
541 template<typename T>
RegisterSpanResource(const std::string & key,const RefPtr<ResourceObject> & resObj,T value)542 void JSSpan::RegisterSpanResource(const std::string& key, const RefPtr<ResourceObject>& resObj, T value)
543 {
544     auto uiNode = NG::ViewStackProcessor::GetInstance()->GetMainElementNode();
545     CHECK_NULL_VOID(uiNode);
546     auto spanNode = AceType::DynamicCast<NG::SpanNode>(uiNode);
547     if (spanNode) {
548         spanNode->RegisterResource<T>(key, resObj, value);
549     }
550 }
551 
UnregisterSpanResource(const std::string & key)552 void JSSpan::UnregisterSpanResource(const std::string& key)
553 {
554     auto uiNode = NG::ViewStackProcessor::GetInstance()->GetMainElementNode();
555     CHECK_NULL_VOID(uiNode);
556     auto spanNode = AceType::DynamicCast<NG::SpanNode>(uiNode);
557     if (spanNode) {
558         spanNode->UnregisterResource(key);
559     }
560 }
561 
562 } // namespace OHOS::Ace::Framework
563