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