• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components/declaration/common/declaration.h"
17 
18 #include "base/geometry/calc_dimension.h"
19 #include "base/geometry/dimension.h"
20 #include "base/log/ace_trace.h"
21 #include "base/utils/string_utils.h"
22 #include "core/common/ace_application_info.h"
23 #include "core/components/common/properties/color.h"
24 #include "core/components/common/properties/decoration.h"
25 #include "core/components/declaration/common/declaration_constants.h"
26 #include "frameworks/bridge/common/utils/utils.h"
27 
28 namespace OHOS::Ace {
29 
30 using namespace Framework;
31 
32 namespace {
33 
34 constexpr uint32_t TRANSFORM_SINGLE = 1;
35 constexpr uint32_t TRANSFORM_DUAL = 2;
36 constexpr int32_t DIRECTION_ANGLE = 1;
37 constexpr int32_t DIRECTION_SIDE = 2;
38 constexpr int32_t DIRECTION_CORNER = 3;
39 constexpr int32_t MS_TO_S = 1000;
40 constexpr uint32_t COMMON_METHOD_FOCUS_ARGS_SIZE = 1;
41 constexpr Dimension TRANSFORM_ORIGIN_DEFAULT = 0.5_pct;
42 const char COMMON_METHOD_FOCUS[] = "focus";
43 
44 // Shared Transition Effect Type String
45 constexpr char SHARED_TRANSITION_EFFECT_STATIC[] = "static";
46 constexpr char SHARED_TRANSITION_EFFECT_EXCHANGE[] = "exchange";
47 
48 template<class T>
ParseFunctionValue(const std::string & line,const std::string & key,std::function<T (const std::string &)> parser)49 T ParseFunctionValue(const std::string& line, const std::string& key, std::function<T(const std::string&)> parser)
50 {
51     std::vector<std::string> strs;
52     StringUtils::SplitStr(line, " ", strs, true);
53     for (const auto& str : strs) {
54         if (str.empty()) {
55             continue;
56         }
57         auto leftIndex = str.find('(');
58         auto rightIndex = str.find(')');
59         if (leftIndex == std::string::npos || rightIndex == std::string::npos) {
60             continue;
61         }
62         if (leftIndex + 1 >= rightIndex) {
63             continue;
64         }
65         if (str.substr(0, leftIndex) != key) {
66             continue;
67         }
68 
69         auto valueStr = str.substr(leftIndex + 1, rightIndex - leftIndex - 1);
70         return parser(valueStr);
71     }
72     return T {};
73 }
74 
ParseSharedEffect(const std::string & effect,Declaration & declaration)75 RefPtr<SharedTransitionEffect> ParseSharedEffect(const std::string& effect, Declaration& declaration)
76 {
77     std::string effectTrim = effect;
78     RemoveHeadTailSpace(effectTrim);
79     if (effectTrim == SHARED_TRANSITION_EFFECT_STATIC) {
80         return SharedTransitionEffect::GetSharedTransitionEffect(
81             SharedTransitionEffectType::SHARED_EFFECT_STATIC, declaration.GetShareId());
82     } else if (effectTrim == SHARED_TRANSITION_EFFECT_EXCHANGE) {
83         return SharedTransitionEffect::GetSharedTransitionEffect(
84             SharedTransitionEffectType::SHARED_EFFECT_EXCHANGE, declaration.GetShareId());
85     } else {
86         LOGE("Parse shared effect failed. unknown effect: %{public}s, share id: %{public}s", effect.c_str(),
87             declaration.GetShareId().c_str());
88         return nullptr;
89     }
90 }
91 
ParseTransitionEffect(const std::string & option)92 TransitionEffect ParseTransitionEffect(const std::string& option)
93 {
94     static std::unordered_map<std::string, TransitionEffect> types = {
95         { "unfold", TransitionEffect::UNFOLD },
96         { "none", TransitionEffect::NONE },
97     };
98     auto pos = types.find(option);
99     if (pos != types.end()) {
100         return pos->second;
101     }
102     return TransitionEffect::NONE;
103 }
104 
ParseClickEffect(const std::string & effect)105 ClickSpringEffectType ParseClickEffect(const std::string& effect)
106 {
107     static std::unordered_map<std::string, ClickSpringEffectType> types = {
108         { "spring-small", ClickSpringEffectType::SMALL },
109         { "spring-medium", ClickSpringEffectType::MEDIUM },
110         { "spring-large", ClickSpringEffectType::LARGE },
111     };
112     auto pos = types.find(effect);
113     if (pos != types.end()) {
114         return pos->second;
115     }
116     return ClickSpringEffectType::NONE;
117 }
118 
StrToWindowBlurStyle(const std::string & value)119 inline WindowBlurStyle StrToWindowBlurStyle(const std::string& value)
120 {
121     static std::unordered_map<std::string, WindowBlurStyle> types = {
122         { "small_light", WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT },
123         { "medium_light", WindowBlurStyle::STYLE_BACKGROUND_MEDIUM_LIGHT },
124         { "large_light", WindowBlurStyle::STYLE_BACKGROUND_LARGE_LIGHT },
125         { "xlarge_light", WindowBlurStyle::STYLE_BACKGROUND_XLARGE_LIGHT },
126         { "small_dark", WindowBlurStyle::STYLE_BACKGROUND_SMALL_DARK },
127         { "medium_dark", WindowBlurStyle::STYLE_BACKGROUND_MEDIUM_DARK },
128         { "large_dark", WindowBlurStyle::STYLE_BACKGROUND_LARGE_DARK },
129         { "xlarge_dark", WindowBlurStyle::STYLE_BACKGROUND_XLARGE_DARK },
130     };
131     auto pos = types.find(value);
132     if (pos != types.end()) {
133         return pos->second;
134     }
135     return WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT;
136 }
137 
138 } // namespace
139 
Declaration()140 Declaration::Declaration()
141 {
142     backDecoration_ = AceType::MakeRefPtr<Decoration>();
143 }
144 
145 Declaration::~Declaration() = default;
146 
Init()147 void Declaration::Init()
148 {
149     InitCommonAttribute();
150     InitCommonStyle();
151     InitCommonEvent();
152     InitCommonMethod();
153     InitSpecialized();
154     auto& commonAttr = MaybeResetAttribute<CommonAttribute>(AttributeTag::COMMON_ATTR);
155     if (commonAttr.IsValid()) {
156         commonAttr.isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
157     }
158 
159     auto& backgroundStyle = MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
160     if (backgroundStyle.IsValid()) {
161         backgroundStyle.backgroundImage = AceType::MakeRefPtr<BackgroundImage>();
162         backgroundStyle.borderImage = AceType::MakeRefPtr<BorderImage>();
163     }
164 }
165 
InitCommonAttribute()166 void Declaration::InitCommonAttribute()
167 {
168     for (auto attribute : DeclarationConstants::DEFAULT_ATTRS) {
169         AddCommonAttribute(attribute);
170     }
171 }
172 
InitCommonStyle()173 void Declaration::InitCommonStyle()
174 {
175     for (auto style : DeclarationConstants::DEFAULT_STYLES) {
176         AddCommonStyle(style);
177     }
178 }
179 
InitCommonEvent()180 void Declaration::InitCommonEvent()
181 {
182     for (auto event : DeclarationConstants::DEFAULT_EVENTS) {
183         AddCommonEvent(event);
184     }
185 }
186 
InitCommonMethod()187 void Declaration::InitCommonMethod()
188 {
189     for (auto method : DeclarationConstants::DEFAULT_METHODS) {
190         AddCommonMethod(method);
191     }
192 }
193 
AddCommonAttribute(AttributeTag tag)194 void Declaration::AddCommonAttribute(AttributeTag tag)
195 {
196     static const LinearEnumMapNode<AttributeTag, void (*)(Declaration&)> operators[] = {
197         { AttributeTag::COMMON_ATTR,
198             [](Declaration& declaration) {
199                 declaration.attributes_.try_emplace(
200                     AttributeTag::COMMON_ATTR, DeclarationConstants::DEFAULT_COMMON_ATTR);
201             } },
202         { AttributeTag::COMMON_DISABLED_ATTR,
203             [](Declaration& declaration) {
204                 declaration.attributes_.try_emplace(
205                     AttributeTag::COMMON_DISABLED_ATTR, DeclarationConstants::DEFAULT_DISABLED_ATTR);
206             } },
207         { AttributeTag::COMMON_FOCUSABLE_ATTR,
208             [](Declaration& declaration) {
209                 declaration.attributes_.try_emplace(
210                     AttributeTag::COMMON_FOCUSABLE_ATTR, DeclarationConstants::DEFAULT_FOCUSABLE_ATTR);
211             } },
212         { AttributeTag::COMMON_TOUCHABLE_ATTR,
213             [](Declaration& declaration) {
214                 declaration.attributes_.try_emplace(
215                     AttributeTag::COMMON_TOUCHABLE_ATTR, DeclarationConstants::DEFAULT_TOUCHABLE_ATTR);
216             } },
217         { AttributeTag::COMMON_DATA_ATTR,
218             [](Declaration& declaration) {
219                 declaration.attributes_.try_emplace(
220                     AttributeTag::COMMON_DATA_ATTR, DeclarationConstants::DEFAULT_DATA_ATTR);
221             } },
222         { AttributeTag::COMMON_CLICK_EFFECT_ATTR,
223             [](Declaration& declaration) {
224                 declaration.attributes_.try_emplace(
225                     AttributeTag::COMMON_CLICK_EFFECT_ATTR, DeclarationConstants::DEFAULT_CLICK_EFFECT_ATTR);
226             } },
227         { AttributeTag::COMMON_RENDER_ATTR,
228             [](Declaration& declaration) {
229                 declaration.attributes_.try_emplace(
230                     AttributeTag::COMMON_RENDER_ATTR, DeclarationConstants::DEFAULT_RENDER_ATTR);
231             } },
232         { AttributeTag::COMMON_MULTIMODAL_ATTR,
233             [](Declaration& declaration) {
234                 declaration.attributes_.try_emplace(
235                     AttributeTag::COMMON_MULTIMODAL_ATTR, DeclarationConstants::DEFAULT_MULTI_MODAL_ATTR);
236             } },
237     };
238     auto operatorIter = BinarySearchFindIndex(operators, ArraySize(operators), tag);
239     if (operatorIter != -1) {
240         operators[operatorIter].value(*this);
241     } else {
242         LOGW("attribute tag %{public}d is invalid", tag);
243     }
244 }
245 
AddCommonStyle(StyleTag tag)246 void Declaration::AddCommonStyle(StyleTag tag)
247 {
248     static const LinearEnumMapNode<StyleTag, void (*)(Declaration&)> operators[] = {
249         { StyleTag::COMMON_STYLE,
250             [](Declaration& declaration) {
251                 declaration.styles_.try_emplace(StyleTag::COMMON_STYLE, DeclarationConstants::DEFAULT_COMMON_STYLE);
252             } },
253         { StyleTag::COMMON_SIZE_STYLE,
254             [](Declaration& declaration) {
255                 declaration.styles_.try_emplace(StyleTag::COMMON_SIZE_STYLE, DeclarationConstants::DEFAULT_SIZE_STYLE);
256             } },
257         { StyleTag::COMMON_MARGIN_STYLE,
258             [](Declaration& declaration) {
259                 declaration.styles_.try_emplace(
260                     StyleTag::COMMON_MARGIN_STYLE, DeclarationConstants::DEFAULT_MARGIN_STYLE);
261             } },
262         { StyleTag::COMMON_PADDING_STYLE,
263             [](Declaration& declaration) {
264                 declaration.styles_.try_emplace(
265                     StyleTag::COMMON_PADDING_STYLE, DeclarationConstants::DEFAULT_PADDING_STYLE);
266             } },
267         { StyleTag::COMMON_BORDER_STYLE,
268             [](Declaration& declaration) {
269                 declaration.styles_.try_emplace(
270                     StyleTag::COMMON_BORDER_STYLE, DeclarationConstants::DEFAULT_BORDER_STYLE);
271             } },
272         { StyleTag::COMMON_BACKGROUND_STYLE,
273             [](Declaration& declaration) {
274                 declaration.styles_.try_emplace(
275                     StyleTag::COMMON_BACKGROUND_STYLE, DeclarationConstants::DEFAULT_BACKGROUND_STYLE);
276             } },
277         { StyleTag::COMMON_FLEX_STYLE,
278             [](Declaration& declaration) {
279                 declaration.styles_.try_emplace(StyleTag::COMMON_FLEX_STYLE, DeclarationConstants::DEFAULT_FLEX_STYLE);
280             } },
281         { StyleTag::COMMON_POSITION_STYLE,
282             [](Declaration& declaration) {
283                 declaration.styles_.try_emplace(
284                     StyleTag::COMMON_POSITION_STYLE, DeclarationConstants::DEFAULT_POSITION_STYLE);
285             } },
286         { StyleTag::COMMON_OPACITY_STYLE,
287             [](Declaration& declaration) {
288                 declaration.styles_.try_emplace(
289                     StyleTag::COMMON_OPACITY_STYLE, DeclarationConstants::DEFAULT_OPACITY_STYLE);
290             } },
291         { StyleTag::COMMON_VISIBILITY_STYLE,
292             [](Declaration& declaration) {
293                 declaration.styles_.try_emplace(
294                     StyleTag::COMMON_VISIBILITY_STYLE, DeclarationConstants::DEFAULT_VISIBILITY_STYLE);
295             } },
296         { StyleTag::COMMON_DISPLAY_STYLE,
297             [](Declaration& declaration) {
298                 declaration.styles_.try_emplace(
299                     StyleTag::COMMON_DISPLAY_STYLE, DeclarationConstants::DEFAULT_DISPLAY_STYLE);
300             } },
301         { StyleTag::COMMON_SHADOW_STYLE,
302             [](Declaration& declaration) {
303                 declaration.styles_.try_emplace(
304                     StyleTag::COMMON_SHADOW_STYLE, DeclarationConstants::DEFAULT_SHADOW_STYLE);
305             } },
306         { StyleTag::COMMON_OVERFLOW_STYLE,
307             [](Declaration& declaration) {
308                 declaration.styles_.try_emplace(
309                     StyleTag::COMMON_OVERFLOW_STYLE, DeclarationConstants::DEFAULT_OVERFLOW_STYLE);
310             } },
311         { StyleTag::COMMON_FILTER_STYLE,
312             [](Declaration& declaration) {
313                 declaration.styles_.try_emplace(
314                     StyleTag::COMMON_FILTER_STYLE, DeclarationConstants::DEFAULT_FILTER_STYLE);
315             } },
316         { StyleTag::COMMON_ANIMATION_STYLE,
317             [](Declaration& declaration) {
318                 declaration.styles_.try_emplace(
319                     StyleTag::COMMON_ANIMATION_STYLE, DeclarationConstants::DEFAULT_ANIMATION_STYLE);
320             } },
321         { StyleTag::COMMON_SHARE_TRANSITION_STYLE,
322             [](Declaration& declaration) {
323                 declaration.styles_.try_emplace(
324                     StyleTag::COMMON_SHARE_TRANSITION_STYLE, DeclarationConstants::DEFAULT_SHARE_TRANSITION_STYLE);
325             } },
326         { StyleTag::COMMON_CARD_TRANSITION_STYLE,
327             [](Declaration& declaration) {
328                 declaration.styles_.try_emplace(
329                     StyleTag::COMMON_CARD_TRANSITION_STYLE, DeclarationConstants::DEFAULT_CARD_TRANSITION_STYLE);
330             } },
331         { StyleTag::COMMON_PAGE_TRANSITION_STYLE,
332             [](Declaration& declaration) {
333                 declaration.styles_.try_emplace(
334                     StyleTag::COMMON_PAGE_TRANSITION_STYLE, DeclarationConstants::DEFAULT_PAGE_TRANSITION_STYLE);
335             } },
336         { StyleTag::COMMON_CLIP_PATH_STYLE,
337             [](Declaration& declaration) {
338               declaration.styles_.try_emplace(
339                   StyleTag::COMMON_CLIP_PATH_STYLE, DeclarationConstants::DEFAULT_CLIP_PATH_STYLE);
340             } },
341         { StyleTag::COMMON_MASK_STYLE,
342             [](Declaration& declaration) {
343               declaration.styles_.try_emplace(
344                   StyleTag::COMMON_MASK_STYLE, DeclarationConstants::DEFAULT_MASK_STYLE);
345             } },
346         { StyleTag::COMMON_IMAGE_STYLE,
347             [](Declaration& declaration) {
348               declaration.styles_.try_emplace(
349                   StyleTag::COMMON_IMAGE_STYLE, DeclarationConstants::DEFAULT_IMAGE_STYLE);
350             } },
351     };
352     auto operatorIter = BinarySearchFindIndex(operators, ArraySize(operators), tag);
353     if (operatorIter != -1) {
354         operators[operatorIter].value(*this);
355     } else {
356         LOGW("style tag %{public}d is invalid", tag);
357     }
358 }
359 
AddCommonEvent(EventTag tag)360 void Declaration::AddCommonEvent(EventTag tag)
361 {
362     static const LinearEnumMapNode<EventTag, void (*)(Declaration&)> operators[] = {
363         { EventTag::COMMON_RAW_EVENT,
364             [](Declaration& declaration) {
365                 declaration.events_.try_emplace(EventTag::COMMON_RAW_EVENT, DeclarationConstants::DEFAULT_RAW_EVENT);
366             } },
367         { EventTag::COMMON_GESTURE_EVENT,
368             [](Declaration& declaration) {
369                 declaration.events_.try_emplace(
370                     EventTag::COMMON_GESTURE_EVENT, DeclarationConstants::DEFAULT_GESTURE_EVENT);
371             } },
372         { EventTag::COMMON_REMOTE_MESSAGE_GESTURE_EVENT,
373             [](Declaration& declaration) {
374                 declaration.events_.try_emplace(
375                     EventTag::COMMON_REMOTE_MESSAGE_GESTURE_EVENT, DeclarationConstants::DEFAULT_GESTURE_EVENT);
376             } },
377         { EventTag::COMMON_FOCUS_EVENT,
378             [](Declaration& declaration) {
379                 declaration.events_.try_emplace(
380                     EventTag::COMMON_FOCUS_EVENT, DeclarationConstants::DEFAULT_FOCUS_EVENT);
381             } },
382         { EventTag::COMMON_KEY_EVENT,
383             [](Declaration& declaration) {
384                 declaration.events_.try_emplace(EventTag::COMMON_KEY_EVENT, DeclarationConstants::DEFAULT_KEY_EVENT);
385             } },
386         { EventTag::COMMON_MOUSE_EVENT,
387             [](Declaration& declaration) {
388                 declaration.events_.try_emplace(
389                     EventTag::COMMON_MOUSE_EVENT, DeclarationConstants::DEFAULT_MOUSE_EVENT);
390             } },
391         { EventTag::COMMON_SWIPE_EVENT,
392             [](Declaration& declaration) {
393                 declaration.events_.try_emplace(
394                     EventTag::COMMON_SWIPE_EVENT, DeclarationConstants::DEFAULT_SWIPE_EVENT);
395             } },
396         { EventTag::COMMON_ATTACH_EVENT,
397             [](Declaration& declaration) {
398                 declaration.events_.try_emplace(
399                     EventTag::COMMON_ATTACH_EVENT, DeclarationConstants::DEFAULT_ATTACH_EVENT);
400             } },
401         { EventTag::COMMON_CROWN_EVENT,
402             [](Declaration& declaration) {
403                 declaration.events_.try_emplace(
404                     EventTag::COMMON_CROWN_EVENT, DeclarationConstants::DEFAULT_CROWN_EVENT);
405             } },
406     };
407     auto operatorIter = BinarySearchFindIndex(operators, ArraySize(operators), tag);
408     if (operatorIter != -1) {
409         operators[operatorIter].value(*this);
410     } else {
411         LOGW("event tag %{public}d is invalid", tag);
412     }
413 }
414 
AddCommonMethod(MethodTag tag)415 void Declaration::AddCommonMethod(MethodTag tag)
416 {
417     static const LinearEnumMapNode<MethodTag, void (*)(Declaration&)> operators[] = {
418         { MethodTag::COMMON_METHOD,
419             [](Declaration& declaration) {
420                 declaration.methods_.try_emplace(MethodTag::COMMON_METHOD, DeclarationConstants::DEFAULT_METHOD);
421             } },
422     };
423     auto operatorIter = BinarySearchFindIndex(operators, ArraySize(operators), tag);
424     if (operatorIter != -1) {
425         operators[operatorIter].value(*this);
426     } else {
427         LOGW("method tag %{public}d is invalid", tag);
428     }
429 }
430 
AddSpecializedAttribute(std::shared_ptr<Attribute> && specializedAttribute)431 void Declaration::AddSpecializedAttribute(std::shared_ptr<Attribute>&& specializedAttribute)
432 {
433     attributes_.try_emplace(AttributeTag::SPECIALIZED_ATTR, std::move(specializedAttribute));
434 }
435 
AddSpecializedStyle(std::shared_ptr<Style> && specializedStyle)436 void Declaration::AddSpecializedStyle(std::shared_ptr<Style>&& specializedStyle)
437 {
438     styles_.try_emplace(StyleTag::SPECIALIZED_STYLE, std::move(specializedStyle));
439 }
440 
AddSpecializedEvent(std::shared_ptr<Event> && specializedEvent)441 void Declaration::AddSpecializedEvent(std::shared_ptr<Event>&& specializedEvent)
442 {
443     events_.try_emplace(EventTag::SPECIALIZED_EVENT, std::move(specializedEvent));
444 }
445 
AddSpecializedRemoteMessageEvent(std::shared_ptr<Event> && specializedEvent)446 void Declaration::AddSpecializedRemoteMessageEvent(std::shared_ptr<Event>&& specializedEvent)
447 {
448     events_.try_emplace(EventTag::SPECIALIZED_REMOTE_MESSAGE_EVENT, std::move(specializedEvent));
449 }
450 
AddSpecializedMethod(std::shared_ptr<Method> && specializedMethod)451 void Declaration::AddSpecializedMethod(std::shared_ptr<Method>&& specializedMethod)
452 {
453     methods_.try_emplace(MethodTag::SPECIALIZED_METHOD, std::move(specializedMethod));
454 }
455 
GetAttribute(AttributeTag tag) const456 Attribute& Declaration::GetAttribute(AttributeTag tag) const
457 {
458     auto it = attributes_.find(tag);
459     if (it != attributes_.end()) {
460         return *(it->second);
461     } else {
462         static Attribute errAttribute {
463             .tag = AttributeTag::UNKNOWN
464         };
465         return errAttribute;
466     }
467 }
468 
GetStyle(StyleTag tag) const469 Style& Declaration::GetStyle(StyleTag tag) const
470 {
471     auto it = styles_.find(tag);
472     if (it != styles_.end()) {
473         return *(it->second);
474     } else {
475         static Style errStyle { .tag = StyleTag::UNKNOWN };
476         return errStyle;
477     }
478 }
479 
GetEvent(EventTag tag) const480 Event& Declaration::GetEvent(EventTag tag) const
481 {
482     auto it = events_.find(tag);
483     if (it != events_.end()) {
484         return *(it->second);
485     } else {
486         static Event errEvent { .tag = EventTag::UNKNOWN };
487         return errEvent;
488     }
489 }
490 
GetMethod(MethodTag tag) const491 Method& Declaration::GetMethod(MethodTag tag) const
492 {
493     auto it = methods_.find(tag);
494     if (it != methods_.end()) {
495         return *(it->second);
496     } else {
497         static Method errMethod { .tag = MethodTag::UNKNOWN };
498         return errMethod;
499     }
500 }
501 
SetShowAttr(const std::string & showValue)502 void Declaration::SetShowAttr(const std::string& showValue)
503 {
504     auto& renderAttr = MaybeResetAttribute<CommonRenderAttribute>(AttributeTag::COMMON_RENDER_ATTR);
505     if (renderAttr.IsValid()) {
506         renderAttr.show = showValue;
507     }
508     auto& displayStyle = MaybeResetStyle<CommonDisplayStyle>(StyleTag::COMMON_DISPLAY_STYLE);
509     if (displayStyle.IsValid()) {
510         displayStyle.display = (showValue == "false") ? DisplayType::NONE : DisplayType::NO_SETTING;
511     }
512 }
513 
SetAttr(const std::vector<std::pair<std::string,std::string>> & attrs)514 void Declaration::SetAttr(const std::vector<std::pair<std::string, std::string>>& attrs)
515 {
516     ACE_SCOPED_TRACE("Declaration::SetAttr");
517     if (onSetAttribute_) {
518         onSetAttribute_();
519     }
520     static const std::string flagOn = "on";
521     static const std::string flagOff = "off";
522     static const std::string flagAuto = "auto";
523     // static linear map must be sorted by key.
524     static const LinearMapNode<void (*)(const std::string&, Declaration&)> attrSetters[] = {
525         { DOM_CLICK_EFFECT,
526             [](const std::string& value, Declaration& declaration) {
527                 auto& clickEffectAttr =
528                     declaration.MaybeResetAttribute<CommonClickEffectAttribute>(AttributeTag::COMMON_CLICK_EFFECT_ATTR);
529                 if (clickEffectAttr.IsValid()) {
530                     declaration.hasTransformStyle_ = true;
531                     declaration.hasClickEffect_ = true;
532                     clickEffectAttr.clickEffect = ParseClickEffect(value);
533                 }
534             } },
535         { DOM_DIR,
536             [](const std::string& value, Declaration& declaration) {
537                 auto& commonAttr = declaration.MaybeResetAttribute<CommonAttribute>(AttributeTag::COMMON_ATTR);
538                 if (commonAttr.IsValid()) {
539                     if (value == "rtl") {
540                         commonAttr.isRightToLeft = true;
541                         commonAttr.direction = TextDirection::RTL;
542                     } else if (value == "ltr") {
543                         commonAttr.isRightToLeft = false;
544                         commonAttr.direction = TextDirection::LTR;
545                     } else {
546                         commonAttr.isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
547                         commonAttr.direction = TextDirection::AUTO;
548                     }
549                 }
550             } },
551         { DOM_FOCUSABLE,
552             [](const std::string& value, Declaration& declaration) {
553                 auto& focusableAttr =
554                     declaration.MaybeResetAttribute<CommonFocusableAttribute>(AttributeTag::COMMON_FOCUSABLE_ATTR);
555                 if (focusableAttr.IsValid()) {
556                     focusableAttr.focusable.first = StringToBool(value);
557                     focusableAttr.focusable.second = true; // Tag whether user defined focusable.
558                 }
559             } },
560         { DOM_ID,
561             [](const std::string& value, Declaration& declaration) {
562                 auto& commonAttr = declaration.MaybeResetAttribute<CommonAttribute>(AttributeTag::COMMON_ATTR);
563                 if (commonAttr.IsValid()) {
564                     commonAttr.id = value;
565                     declaration.hasIdAttr_ = true;
566                 }
567             } },
568 #ifndef WEARABLE_PRODUCT
569         { DOM_SCENE_LABEL,
570             [](const std::string& value, Declaration& declaration) {
571                 auto& multimodalAttr =
572                     declaration.MaybeResetAttribute<CommonMultimodalAttribute>(AttributeTag::COMMON_MULTIMODAL_ATTR);
573                 if (!multimodalAttr.IsValid()) {
574                     return;
575                 }
576                 static const LinearMapNode<SceneLabel> multimodalSceneMap[] = {
577                     { "audio", SceneLabel::AUDIO },
578                     { "common", SceneLabel::COMMON },
579                     { "page", SceneLabel::PAGE },
580                     { "switch", SceneLabel::SWITCH },
581                     { "video", SceneLabel::VIDEO },
582                 };
583                 auto iter = BinarySearchFindIndex(multimodalSceneMap, ArraySize(multimodalSceneMap), value.c_str());
584                 if (iter != -1) {
585                     multimodalAttr.scene = multimodalSceneMap[iter].value;
586                 }
587             } },
588 #endif
589         { DOM_SHOW,
590             [](const std::string& value, Declaration& declaration) {
591                 declaration.hasDisplayStyle_ = true;
592                 if (declaration.useLiteStyle_) {
593                     auto& visibilityStyle =
594                         declaration.MaybeResetStyle<CommonVisibilityStyle>(StyleTag::COMMON_VISIBILITY_STYLE);
595                     if (visibilityStyle.IsValid()) {
596                         visibilityStyle.visibility =
597                             (value == "true") ? VisibilityType::VISIBLE : VisibilityType::HIDDEN;
598                     }
599                 } else {
600                     declaration.SetShowAttr(value);
601                 }
602             } },
603 #ifndef WEARABLE_PRODUCT
604         { DOM_SPRING_EFFECT,
605             [](const std::string& value, Declaration& declaration) {
606                 auto& clickEffectAttr =
607                     declaration.MaybeResetAttribute<CommonClickEffectAttribute>(AttributeTag::COMMON_CLICK_EFFECT_ATTR);
608                 if (clickEffectAttr.IsValid()) {
609                     declaration.hasTransformStyle_ = true;
610                     declaration.hasClickEffect_ = true;
611                     clickEffectAttr.clickEffect = ParseClickEffect(value);
612                 }
613             } },
614         { DOM_SUBSCRIPT_FLAG,
615             [](const std::string& value, Declaration& declaration) {
616                 auto& multimodalAttr =
617                     declaration.MaybeResetAttribute<CommonMultimodalAttribute>(AttributeTag::COMMON_MULTIMODAL_ATTR);
618                 if (multimodalAttr.IsValid()) {
619                     multimodalAttr.useSubscript =
620                         (value == flagOn) || (value == flagAuto && declaration.IsSubscriptEnable());
621                 }
622             } },
623         { DOM_SUBSCRIPT_LABEL,
624             [](const std::string& value, Declaration& declaration) {
625                 auto& multimodalAttr =
626                     declaration.MaybeResetAttribute<CommonMultimodalAttribute>(AttributeTag::COMMON_MULTIMODAL_ATTR);
627                 if (multimodalAttr.IsValid()) {
628                     multimodalAttr.subscriptLabel = value;
629                 }
630             } },
631         { DOM_TOUCHABLE,
632             [](const std::string& value, Declaration& declaration) {
633                 auto& touchableAttr =
634                     declaration.MaybeResetAttribute<CommonTouchableAttribute>(AttributeTag::COMMON_TOUCHABLE_ATTR);
635                 if (touchableAttr.IsValid()) {
636                     touchableAttr.touchable = StringToBool(value);
637                 }
638             } },
639         { DOM_VOICE_LABEL,
640             [](const std::string& value, Declaration& declaration) {
641                 auto& multimodalAttr =
642                     declaration.MaybeResetAttribute<CommonMultimodalAttribute>(AttributeTag::COMMON_MULTIMODAL_ATTR);
643                 if (multimodalAttr.IsValid()) {
644                     multimodalAttr.voiceLabel = value;
645                 }
646             } },
647 #endif
648     };
649 
650     for (const auto& attr : attrs) {
651         if (attr.first == DOM_DISABLED) {
652             isDisabled_ = StringToBool(attr.second);
653         }
654 
655         if (attr.first == DOM_BUTTON_WAITING) {
656             isWaiting_ = StringToBool(attr.second);
657         }
658 
659         if (attr.first == DOM_CHECKED) {
660             isChecked_ = StringToBool(attr.second);
661         }
662 
663         if (SetSpecializedAttr(attr)) {
664             continue;
665         }
666         auto operatorIter = BinarySearchFindIndex(attrSetters, ArraySize(attrSetters), attr.first.c_str());
667         if (operatorIter != -1) {
668             attrSetters[operatorIter].value(attr.second, *this);
669         }
670     }
671 }
672 
SetStyle(const std::vector<std::pair<std::string,std::string>> & styles)673 void Declaration::SetStyle(const std::vector<std::pair<std::string, std::string>>& styles)
674 {
675     ACE_SCOPED_TRACE("Declaration::SetStyle");
676     for (const auto& style : styles) {
677         if (style.first.find(DOM_PSEUDO_CLASS_SYMBOL) == std::string::npos) {
678             SetCurrentStyle(style);
679         }
680     }
681 }
682 
SetCurrentStyle(const std::pair<std::string,std::string> & style)683 void Declaration::SetCurrentStyle(const std::pair<std::string, std::string>& style)
684 {
685     if (SetSpecializedStyle(style)) {
686         // If the subclass consumes this property, it will no longer look in the general property.
687         return;
688     }
689 
690     // Operator map for styles
691     static const LinearMapNode<void (*)(const std::string&, Declaration&)> styleSetter[] = {
692         { DOM_ALIGN_SELF,
693             [](const std::string& value, Declaration& declaration) {
694                 auto& commonStyle = declaration.MaybeResetStyle<CommonStyle>(StyleTag::COMMON_STYLE);
695                 if (commonStyle.IsValid()) {
696                     commonStyle.alignSelf = value;
697                 }
698             } },
699         { DOM_ANIMATION_DELAY,
700             [](const std::string& value, Declaration& declaration) {
701                 auto& animationStyle =
702                     declaration.MaybeResetStyle<CommonAnimationStyle>(StyleTag::COMMON_ANIMATION_STYLE);
703                 if (animationStyle.IsValid()) {
704                     if (value.find("ms") != std::string::npos) {
705                         animationStyle.animationDelay = StringUtils::StringToInt(value);
706                         animationStyle.tweenOption.SetDelay(animationStyle.animationDelay);
707                     } else {
708                         animationStyle.animationDelay = StringUtils::StringToInt(value) * MS_TO_S;
709                         animationStyle.tweenOption.SetDelay(animationStyle.animationDelay);
710                     }
711                 }
712             } },
713         { DOM_ANIMATION_DIRECTION,
714             [](const std::string& value, Declaration& declaration) {
715                 auto& animationStyle =
716                     declaration.MaybeResetStyle<CommonAnimationStyle>(StyleTag::COMMON_ANIMATION_STYLE);
717                 if (animationStyle.IsValid()) {
718                     animationStyle.tweenOption.SetAnimationDirection(StringToAnimationDirection(value));
719                 }
720             } },
721         { DOM_ANIMATION_DURATION,
722             [](const std::string& value, Declaration& declaration) {
723                 auto& animationStyle =
724                     declaration.MaybeResetStyle<CommonAnimationStyle>(StyleTag::COMMON_ANIMATION_STYLE);
725                 if (animationStyle.IsValid()) {
726                     if (value.find("ms") != std::string::npos) {
727                         animationStyle.animationDuration = StringUtils::StringToInt(value);
728                         animationStyle.tweenOption.SetDuration(animationStyle.animationDuration);
729                     } else {
730                         animationStyle.animationDuration = StringUtils::StringToInt(value) * MS_TO_S;
731                         animationStyle.tweenOption.SetDuration(animationStyle.animationDuration);
732                     }
733                 }
734             } },
735         { DOM_ANIMATION_FILL_MODE,
736             [](const std::string& value, Declaration& declaration) {
737                 auto& animationStyle =
738                     declaration.MaybeResetStyle<CommonAnimationStyle>(StyleTag::COMMON_ANIMATION_STYLE);
739                 if (animationStyle.IsValid()) {
740                     animationStyle.fillMode = StringToFillMode(value);
741                     animationStyle.tweenOption.SetFillMode(animationStyle.fillMode);
742                 }
743             } },
744         { DOM_ANIMATION_ITERATION_COUNT,
745             [](const std::string& value, Declaration& declaration) {
746                 auto& animationStyle =
747                     declaration.MaybeResetStyle<CommonAnimationStyle>(StyleTag::COMMON_ANIMATION_STYLE);
748                 if (animationStyle.IsValid()) {
749                     animationStyle.iteration = StringUtils::StringToInt(value);
750                     animationStyle.tweenOption.SetIteration(animationStyle.iteration);
751                 }
752             } },
753         { DOM_ANIMATION_PLAY_STATE,
754             [](const std::string& value, Declaration& declaration) {
755                 auto& animationStyle =
756                     declaration.MaybeResetStyle<CommonAnimationStyle>(StyleTag::COMMON_ANIMATION_STYLE);
757                 if (animationStyle.IsValid()) {
758                     animationStyle.animationOperation = StringToAnimationOperation(value);
759                 }
760             } },
761         { DOM_ANIMATION_TIMING_FUNCTION,
762             [](const std::string& value, Declaration& declaration) {
763                 auto& animationStyle =
764                     declaration.MaybeResetStyle<CommonAnimationStyle>(StyleTag::COMMON_ANIMATION_STYLE);
765                 if (animationStyle.IsValid()) {
766                     animationStyle.curve = CreateCurve(value);
767                     animationStyle.tweenOption.SetCurve(animationStyle.curve);
768                 }
769             } },
770         { DOM_APPEARING_DURATION,
771             [](const std::string& value, Declaration& declaration) {
772                 auto& opacityStyle = declaration.MaybeResetStyle<CommonOpacityStyle>(StyleTag::COMMON_OPACITY_STYLE);
773                 if (opacityStyle.IsValid()) {
774                     opacityStyle.appearingDuration = StringUtils::StringToInt(value);
775                     declaration.hasDisplayStyle_ = true;
776                 }
777             } },
778         { DOM_ASPECT_RATIO,
779             [](const std::string& value, Declaration& declaration) {
780                 auto& sizeStyle = declaration.MaybeResetStyle<CommonSizeStyle>(StyleTag::COMMON_SIZE_STYLE);
781                 if (sizeStyle.IsValid()) {
782                     sizeStyle.aspectRatio = StringToDouble(value);
783                 }
784             } },
785         { DOM_BACKDROP_FILTER,
786             [](const std::string& value, Declaration& declaration) {
787                 declaration.hasDecorationStyle_ = true;
788                 auto radius = ParseFunctionValue<Dimension>(value, DOM_BLUR, StringToDimension);
789                 if (radius.IsValid()) {
790                     declaration.backDecoration_->SetBlurRadius(radius);
791                 } else {
792                     declaration.backDecoration_->SetBlurRadius(Dimension {});
793                 }
794             } },
795         { DOM_BACKGROUND, &Declaration::SetBackground },
796         { DOM_BACKGROUND_COLOR,
797             [](const std::string& value, Declaration& declaration) {
798                 auto& backgroundStyle =
799                     declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
800                 if (backgroundStyle.IsValid()) {
801                     auto backgroundColor = declaration.ParseColor(value);
802                     backgroundStyle.backgroundColor = backgroundColor;
803                     declaration.backDecoration_->SetBackgroundColor(backgroundColor);
804                     declaration.hasBackGroundColor_ = true;
805                     declaration.hasDecorationStyle_ = true;
806                 }
807             } },
808         { DOM_BACKGROUND_IMAGE,
809             [](const std::string& value, Declaration& declaration) {
810                 auto& backgroundStyle =
811                     declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
812                 if (backgroundStyle.IsValid()) {
813                     backgroundStyle.backgroundImage->SetSrc(value, declaration.GetThemeConstants());
814                     declaration.backDecoration_->SetImage(backgroundStyle.backgroundImage);
815                     declaration.backDecoration_->SetBackgroundColor(Color::TRANSPARENT);
816                     declaration.hasDecorationStyle_ = true;
817                 }
818             } },
819         { DOM_BACKGROUND_IMAGE_POSITION, &Declaration::SetBackgroundImagePosition },
820         { DOM_BACKGROUND_IMAGE_REPEAT,
821             [](const std::string& value, Declaration& declaration) {
822                 auto& backgroundStyle =
823                     declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
824                 if (backgroundStyle.IsValid()) {
825                     backgroundStyle.backgroundRepeat = ConvertStrToImageRepeat(value);
826                     backgroundStyle.backgroundImage->SetImageRepeat(backgroundStyle.backgroundRepeat);
827                     declaration.hasDecorationStyle_ = true;
828                 }
829             } },
830         { DOM_BACKGROUND_IMAGE_SIZE, &Declaration::SetBackgroundImageSize },
831         { DOM_BORDER, &Declaration::SetBorderOverall },
832         { DOM_BORDER_BOTTOM_COLOR,
833             [](const std::string& value, Declaration& declaration) {
834                 auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
835                 if (borderStyle.IsValid()) {
836                     borderStyle.border.SetBottomColor(declaration.ParseColor(value));
837                     declaration.hasBorderStyle_ = true;
838                     declaration.hasDecorationStyle_ = true;
839                 }
840             } },
841         { DOM_BORDER_BOTTOM_LEFT_RADIUS,
842             [](const std::string& value, Declaration& declaration) {
843                 auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
844                 if (borderStyle.IsValid()) {
845                     borderStyle.border.SetBottomLeftRadius(Radius(declaration.ParseDimension(value)));
846                     declaration.hasBorderStyle_ = true;
847                     declaration.hasBorderRadiusStyle_ = true;
848                     declaration.hasDecorationStyle_ = true;
849                 }
850             } },
851         { DOM_BORDER_BOTTOM_RIGHT_RADIUS,
852             [](const std::string& value, Declaration& declaration) {
853                 auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
854                 if (borderStyle.IsValid()) {
855                     borderStyle.border.SetBottomRightRadius(Radius(declaration.ParseDimension(value)));
856                     declaration.hasBorderStyle_ = true;
857                     declaration.hasBorderRadiusStyle_ = true;
858                     declaration.hasDecorationStyle_ = true;
859                 }
860             } },
861         { DOM_BORDER_BOTTOM_STYLE,
862             [](const std::string& value, Declaration& declaration) {
863                 auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
864                 if (borderStyle.IsValid()) {
865                     borderStyle.border.SetBottomStyle(ConvertStrToBorderStyle(value));
866                     declaration.hasBorderStyle_ = true;
867                     declaration.hasDecorationStyle_ = true;
868                 }
869             } },
870         { DOM_BORDER_BOTTOM_WIDTH,
871             [](const std::string& value, Declaration& declaration) {
872                 auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
873                 if (borderStyle.IsValid()) {
874                     borderStyle.border.SetBottomWidth(declaration.ParseDimension(value));
875                     declaration.hasBorderStyle_ = true;
876                     declaration.hasDecorationStyle_ = true;
877                 }
878             } },
879         { DOM_BORDER_COLOR, &Declaration::SetBorderColorForFourEdges },
880 
881         { DOM_BORDER_IMAGE, &Declaration::SetBorderImage},
882         { DOM_BORDER_IMAGE_OUTSET, &Declaration::SetBorderImageOutSetForFourEdges},
883         { DOM_BORDER_IMAGE_REPEAT, &Declaration::SetBorderImageRepeatForFourEdges},
884         { DOM_BORDER_IMAGE_SLICE, &Declaration::SetBorderImageSliceForFourEdges},
885         { DOM_BORDER_IMAGE_SOURCE, &Declaration::SetBorderImageFindUrl},
886         { DOM_BORDER_IMAGE_WIDTH, &Declaration::SetBorderImageWidthForFourEdges},
887 
888         { DOM_BORDER_LEFT_COLOR,
889             [](const std::string& value, Declaration& declaration) {
890                 auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
891                 if (borderStyle.IsValid()) {
892                     borderStyle.border.SetLeftColor(declaration.ParseColor(value));
893                     declaration.hasBorderStyle_ = true;
894                     declaration.hasDecorationStyle_ = true;
895                 }
896             } },
897         { DOM_BORDER_LEFT_STYLE,
898             [](const std::string& value, Declaration& declaration) {
899                 auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
900                 if (borderStyle.IsValid()) {
901                     borderStyle.border.SetLeftStyle(ConvertStrToBorderStyle(value));
902                     declaration.hasBorderStyle_ = true;
903                     declaration.hasDecorationStyle_ = true;
904                 }
905             } },
906         { DOM_BORDER_LEFT_WIDTH,
907             [](const std::string& value, Declaration& declaration) {
908                 auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
909                 if (borderStyle.IsValid()) {
910                     borderStyle.border.SetLeftWidth(declaration.ParseDimension(value));
911                     declaration.hasBorderStyle_ = true;
912                     declaration.hasDecorationStyle_ = true;
913                 }
914             } },
915         { DOM_BORDER_RADIUS,
916             [](const std::string& value, Declaration& declaration) {
917                 auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
918                 if (borderStyle.IsValid()) {
919                     borderStyle.border.SetBorderRadius(Radius(declaration.ParseDimension(value)));
920                     declaration.hasBorderStyle_ = true;
921                     declaration.hasBorderRadiusStyle_ = true;
922                     declaration.hasDecorationStyle_ = true;
923                 }
924             } },
925         { DOM_BORDER_RIGHT_COLOR,
926             [](const std::string& value, Declaration& declaration) {
927                 auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
928                 if (borderStyle.IsValid()) {
929                     borderStyle.border.SetRightColor(declaration.ParseColor(value));
930                     declaration.hasBorderStyle_ = true;
931                     declaration.hasDecorationStyle_ = true;
932                 }
933             } },
934         { DOM_BORDER_RIGHT_STYLE,
935             [](const std::string& value, Declaration& declaration) {
936                 auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
937                 if (borderStyle.IsValid()) {
938                     borderStyle.border.SetRightStyle(ConvertStrToBorderStyle(value));
939                     declaration.hasBorderStyle_ = true;
940                     declaration.hasDecorationStyle_ = true;
941                 }
942             } },
943         { DOM_BORDER_RIGHT_WIDTH,
944             [](const std::string& value, Declaration& declaration) {
945                 auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
946                 if (borderStyle.IsValid()) {
947                     borderStyle.border.SetRightWidth(declaration.ParseDimension(value));
948                     declaration.hasBorderStyle_ = true;
949                     declaration.hasDecorationStyle_ = true;
950                 }
951             } },
952         { DOM_BORDER_STYLE, &Declaration::SetBorderStyleForFourEdges },
953         { DOM_BORDER_TOP_COLOR,
954             [](const std::string& value, Declaration& declaration) {
955                 auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
956                 if (borderStyle.IsValid()) {
957                     borderStyle.border.SetTopColor(declaration.ParseColor(value));
958                     declaration.hasBorderStyle_ = true;
959                     declaration.hasDecorationStyle_ = true;
960                 }
961             } },
962         { DOM_BORDER_TOP_LEFT_RADIUS,
963             [](const std::string& value, Declaration& declaration) {
964                 auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
965                 if (borderStyle.IsValid()) {
966                     borderStyle.border.SetTopLeftRadius(Radius(declaration.ParseDimension(value)));
967                     declaration.hasBorderStyle_ = true;
968                     declaration.hasBorderRadiusStyle_ = true;
969                     declaration.hasDecorationStyle_ = true;
970                 }
971             } },
972         { DOM_BORDER_TOP_RIGHT_RADIUS,
973             [](const std::string& value, Declaration& declaration) {
974                 auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
975                 if (borderStyle.IsValid()) {
976                     borderStyle.border.SetTopRightRadius(Radius(declaration.ParseDimension(value)));
977                     declaration.hasBorderStyle_ = true;
978                     declaration.hasBorderRadiusStyle_ = true;
979                     declaration.hasDecorationStyle_ = true;
980                 }
981             } },
982         { DOM_BORDER_TOP_STYLE,
983             [](const std::string& value, Declaration& declaration) {
984                 auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
985                 if (borderStyle.IsValid()) {
986                     borderStyle.border.SetTopStyle(ConvertStrToBorderStyle(value));
987                     declaration.hasBorderStyle_ = true;
988                     declaration.hasDecorationStyle_ = true;
989                 }
990             } },
991         { DOM_BORDER_TOP_WIDTH,
992             [](const std::string& value, Declaration& declaration) {
993                 auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
994                 if (borderStyle.IsValid()) {
995                     borderStyle.border.SetTopWidth(declaration.ParseDimension(value));
996                     declaration.hasBorderStyle_ = true;
997                     declaration.hasDecorationStyle_ = true;
998                 }
999             } },
1000         { DOM_BORDER_WIDTH, &Declaration::SetBorderWidthForFourEdges },
1001         { DOM_POSITION_BOTTOM,
1002             [](const std::string& value, Declaration& declaration) {
1003                 auto& positionStyle = declaration.MaybeResetStyle<CommonPositionStyle>(StyleTag::COMMON_POSITION_STYLE);
1004                 if (positionStyle.IsValid() && !value.empty()) {
1005                     positionStyle.bottom = declaration.ParseDimension(value);
1006                     declaration.hasPositionStyle_ = true;
1007                     declaration.hasBottom_ = true;
1008                 }
1009             } },
1010         { DOM_BOX_SHADOW_BLUR,
1011             [](const std::string& value, Declaration& declaration) {
1012                 auto& shadowStyle = declaration.MaybeResetStyle<CommonShadowStyle>(StyleTag::COMMON_SHADOW_STYLE);
1013                 if (shadowStyle.IsValid()) {
1014                     shadowStyle.shadow.SetBlurRadius(StringToDouble(value));
1015                     declaration.hasDecorationStyle_ = true;
1016                     declaration.hasShadowStyle_ = true;
1017                 }
1018             } },
1019         { DOM_BOX_SHADOW_COLOR,
1020             [](const std::string& value, Declaration& declaration) {
1021                 auto& shadowStyle = declaration.MaybeResetStyle<CommonShadowStyle>(StyleTag::COMMON_SHADOW_STYLE);
1022                 if (shadowStyle.IsValid()) {
1023                     if (value.empty()) {
1024                         shadowStyle.shadow.SetColor(Color::BLACK);
1025                         return;
1026                     }
1027                     shadowStyle.shadow.SetColor(declaration.ParseColor(value));
1028                     declaration.hasDecorationStyle_ = true;
1029                     declaration.hasShadowStyle_ = true;
1030                 }
1031             } },
1032         { DOM_BOX_SHADOW_H,
1033             [](const std::string& value, Declaration& declaration) {
1034                 auto& shadowStyle = declaration.MaybeResetStyle<CommonShadowStyle>(StyleTag::COMMON_SHADOW_STYLE);
1035                 if (shadowStyle.IsValid()) {
1036                     shadowStyle.shadow.SetOffsetX(StringToDouble(value));
1037                     declaration.hasDecorationStyle_ = true;
1038                     declaration.hasShadowStyle_ = true;
1039                 }
1040             } },
1041         { DOM_BOX_SHADOW_SPREAD,
1042             [](const std::string& value, Declaration& declaration) {
1043                 auto& shadowStyle = declaration.MaybeResetStyle<CommonShadowStyle>(StyleTag::COMMON_SHADOW_STYLE);
1044                 if (shadowStyle.IsValid()) {
1045                     shadowStyle.shadow.SetSpreadRadius(StringToDouble(value));
1046                     declaration.hasDecorationStyle_ = true;
1047                     declaration.hasShadowStyle_ = true;
1048                 }
1049             } },
1050         { DOM_BOX_SHADOW_V,
1051             [](const std::string& value, Declaration& declaration) {
1052                 auto& shadowStyle = declaration.MaybeResetStyle<CommonShadowStyle>(StyleTag::COMMON_SHADOW_STYLE);
1053                 if (shadowStyle.IsValid()) {
1054                     shadowStyle.shadow.SetOffsetY(StringToDouble(value));
1055                     declaration.hasDecorationStyle_ = true;
1056                     declaration.hasShadowStyle_ = true;
1057                 }
1058             } },
1059         { DOM_BOX_SIZING,
1060             [](const std::string& value, Declaration& declaration) {
1061                 auto& sizeStyle = declaration.MaybeResetStyle<CommonSizeStyle>(StyleTag::COMMON_SIZE_STYLE);
1062                 if (sizeStyle.IsValid()) {
1063                     sizeStyle.boxSizing = ConvertStrToBoxSizing(value);
1064                 }
1065             } },
1066         { DOM_CLIP_PATH,
1067             [](const std::string& value, Declaration& declaration) {
1068                 auto& clipPathStyle =
1069                     declaration.MaybeResetStyle<CommonClipPathStyle>(StyleTag::COMMON_CLIP_PATH_STYLE);
1070                 if (clipPathStyle.IsValid()) {
1071                     clipPathStyle.clipPath = CreateClipPath(value);
1072                 }
1073             } },
1074         { DOM_DISPLAY,
1075             [](const std::string& value, Declaration& declaration) {
1076                 auto& displayStyle = declaration.MaybeResetStyle<CommonDisplayStyle>(StyleTag::COMMON_DISPLAY_STYLE);
1077                 if (displayStyle.IsValid()) {
1078                     if (value == DOM_DISPLAY_NONE) {
1079                         displayStyle.display = DisplayType::NONE;
1080                     } else if (value == DOM_DISPLAY_GRID) {
1081                         displayStyle.display = DisplayType::GRID;
1082                     } else if (value == DOM_DISPLAY_FLEX) {
1083                         displayStyle.display = DisplayType::FLEX;
1084                     } else if (value == DOM_DISPLAY_BLOCK) {
1085                         displayStyle.display = DisplayType::BLOCK;
1086                     } else if (value == DOM_DISPLAY_INLINE) {
1087                         displayStyle.display = DisplayType::INLINE;
1088                     } else if (value == DOM_DISPLAY_INLINE_BLOCK) {
1089                         displayStyle.display = DisplayType::INLINE_BLOCK;
1090                     } else if (value == DOM_DISPLAY_INLINE_FLEX) {
1091                         displayStyle.display = DisplayType::INLINE_FLEX;
1092                     }
1093                     declaration.hasDisplayStyle_ = true;
1094                 }
1095             } },
1096         { DOM_DISPLAY_INDEX,
1097             [](const std::string& value, Declaration& declaration) {
1098                 auto& flexStyle = declaration.MaybeResetStyle<CommonFlexStyle>(StyleTag::COMMON_FLEX_STYLE);
1099                 if (flexStyle.IsValid()) {
1100                     flexStyle.displayIndex = StringToInt(value);
1101                 }
1102             } },
1103         { DOM_POSITION_END,
1104             [](const std::string& value, Declaration& declaration) {
1105                 auto& positionStyle = declaration.MaybeResetStyle<CommonPositionStyle>(StyleTag::COMMON_POSITION_STYLE);
1106                 if (positionStyle.IsValid() && !value.empty()) {
1107                     if (declaration.IsRightToLeft()) {
1108                         positionStyle.left = declaration.ParseDimension(value);
1109                         declaration.hasLeft_ = true;
1110                     } else {
1111                         positionStyle.right = declaration.ParseDimension(value);
1112                         declaration.hasRight_ = true;
1113                     }
1114                     declaration.hasPositionStyle_ = true;
1115                 }
1116             } },
1117         { DOM_FILTER,
1118             [](const std::string& value, Declaration& declaration) {
1119                 declaration.hasFrontDecorationStyle_ = true;
1120                 if (!declaration.frontDecoration_) {
1121                     declaration.frontDecoration_ = AceType::MakeRefPtr<Decoration>();
1122                 }
1123                 auto radius = ParseFunctionValue<Dimension>(value, DOM_BLUR, StringToDimension);
1124                 if (radius.IsValid()) {
1125                     declaration.frontDecoration_->SetBlurRadius(radius);
1126                 } else {
1127                     declaration.frontDecoration_->SetBlurRadius(Dimension {});
1128                 }
1129             } },
1130         { DOM_FLEX,
1131             [](const std::string& value, Declaration& declaration) {
1132                 auto& flexStyle = declaration.MaybeResetStyle<CommonFlexStyle>(StyleTag::COMMON_FLEX_STYLE);
1133                 if (flexStyle.IsValid()) {
1134                     flexStyle.flexGrow = StringToDouble(value);
1135                 }
1136             } },
1137         { DOM_FLEX_BASIS,
1138             [](const std::string& value, Declaration& declaration) {
1139                 auto& flexStyle = declaration.MaybeResetStyle<CommonFlexStyle>(StyleTag::COMMON_FLEX_STYLE);
1140                 if (flexStyle.IsValid()) {
1141                     flexStyle.flexBasis = StringToDimension(value);
1142                 }
1143             } },
1144         { DOM_FLEX_GROW,
1145             [](const std::string& value, Declaration& declaration) {
1146                 auto& flexStyle = declaration.MaybeResetStyle<CommonFlexStyle>(StyleTag::COMMON_FLEX_STYLE);
1147                 if (flexStyle.IsValid()) {
1148                     flexStyle.flexGrow = StringToDouble(value);
1149                 }
1150             } },
1151         { DOM_FLEX_SHRINK,
1152             [](const std::string& value, Declaration& declaration) {
1153                 auto& flexStyle = declaration.MaybeResetStyle<CommonFlexStyle>(StyleTag::COMMON_FLEX_STYLE);
1154                 if (flexStyle.IsValid()) {
1155                     flexStyle.flexShrink = StringToDouble(value);
1156                 }
1157             } },
1158         { DOM_FLEX_WEIGHT,
1159             [](const std::string& value, Declaration& declaration) {
1160                 auto& flexStyle = declaration.MaybeResetStyle<CommonFlexStyle>(StyleTag::COMMON_FLEX_STYLE);
1161                 if (flexStyle.IsValid()) {
1162                     flexStyle.flexWeight = StringToDouble(value);
1163                 }
1164             } },
1165         { DOM_HEIGHT,
1166             [](const std::string& value, Declaration& declaration) {
1167                 auto& sizeStyle = declaration.MaybeResetStyle<CommonSizeStyle>(StyleTag::COMMON_SIZE_STYLE);
1168                 if (sizeStyle.IsValid()) {
1169                     sizeStyle.height = declaration.ParseCalcDimension(value);
1170                     declaration.hasBoxStyle_ = true;
1171                 }
1172             } },
1173         { DOM_IMAGE_FILL,
1174             [](const std::string& value, Declaration& declaration) {
1175                 auto& imageStyle = declaration.MaybeResetStyle<CommonImageStyle>(StyleTag::COMMON_IMAGE_STYLE);
1176                 if (imageStyle.IsValid()) {
1177                     imageStyle.imageFill = declaration.ParseColor(value);
1178                 }
1179             } },
1180         { DOM_LAYOUT_IN_BOX,
1181             [](const std::string& value, Declaration& declaration) {
1182                 auto& commonStyle = declaration.MaybeResetStyle<CommonStyle>(StyleTag::COMMON_STYLE);
1183                 if (commonStyle.IsValid()) {
1184                     commonStyle.layoutInBox = StringToBool(value);
1185                     declaration.hasBoxStyle_ = true;
1186                 }
1187             } },
1188         { DOM_POSITION_LEFT,
1189             [](const std::string& value, Declaration& declaration) {
1190                 auto& positionStyle = declaration.MaybeResetStyle<CommonPositionStyle>(StyleTag::COMMON_POSITION_STYLE);
1191                 if (positionStyle.IsValid() && !value.empty()) {
1192                     positionStyle.left = declaration.ParseDimension(value);
1193                     declaration.hasPositionStyle_ = true;
1194                     declaration.hasLeft_ = true;
1195                 }
1196             } },
1197         { DOM_MARGIN, &Declaration::SetMarginOverall },
1198         { DOM_MARGIN_BOTTOM,
1199             [](const std::string& value, Declaration& declaration) {
1200                 auto& marginStyle = declaration.MaybeResetStyle<CommonMarginStyle>(StyleTag::COMMON_MARGIN_STYLE);
1201                 if (marginStyle.IsValid()) {
1202                     marginStyle.margin.SetBottom(declaration.ParseCalcDimension(value));
1203                     declaration.hasBoxStyle_ = true;
1204                 }
1205             } },
1206         { DOM_MARGIN_END,
1207             [](const std::string& value, Declaration& declaration) {
1208                 auto& marginStyle = declaration.MaybeResetStyle<CommonMarginStyle>(StyleTag::COMMON_MARGIN_STYLE);
1209                 if (marginStyle.IsValid()) {
1210                     if (declaration.IsRightToLeft()) {
1211                         marginStyle.margin.SetLeft(declaration.ParseCalcDimension(value));
1212                     } else {
1213                         marginStyle.margin.SetRight(declaration.ParseCalcDimension(value));
1214                     }
1215                     declaration.hasBoxStyle_ = true;
1216                 }
1217             } },
1218         { DOM_MARGIN_LEFT,
1219             [](const std::string& value, Declaration& declaration) {
1220                 auto& marginStyle = declaration.MaybeResetStyle<CommonMarginStyle>(StyleTag::COMMON_MARGIN_STYLE);
1221                 if (marginStyle.IsValid()) {
1222                     marginStyle.margin.SetLeft(declaration.ParseCalcDimension(value));
1223                     declaration.hasBoxStyle_ = true;
1224                 }
1225             } },
1226         { DOM_MARGIN_RIGHT,
1227             [](const std::string& value, Declaration& declaration) {
1228                 auto& marginStyle = declaration.MaybeResetStyle<CommonMarginStyle>(StyleTag::COMMON_MARGIN_STYLE);
1229                 if (marginStyle.IsValid()) {
1230                     marginStyle.margin.SetRight(declaration.ParseCalcDimension(value));
1231                     declaration.hasBoxStyle_ = true;
1232                 }
1233             } },
1234         { DOM_MARGIN_START,
1235             [](const std::string& value, Declaration& declaration) {
1236                 auto& marginStyle = declaration.MaybeResetStyle<CommonMarginStyle>(StyleTag::COMMON_MARGIN_STYLE);
1237                 if (marginStyle.IsValid()) {
1238                     if (declaration.IsRightToLeft()) {
1239                         marginStyle.margin.SetRight(declaration.ParseCalcDimension(value));
1240                     } else {
1241                         marginStyle.margin.SetLeft(declaration.ParseCalcDimension(value));
1242                     }
1243                     declaration.hasBoxStyle_ = true;
1244                 }
1245             } },
1246         { DOM_MARGIN_TOP,
1247             [](const std::string& value, Declaration& declaration) {
1248                 auto& marginStyle = declaration.MaybeResetStyle<CommonMarginStyle>(StyleTag::COMMON_MARGIN_STYLE);
1249                 if (marginStyle.IsValid()) {
1250                     marginStyle.margin.SetTop(declaration.ParseCalcDimension(value));
1251                     declaration.hasBoxStyle_ = true;
1252                 }
1253             } },
1254         { DOM_MASK_IMAGE,
1255             [](const std::string& value, Declaration& declaration) {
1256                 auto& maskStyle = declaration.MaybeResetStyle<CommonMaskStyle>(StyleTag::COMMON_MASK_STYLE);
1257                 if (maskStyle.IsValid()) {
1258                     maskStyle.maskImage = value;
1259                 }
1260             } },
1261         { DOM_MASK_POSITION,
1262             [](const std::string& value, Declaration& declaration) {
1263                 auto& maskStyle = declaration.MaybeResetStyle<CommonMaskStyle>(StyleTag::COMMON_MASK_STYLE);
1264                 if (maskStyle.IsValid()) {
1265                     maskStyle.maskPosition = value;
1266                 }
1267             } },
1268         { DOM_MASK_SIZE,
1269             [](const std::string& value, Declaration& declaration) {
1270                 auto& maskStyle = declaration.MaybeResetStyle<CommonMaskStyle>(StyleTag::COMMON_MASK_STYLE);
1271                 if (maskStyle.IsValid()) {
1272                     maskStyle.maskSize = value;
1273                 }
1274             } },
1275         { DOM_MAX_HEIGHT,
1276             [](const std::string& value, Declaration& declaration) {
1277                 auto& sizeStyle = declaration.MaybeResetStyle<CommonSizeStyle>(StyleTag::COMMON_SIZE_STYLE);
1278                 if (sizeStyle.IsValid()) {
1279                     sizeStyle.maxHeight = declaration.ParseCalcDimension(value);
1280                 }
1281             } },
1282         { DOM_MAX_WIDTH,
1283             [](const std::string& value, Declaration& declaration) {
1284                 auto& sizeStyle = declaration.MaybeResetStyle<CommonSizeStyle>(StyleTag::COMMON_SIZE_STYLE);
1285                 if (sizeStyle.IsValid()) {
1286                     sizeStyle.maxWidth = declaration.ParseCalcDimension(value);
1287                 }
1288             } },
1289         { DOM_MIN_HEIGHT,
1290             [](const std::string& value, Declaration& declaration) {
1291                 auto& sizeStyle = declaration.MaybeResetStyle<CommonSizeStyle>(StyleTag::COMMON_SIZE_STYLE);
1292                 if (sizeStyle.IsValid()) {
1293                     sizeStyle.minHeight = declaration.ParseCalcDimension(value);
1294                 }
1295             } },
1296         { DOM_MIN_WIDTH,
1297             [](const std::string& value, Declaration& declaration) {
1298                 auto& sizeStyle = declaration.MaybeResetStyle<CommonSizeStyle>(StyleTag::COMMON_SIZE_STYLE);
1299                 if (sizeStyle.IsValid()) {
1300                     sizeStyle.minWidth = declaration.ParseCalcDimension(value);
1301                 }
1302             } },
1303         { DOM_OPACITY,
1304             [](const std::string& value, Declaration& declaration) {
1305                 auto& opacityStyle = declaration.MaybeResetStyle<CommonOpacityStyle>(StyleTag::COMMON_OPACITY_STYLE);
1306                 if (opacityStyle.IsValid()) {
1307                     opacityStyle.opacity = declaration.ParseDouble(value);
1308                     declaration.hasDisplayStyle_ = true;
1309                 }
1310             } },
1311         { DOM_OVERFLOW_STYLE,
1312             [](const std::string& value, Declaration& declaration) {
1313                 auto& overflowStyle = declaration.MaybeResetStyle<CommonOverflowStyle>(StyleTag::COMMON_OVERFLOW_STYLE);
1314                 if (overflowStyle.IsValid()) {
1315                     overflowStyle.overflow = ConvertStrToOverflow(value);
1316                     declaration.hasOverflowStyle_ = true;
1317                 }
1318             } },
1319         { DOM_SCROLL_OVER_SCROLL_EFFECT,
1320             [](const std::string& val, Declaration& declaration) {
1321                 auto& overflowStyle = declaration.MaybeResetStyle<CommonOverflowStyle>(StyleTag::COMMON_OVERFLOW_STYLE);
1322                 if (!overflowStyle.IsValid()) {
1323                     return;
1324                 }
1325                 if (val == DOM_SCROLL_EFFECT_SPRING) {
1326                     overflowStyle.edgeEffect = EdgeEffect::SPRING;
1327                 } else if (val == DOM_SCROLL_EFFECT_FADE) {
1328                     overflowStyle.edgeEffect = EdgeEffect::FADE;
1329                 } else {
1330                     overflowStyle.edgeEffect = EdgeEffect::NONE;
1331                 }
1332             } },
1333         { DOM_PADDING, &Declaration::SetPaddingOverall },
1334         { DOM_PADDING_BOTTOM,
1335             [](const std::string& value, Declaration& declaration) {
1336                 auto& paddingStyle = declaration.MaybeResetStyle<CommonPaddingStyle>(StyleTag::COMMON_PADDING_STYLE);
1337                 if (paddingStyle.IsValid()) {
1338                     paddingStyle.padding.SetBottom(declaration.ParseCalcDimension(value));
1339                     declaration.hasBoxStyle_ = true;
1340                 }
1341             } },
1342         { DOM_PADDING_END,
1343             [](const std::string& value, Declaration& declaration) {
1344                 auto& paddingStyle = declaration.MaybeResetStyle<CommonPaddingStyle>(StyleTag::COMMON_PADDING_STYLE);
1345                 if (paddingStyle.IsValid()) {
1346                     if (declaration.IsRightToLeft()) {
1347                         paddingStyle.padding.SetLeft(declaration.ParseCalcDimension(value));
1348                     } else {
1349                         paddingStyle.padding.SetRight(declaration.ParseCalcDimension(value));
1350                     }
1351                     declaration.hasBoxStyle_ = true;
1352                 }
1353             } },
1354         { DOM_PADDING_LEFT,
1355             [](const std::string& value, Declaration& declaration) {
1356                 auto& paddingStyle = declaration.MaybeResetStyle<CommonPaddingStyle>(StyleTag::COMMON_PADDING_STYLE);
1357                 if (paddingStyle.IsValid()) {
1358                     paddingStyle.padding.SetLeft(declaration.ParseCalcDimension(value));
1359                     declaration.hasBoxStyle_ = true;
1360                 }
1361             } },
1362         { DOM_PADDING_RIGHT,
1363             [](const std::string& value, Declaration& declaration) {
1364                 auto& paddingStyle = declaration.MaybeResetStyle<CommonPaddingStyle>(StyleTag::COMMON_PADDING_STYLE);
1365                 if (paddingStyle.IsValid()) {
1366                     paddingStyle.padding.SetRight(declaration.ParseCalcDimension(value));
1367                     declaration.hasBoxStyle_ = true;
1368                 }
1369             } },
1370         { DOM_PADDING_START,
1371             [](const std::string& value, Declaration& declaration) {
1372                 auto& paddingStyle = declaration.MaybeResetStyle<CommonPaddingStyle>(StyleTag::COMMON_PADDING_STYLE);
1373                 if (paddingStyle.IsValid()) {
1374                     if (declaration.IsRightToLeft()) {
1375                         paddingStyle.padding.SetRight(declaration.ParseCalcDimension(value));
1376                     } else {
1377                         paddingStyle.padding.SetLeft(declaration.ParseCalcDimension(value));
1378                     }
1379                     declaration.hasBoxStyle_ = true;
1380                 }
1381             } },
1382         { DOM_PADDING_TOP,
1383             [](const std::string& value, Declaration& declaration) {
1384                 auto& paddingStyle = declaration.MaybeResetStyle<CommonPaddingStyle>(StyleTag::COMMON_PADDING_STYLE);
1385                 if (paddingStyle.IsValid()) {
1386                     paddingStyle.padding.SetTop(declaration.ParseCalcDimension(value));
1387                     declaration.hasBoxStyle_ = true;
1388                 }
1389             } },
1390         { DOM_POSITION,
1391             [](const std::string& value, Declaration& declaration) {
1392                 auto& positionStyle = declaration.MaybeResetStyle<CommonPositionStyle>(StyleTag::COMMON_POSITION_STYLE);
1393                 if (positionStyle.IsValid() && !value.empty()) {
1394                     positionStyle.position =
1395                         value == DOM_POSITION_FIXED
1396                             ? PositionType::PTFIXED
1397                             : value == DOM_POSITION_ABSOLUTE ? PositionType::PTABSOLUTE : PositionType::PTRELATIVE;
1398                     declaration.hasPositionStyle_ = true;
1399                 }
1400             } },
1401         { DOM_POSITION_RIGHT,
1402             [](const std::string& value, Declaration& declaration) {
1403                 auto& positionStyle = declaration.MaybeResetStyle<CommonPositionStyle>(StyleTag::COMMON_POSITION_STYLE);
1404                 if (positionStyle.IsValid() && !value.empty()) {
1405                     positionStyle.right = declaration.ParseDimension(value);
1406                     declaration.hasPositionStyle_ = true;
1407                     declaration.hasRight_ = true;
1408                 }
1409             } },
1410         { DOM_SCROLL_SCROLLBAR_COLOR,
1411             [](const std::string& val, Declaration& declaration) {
1412                 auto& overflowStyle = declaration.MaybeResetStyle<CommonOverflowStyle>(StyleTag::COMMON_OVERFLOW_STYLE);
1413                 if (overflowStyle.IsValid()) {
1414                     overflowStyle.scrollBarColor.first = true;
1415                     overflowStyle.scrollBarColor.second = declaration.ParseColor(val);
1416                 }
1417             } },
1418         { DOM_SCROLL_SCROLLBAR_WIDTH,
1419             [](const std::string& val, Declaration& declaration) {
1420                 auto& overflowStyle = declaration.MaybeResetStyle<CommonOverflowStyle>(StyleTag::COMMON_OVERFLOW_STYLE);
1421                 if (overflowStyle.IsValid()) {
1422                     overflowStyle.scrollBarWidth.first = true;
1423                     auto width = declaration.ParseDimension(val);
1424                     overflowStyle.scrollBarWidth.second = width.IsValid() ? width : Dimension();
1425                 }
1426             } },
1427         { DOM_SHARED_TRANSITION_EFFECT,
1428             [](const std::string& value, Declaration& declaration) {
1429                 auto& shareTransitionStyle =
1430                     declaration.MaybeResetStyle<CommonShareTransitionStyle>(StyleTag::COMMON_SHARE_TRANSITION_STYLE);
1431                 if (shareTransitionStyle.IsValid()) {
1432                     shareTransitionStyle.sharedEffect = ParseSharedEffect(value, declaration);
1433                 }
1434             } },
1435         { DOM_SHARED_TRANSITION_TIMING_FUNCTION,
1436             [](const std::string& value, Declaration& declaration) {
1437                 auto& shareTransitionStyle =
1438                     declaration.MaybeResetStyle<CommonShareTransitionStyle>(StyleTag::COMMON_SHARE_TRANSITION_STYLE);
1439                 if (shareTransitionStyle.IsValid()) {
1440                     shareTransitionStyle.curve = CreateCurve(value);
1441                     shareTransitionStyle.sharedTransitionOption.SetCurve(shareTransitionStyle.curve);
1442                 }
1443             } },
1444         { DOM_POSITION_START,
1445             [](const std::string& value, Declaration& declaration) {
1446                 auto& positionStyle = declaration.MaybeResetStyle<CommonPositionStyle>(StyleTag::COMMON_POSITION_STYLE);
1447                 if (positionStyle.IsValid() && !value.empty()) {
1448                     if (declaration.IsRightToLeft()) {
1449                         positionStyle.right = declaration.ParseDimension(value);
1450                         declaration.hasRight_ = true;
1451                     } else {
1452                         positionStyle.left = declaration.ParseDimension(value);
1453                         declaration.hasLeft_ = true;
1454                     }
1455                     declaration.hasPositionStyle_ = true;
1456                 }
1457             } },
1458         { DOM_POSITION_TOP,
1459             [](const std::string& value, Declaration& declaration) {
1460                 auto& positionStyle = declaration.MaybeResetStyle<CommonPositionStyle>(StyleTag::COMMON_POSITION_STYLE);
1461                 if (positionStyle.IsValid() && !value.empty()) {
1462                     positionStyle.top = declaration.ParseDimension(value);
1463                     declaration.hasPositionStyle_ = true;
1464                     declaration.hasTop_ = true;
1465                 }
1466             } },
1467         { DOM_TRANSFORM_ORIGIN,
1468             [](const std::string& val, Declaration& declaration) {
1469                 declaration.hasTransformStyle_ = true;
1470                 auto& animationStyle =
1471                     declaration.MaybeResetStyle<CommonAnimationStyle>(StyleTag::COMMON_ANIMATION_STYLE);
1472                 if (!animationStyle.IsValid()) {
1473                     return;
1474                 }
1475 
1476                 std::vector<std::string> offsets;
1477                 StringUtils::StringSplitter(val, ' ', offsets);
1478                 if (offsets.size() == TRANSFORM_SINGLE) {
1479                     Dimension originDimensionX = TRANSFORM_ORIGIN_DEFAULT;
1480                     Dimension originDimensionY = TRANSFORM_ORIGIN_DEFAULT;
1481                     // for Enum
1482                     if (CheckTransformEnum(val)) {
1483                         auto resultX = ConvertStrToTransformOrigin(val, Axis::HORIZONTAL);
1484                         if (resultX.first) {
1485                             originDimensionX = resultX.second;
1486                         }
1487                         auto resultY = ConvertStrToTransformOrigin(val, Axis::VERTICAL);
1488                         if (resultY.first) {
1489                             originDimensionY = resultY.second;
1490                         }
1491                     } else {
1492                         // for Dimension
1493                         originDimensionX = declaration.ParseDimension(val);
1494                     }
1495                     animationStyle.tweenOption.SetTransformOrigin(originDimensionX, originDimensionY);
1496                     animationStyle.transformOriginX = originDimensionX;
1497                     animationStyle.transformOriginY = originDimensionY;
1498                 } else if (offsets.size() == TRANSFORM_DUAL) {
1499                     Dimension originDimensionX = TRANSFORM_ORIGIN_DEFAULT;
1500                     Dimension originDimensionY = TRANSFORM_ORIGIN_DEFAULT;
1501                     if (CheckTransformEnum(offsets[0])) {
1502                         auto result = ConvertStrToTransformOrigin(offsets[0], Axis::HORIZONTAL);
1503                         if (result.first) {
1504                             originDimensionX = result.second;
1505                         }
1506                     } else {
1507                         originDimensionX = declaration.ParseDimension(offsets[0]);
1508                     }
1509 
1510                     if (CheckTransformEnum(offsets[1])) {
1511                         auto result = ConvertStrToTransformOrigin(offsets[1], Axis::VERTICAL);
1512                         if (result.first) {
1513                             originDimensionY = result.second;
1514                         }
1515                     } else {
1516                         originDimensionY = declaration.ParseDimension(offsets[1]);
1517                     }
1518                     animationStyle.tweenOption.SetTransformOrigin(originDimensionX, originDimensionY);
1519                     animationStyle.transformOriginX = originDimensionX;
1520                     animationStyle.transformOriginY = originDimensionY;
1521                 }
1522                 declaration.hasTransformOriginStyle_ = true;
1523             } },
1524         { DOM_TRANSITION_DURATION,
1525             [](const std::string& value, Declaration& declaration) {
1526                 auto& pageTransitionStyle =
1527                     declaration.MaybeResetStyle<CommonPageTransitionStyle>(StyleTag::COMMON_PAGE_TRANSITION_STYLE);
1528                 if (pageTransitionStyle.IsValid()) {
1529                     if (value.find("ms") != std::string::npos) {
1530                         pageTransitionStyle.transitionDuration = StringUtils::StringToInt(value);
1531                     } else if (value.find('s') != std::string::npos) {
1532                         pageTransitionStyle.transitionDuration = StringUtils::StringToInt(value) * MS_TO_S;
1533                     } else {
1534                         // default unit is ms
1535                         pageTransitionStyle.transitionDuration = StringUtils::StringToInt(value);
1536                     }
1537                     pageTransitionStyle.transitionEnterOption.SetDuration(pageTransitionStyle.transitionDuration);
1538                     pageTransitionStyle.transitionExitOption.SetDuration(pageTransitionStyle.transitionDuration);
1539                 }
1540             } },
1541         // card transition
1542         { DOM_TRANSITION_EFFECT,
1543             [](const std::string& value, Declaration& declaration) {
1544                 declaration.hasTransitionAnimation_ = true;
1545                 auto& cardTransitionStyle =
1546                     declaration.MaybeResetStyle<CommonCardTransitionStyle>(StyleTag::COMMON_CARD_TRANSITION_STYLE);
1547                 if (cardTransitionStyle.IsValid()) {
1548                     declaration.hasTransformStyle_ = true;
1549                     cardTransitionStyle.transitionEffect = ParseTransitionEffect(value);
1550                 }
1551             } },
1552         { DOM_TRANSITION_TIMING_FUNCTION,
1553             [](const std::string& value, Declaration& declaration) {
1554                 auto& pageTransitionStyle =
1555                     declaration.MaybeResetStyle<CommonPageTransitionStyle>(StyleTag::COMMON_PAGE_TRANSITION_STYLE);
1556                 if (pageTransitionStyle.IsValid()) {
1557                     pageTransitionStyle.curve = CreateCurve(value);
1558                     pageTransitionStyle.transitionEnterOption.SetCurve(pageTransitionStyle.curve);
1559                     pageTransitionStyle.transitionExitOption.SetCurve(pageTransitionStyle.curve);
1560                 }
1561             } },
1562         { DOM_VISIBILITY,
1563             [](const std::string& value, Declaration& declaration) {
1564                 auto& visibilityStyle =
1565                     declaration.MaybeResetStyle<CommonVisibilityStyle>(StyleTag::COMMON_VISIBILITY_STYLE);
1566                 if (visibilityStyle.IsValid()) {
1567                     visibilityStyle.visibility =
1568                         (value == DOM_VISIBILITY_HIDDEN) ? VisibilityType::HIDDEN : VisibilityType::VISIBLE;
1569                     declaration.hasDisplayStyle_ = true;
1570                 }
1571             } },
1572         { DOM_WIDTH,
1573             [](const std::string& value, Declaration& declaration) {
1574                 auto& sizeStyle = declaration.MaybeResetStyle<CommonSizeStyle>(StyleTag::COMMON_SIZE_STYLE);
1575                 if (sizeStyle.IsValid()) {
1576                     sizeStyle.width = declaration.ParseCalcDimension(value);
1577                     declaration.hasBoxStyle_ = true;
1578                 }
1579             } },
1580         { DOM_WINDOW_FILTER,
1581             [](const std::string& value, Declaration& declaration) {
1582                 declaration.hasDecorationStyle_ = true;
1583                 std::vector<std::string> offsets;
1584                 StringUtils::StringSplitter(value, ' ', offsets);
1585                 // progress
1586                 if (offsets.size() >= 1) {
1587                     auto parseValue = ParseFunctionValue<Dimension>(offsets[0], DOM_BLUR, StringToDimension);
1588                     if (parseValue.Unit() == DimensionUnit::PERCENT) {
1589                         auto progress = parseValue.Value();
1590                         if (GreatNotEqual(progress, 0.0) && LessOrEqual(progress, 1.0)) {
1591                             declaration.backDecoration_->SetWindowBlurProgress(static_cast<float>(progress));
1592                         }
1593                     } else {
1594                         declaration.backDecoration_->SetWindowBlurProgress(static_cast<float>(0.0f));
1595                     }
1596                 }
1597                 // style
1598                 if (offsets.size() >= 2) {
1599                     auto windowBlurStyle = StrToWindowBlurStyle(offsets[1]);
1600                     declaration.backDecoration_->SetWindowBlurStyle(windowBlurStyle);
1601                 }
1602             } },
1603         { DOM_ZINDEX,
1604             [](const std::string& value, Declaration& declaration) {
1605                 auto& commonStyle = declaration.MaybeResetStyle<CommonStyle>(StyleTag::COMMON_STYLE);
1606                 if (commonStyle.IsValid()) {
1607                     commonStyle.zIndex = StringToInt(value);
1608                 }
1609             } },
1610     };
1611 
1612     auto operatorIter = BinarySearchFindIndex(styleSetter, ArraySize(styleSetter), style.first.c_str());
1613     if (operatorIter != -1) {
1614         styleSetter[operatorIter].value(style.second, *this);
1615     }
1616 
1617     auto& renderAttr = static_cast<CommonRenderAttribute&>(GetAttribute(AttributeTag::COMMON_RENDER_ATTR));
1618     static const std::unordered_set<std::string> displayStyleSet = { DOM_OPACITY, DOM_DISPLAY, DOM_VISIBILITY };
1619     if (displayStyleSet.find(style.first) != displayStyleSet.end() &&
1620         AceApplicationInfo::GetInstance().GetIsCardType() && renderAttr.show == "false") {
1621         SetShowAttr(renderAttr.show);
1622     }
1623 }
1624 
AddEvent(int32_t pageId,const std::string & eventId,const std::vector<std::string> & events)1625 void Declaration::AddEvent(int32_t pageId, const std::string& eventId, const std::vector<std::string>& events)
1626 {
1627     ACE_SCOPED_TRACE("Declaration::AddEvent");
1628     static const LinearMapNode<void (*)(int32_t, const std::string&, Declaration&)> eventSetters[] = {
1629         { DOM_BLUR,
1630             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1631                 auto& focusableEvent = declaration.MaybeResetEvent<CommonFocusEvent>(EventTag::COMMON_FOCUS_EVENT);
1632                 if (focusableEvent.IsValid()) {
1633                     focusableEvent.blur.eventMarker = EventMarker(eventId, DOM_BLUR, pageId);
1634                     focusableEvent.blur.isRefreshed = true;
1635                 }
1636             } },
1637         { DOM_CAPTURE_TOUCH_CANCEL,
1638             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1639                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1640                 if (rawEvent.IsValid()) {
1641                     rawEvent.captureTouchCancel.eventMarker = EventMarker(eventId, DOM_CAPTURE_TOUCH_CANCEL, pageId);
1642                     rawEvent.captureTouchCancel.isRefreshed = true;
1643                 }
1644             } },
1645         { DOM_CAPTURE_TOUCH_END,
1646             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1647                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1648                 if (rawEvent.IsValid()) {
1649                     rawEvent.captureTouchEnd.eventMarker = EventMarker(eventId, DOM_CAPTURE_TOUCH_END, pageId);
1650                     rawEvent.captureTouchEnd.isRefreshed = true;
1651                 }
1652             } },
1653         { DOM_CAPTURE_TOUCH_MOVE,
1654             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1655                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1656                 if (rawEvent.IsValid()) {
1657                     rawEvent.captureTouchMove.eventMarker = EventMarker(eventId, DOM_CAPTURE_TOUCH_MOVE, pageId);
1658                     rawEvent.captureTouchMove.isRefreshed = true;
1659                 }
1660             } },
1661         { DOM_CAPTURE_TOUCH_START,
1662             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1663                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1664                 if (rawEvent.IsValid()) {
1665                     rawEvent.captureTouchStart.eventMarker = EventMarker(eventId, DOM_CAPTURE_TOUCH_START, pageId);
1666                     rawEvent.captureTouchStart.isRefreshed = true;
1667                 }
1668             } },
1669         { DOM_CATCH_BUBBLE_CLICK,
1670             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1671                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1672                 if (gestureEvent.IsValid()) {
1673                     gestureEvent.click.eventMarker = EventMarker(eventId, DOM_CATCH_BUBBLE_CLICK, pageId);
1674                     gestureEvent.click.eventMarker.SetCatchMode(true);
1675                     gestureEvent.click.isRefreshed = true;
1676                 }
1677             } },
1678         { DOM_CATCH_BUBBLE_DOUBLE_CLICK,
1679             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1680                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1681                 if (gestureEvent.IsValid()) {
1682                     gestureEvent.doubleClick.eventMarker = EventMarker(eventId, DOM_CATCH_BUBBLE_DOUBLE_CLICK, pageId);
1683                     gestureEvent.doubleClick.eventMarker.SetCatchMode(true);
1684                     gestureEvent.doubleClick.isRefreshed = true;
1685                 }
1686             } },
1687         { DOM_CATCH_BUBBLE_LONG_PRESS,
1688             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1689                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1690                 if (gestureEvent.IsValid()) {
1691                     gestureEvent.longPress.eventMarker = EventMarker(eventId, DOM_CATCH_BUBBLE_LONG_PRESS, pageId);
1692                     gestureEvent.longPress.eventMarker.SetCatchMode(true);
1693                     gestureEvent.longPress.isRefreshed = true;
1694                 }
1695             } },
1696         { DOM_CATCH_BUBBLE_SWIPE,
1697             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1698                 auto& swipeEvent = declaration.MaybeResetEvent<CommonSwipeEvent>(EventTag::COMMON_SWIPE_EVENT);
1699                 if (swipeEvent.IsValid()) {
1700                     swipeEvent.catchBubbleSwipe.eventMarker = EventMarker(eventId, DOM_CATCH_BUBBLE_SWIPE, pageId);
1701                     swipeEvent.catchBubbleSwipe.isRefreshed = true;
1702                 }
1703             } },
1704         { DOM_CATCH_BUBBLE_TOUCH_CANCEL,
1705             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1706                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1707                 if (rawEvent.IsValid()) {
1708                     rawEvent.catchBubbleTouchCancel.eventMarker =
1709                         EventMarker(eventId, DOM_CATCH_BUBBLE_TOUCH_CANCEL, pageId);
1710                     rawEvent.catchBubbleTouchCancel.isRefreshed = true;
1711                 }
1712             } },
1713         { DOM_CATCH_BUBBLE_TOUCH_END,
1714             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1715                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1716                 if (rawEvent.IsValid()) {
1717                     rawEvent.catchBubbleTouchEnd.eventMarker = EventMarker(eventId, DOM_CATCH_BUBBLE_TOUCH_END, pageId);
1718                     rawEvent.catchBubbleTouchEnd.isRefreshed = true;
1719                 }
1720             } },
1721         { DOM_CATCH_BUBBLE_TOUCH_MOVE,
1722             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1723                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1724                 if (rawEvent.IsValid()) {
1725                     rawEvent.catchBubbleTouchMove.eventMarker =
1726                         EventMarker(eventId, DOM_CATCH_BUBBLE_TOUCH_MOVE, pageId);
1727                     rawEvent.catchBubbleTouchMove.isRefreshed = true;
1728                 }
1729             } },
1730         { DOM_CATCH_BUBBLE_TOUCH_START,
1731             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1732                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1733                 if (rawEvent.IsValid()) {
1734                     rawEvent.catchBubbleTouchStart.eventMarker =
1735                         EventMarker(eventId, DOM_CATCH_BUBBLE_TOUCH_START, pageId);
1736                     rawEvent.catchBubbleTouchStart.isRefreshed = true;
1737                 }
1738             } },
1739         { DOM_CATCH_CAPTURE_TOUCH_CANCEL,
1740             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1741                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1742                 if (rawEvent.IsValid()) {
1743                     rawEvent.catchCaptureTouchCancel.eventMarker =
1744                         EventMarker(eventId, DOM_CATCH_CAPTURE_TOUCH_CANCEL, pageId);
1745                     rawEvent.catchCaptureTouchCancel.isRefreshed = true;
1746                 }
1747             } },
1748         { DOM_CATCH_CAPTURE_TOUCH_END,
1749             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1750                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1751                 if (rawEvent.IsValid()) {
1752                     rawEvent.catchCaptureTouchEnd.eventMarker =
1753                         EventMarker(eventId, DOM_CATCH_CAPTURE_TOUCH_END, pageId);
1754                     rawEvent.catchCaptureTouchEnd.isRefreshed = true;
1755                 }
1756             } },
1757         { DOM_CATCH_CAPTURE_TOUCH_MOVE,
1758             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1759                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1760                 if (rawEvent.IsValid()) {
1761                     rawEvent.catchCaptureTouchMove.eventMarker =
1762                         EventMarker(eventId, DOM_CATCH_CAPTURE_TOUCH_MOVE, pageId);
1763                     rawEvent.catchCaptureTouchMove.isRefreshed = true;
1764                 }
1765             } },
1766         { DOM_CATCH_CAPTURE_TOUCH_START,
1767             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1768                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1769                 if (rawEvent.IsValid()) {
1770                     rawEvent.catchCaptureTouchStart.eventMarker =
1771                         EventMarker(eventId, DOM_CATCH_CAPTURE_TOUCH_START, pageId);
1772                     rawEvent.catchCaptureTouchStart.isRefreshed = true;
1773                 }
1774             } },
1775         { DOM_CLICK,
1776             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1777                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1778                 if (gestureEvent.IsValid()) {
1779                     gestureEvent.click.eventMarker = EventMarker(eventId, DOM_CLICK, pageId);
1780                     gestureEvent.click.eventMarker.SetCatchMode(false);
1781                     gestureEvent.click.isRefreshed = true;
1782                 }
1783             } },
1784         { DOM_DOUBLE_CLICK,
1785             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1786                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1787                 if (gestureEvent.IsValid()) {
1788                     gestureEvent.doubleClick.eventMarker = EventMarker(eventId, DOM_DOUBLE_CLICK, pageId);
1789                     gestureEvent.doubleClick.eventMarker.SetCatchMode(false);
1790                     gestureEvent.doubleClick.isRefreshed = true;
1791                 }
1792             } },
1793         { DOM_DRAG,
1794             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1795                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1796                 if (gestureEvent.IsValid()) {
1797                     gestureEvent.drag.eventMarker = EventMarker(eventId, DOM_DRAG, pageId);
1798                     gestureEvent.drag.isRefreshed = true;
1799                 }
1800             } },
1801         { DOM_DRAG_END,
1802             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1803                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1804                 if (gestureEvent.IsValid()) {
1805                     gestureEvent.dragEnd.eventMarker = EventMarker(eventId, DOM_DRAG_END, pageId);
1806                     gestureEvent.dragEnd.isRefreshed = true;
1807                 }
1808             } },
1809         { DOM_DRAG_ENTER,
1810             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1811                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1812                 if (gestureEvent.IsValid()) {
1813                     gestureEvent.dragEnter.eventMarker = EventMarker(eventId, DOM_DRAG_ENTER, pageId);
1814                     gestureEvent.dragEnter.isRefreshed = true;
1815                 }
1816             } },
1817         { DOM_DRAG_LEAVE,
1818             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1819                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1820                 if (gestureEvent.IsValid()) {
1821                     gestureEvent.dragLeave.eventMarker = EventMarker(eventId, DOM_DRAG_LEAVE, pageId);
1822                     gestureEvent.dragLeave.isRefreshed = true;
1823                 }
1824             } },
1825         { DOM_DRAG_OVER,
1826             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1827                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1828                 if (gestureEvent.IsValid()) {
1829                     gestureEvent.dragOver.eventMarker = EventMarker(eventId, DOM_DRAG_OVER, pageId);
1830                     gestureEvent.dragOver.isRefreshed = true;
1831                 }
1832             } },
1833         { DOM_DRAG_START,
1834             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1835                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1836                 if (gestureEvent.IsValid()) {
1837                     gestureEvent.dragStart.eventMarker = EventMarker(eventId, DOM_DRAG_START, pageId);
1838                     gestureEvent.dragStart.isRefreshed = true;
1839                 }
1840             } },
1841         { DOM_DRAG_DROP,
1842             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1843                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1844                 if (gestureEvent.IsValid()) {
1845                     gestureEvent.dragDrop.eventMarker = EventMarker(eventId, DOM_DRAG_DROP, pageId);
1846                     gestureEvent.dragDrop.isRefreshed = true;
1847                 }
1848             } },
1849         { DOM_FOCUS,
1850             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1851                 auto& focusEvent = declaration.MaybeResetEvent<CommonFocusEvent>(EventTag::COMMON_FOCUS_EVENT);
1852                 if (focusEvent.IsValid()) {
1853                     focusEvent.focus.eventMarker = EventMarker(eventId, DOM_FOCUS, pageId);
1854                     focusEvent.focus.isRefreshed = true;
1855                 }
1856             } },
1857         { DOM_HOVER,
1858             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1859                 auto& mouseEvent = declaration.MaybeResetEvent<CommonMouseEvent>(EventTag::COMMON_MOUSE_EVENT);
1860                 if (mouseEvent.IsValid()) {
1861                     mouseEvent.mouseHover.eventMarker = EventMarker(eventId, DOM_HOVER, pageId);
1862                     mouseEvent.mouseHover.isRefreshed = true;
1863                 }
1864             } },
1865         { DOM_KEY,
1866             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1867                 auto& keyEvent = declaration.MaybeResetEvent<CommonKeyEvent>(EventTag::COMMON_KEY_EVENT);
1868                 if (keyEvent.IsValid()) {
1869                     keyEvent.key.eventMarker = EventMarker(eventId, DOM_KEY, pageId);
1870                     keyEvent.key.isRefreshed = true;
1871                 }
1872             } },
1873         { DOM_LONG_PRESS,
1874             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1875                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1876                 if (gestureEvent.IsValid()) {
1877                     gestureEvent.longPress.eventMarker = EventMarker(eventId, DOM_LONG_PRESS, pageId);
1878                     gestureEvent.longPress.eventMarker.SetCatchMode(false);
1879                     gestureEvent.longPress.isRefreshed = true;
1880                 }
1881             } },
1882         { DOM_MOUSE,
1883             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1884                 auto& mouseEvent = declaration.MaybeResetEvent<CommonMouseEvent>(EventTag::COMMON_MOUSE_EVENT);
1885                 if (mouseEvent.IsValid()) {
1886                     mouseEvent.mouse.eventMarker = EventMarker(eventId, DOM_MOUSE, pageId);
1887                     mouseEvent.mouse.isRefreshed = true;
1888                 }
1889             } },
1890         { DOM_PINCH_CANCEL,
1891             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1892                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1893                 if (gestureEvent.IsValid()) {
1894                     gestureEvent.pinchCancel.eventMarker = EventMarker(eventId, DOM_PINCH_CANCEL, pageId);
1895                     gestureEvent.pinchCancel.isRefreshed = true;
1896                 }
1897             } },
1898         { DOM_PINCH_END,
1899             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1900                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1901                 if (gestureEvent.IsValid()) {
1902                     gestureEvent.pinchEnd.eventMarker = EventMarker(eventId, DOM_PINCH_END, pageId);
1903                     gestureEvent.pinchEnd.isRefreshed = true;
1904                 }
1905             } },
1906         { DOM_PINCH_START,
1907             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1908                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1909                 if (gestureEvent.IsValid()) {
1910                     gestureEvent.pinchStart.eventMarker = EventMarker(eventId, DOM_PINCH_START, pageId);
1911                     gestureEvent.pinchStart.isRefreshed = true;
1912                 }
1913             } },
1914         { DOM_PINCH_UPDATE,
1915             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1916                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1917                 if (gestureEvent.IsValid()) {
1918                     gestureEvent.pinchUpdate.eventMarker = EventMarker(eventId, DOM_PINCH_UPDATE, pageId);
1919                     gestureEvent.pinchUpdate.isRefreshed = true;
1920                 }
1921             } },
1922         { DOM_CROWN_ROTATE,
1923             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1924                 auto& crownEvent = declaration.MaybeResetEvent<CommonCrownEvent>(EventTag::COMMON_CROWN_EVENT);
1925                 if (crownEvent.IsValid()) {
1926                     crownEvent.rotate.eventMarker = EventMarker(eventId, DOM_CROWN_ROTATE, pageId);
1927                     crownEvent.rotate.isRefreshed = true;
1928                 }
1929             } },
1930         { DOM_SWIPE,
1931             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1932                 auto& swipeEvent = declaration.MaybeResetEvent<CommonSwipeEvent>(EventTag::COMMON_SWIPE_EVENT);
1933                 if (swipeEvent.IsValid()) {
1934                     swipeEvent.swipe.eventMarker = EventMarker(eventId, DOM_SWIPE, pageId);
1935                     swipeEvent.swipe.eventMarker.SetCatchMode(false);
1936                     swipeEvent.swipe.isRefreshed = true;
1937                 }
1938             } },
1939         { DOM_TOUCH_CANCEL,
1940             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1941                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1942                 if (rawEvent.IsValid()) {
1943                     rawEvent.touchCancel.eventMarker = EventMarker(eventId, DOM_TOUCH_CANCEL, pageId);
1944                     rawEvent.touchCancel.isRefreshed = true;
1945                 }
1946             } },
1947         { DOM_TOUCH_END,
1948             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1949                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1950                 if (rawEvent.IsValid()) {
1951                     rawEvent.touchEnd.eventMarker = EventMarker(eventId, DOM_TOUCH_END, pageId);
1952                     rawEvent.touchEnd.isRefreshed = true;
1953                 }
1954             } },
1955         { DOM_TOUCH_MOVE,
1956             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1957                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1958                 if (rawEvent.IsValid()) {
1959                     rawEvent.touchMove.eventMarker = EventMarker(eventId, DOM_TOUCH_MOVE, pageId);
1960                     rawEvent.touchMove.isRefreshed = true;
1961                 }
1962             } },
1963         { DOM_TOUCH_START,
1964             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1965                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1966                 if (rawEvent.IsValid()) {
1967                     rawEvent.touchStart.eventMarker = EventMarker(eventId, DOM_TOUCH_START, pageId);
1968                     rawEvent.touchStart.isRefreshed = true;
1969                 }
1970             } },
1971     };
1972     for (const auto& event : events) {
1973         if (SetSpecializedEvent(pageId, eventId, event)) {
1974             continue;
1975         }
1976         auto setterIter = BinarySearchFindIndex(eventSetters, ArraySize(eventSetters), event.c_str());
1977         if (setterIter != -1) {
1978             eventSetters[setterIter].value(pageId, eventId, *this);
1979         }
1980     }
1981 }
1982 
CallMethod(const std::string & method,const std::string & args)1983 void Declaration::CallMethod(const std::string& method, const std::string& args)
1984 {
1985     if (method == COMMON_METHOD_FOCUS) {
1986         if (!focusableController_) {
1987             LOGE("CallMethod: call focus method failed, focusableController_ is null");
1988             return;
1989         }
1990 
1991         bool shouldFocus = true;
1992         std::unique_ptr<JsonValue> argsValue = JsonUtil::ParseJsonString(args);
1993         if (argsValue && argsValue->IsArray() && argsValue->GetArraySize() == COMMON_METHOD_FOCUS_ARGS_SIZE) {
1994             std::unique_ptr<JsonValue> focusValue = argsValue->GetArrayItem(0)->GetValue(COMMON_METHOD_FOCUS);
1995             if (focusValue && focusValue->IsBool()) {
1996                 shouldFocus = focusValue->GetBool();
1997             }
1998         }
1999         OnRequestFocus(shouldFocus);
2000     } else if (method == DOM_LIST_METHOD_SCROLL_BY) {
2001         std::unique_ptr<JsonValue> argsValue = JsonUtil::ParseJsonString(args);
2002         if (!argsValue || !argsValue->IsArray() || argsValue->GetArraySize() != 1) {
2003             LOGE("parse args error");
2004             return;
2005         }
2006         std::unique_ptr<JsonValue> scrollByPara = argsValue->GetArrayItem(0);
2007         double x = scrollByPara->GetDouble("dx", 0.0);
2008         double y = scrollByPara->GetDouble("dy", 0.0);
2009         bool isSmooth = scrollByPara->GetBool("smooth", true);
2010         OnScrollBy(x, y, isSmooth);
2011     } else {
2012         CallSpecializedMethod(method, args);
2013     }
2014 }
2015 
OnRequestFocus(bool shouldFocus)2016 void Declaration::OnRequestFocus(bool shouldFocus)
2017 {
2018     auto& commonMethod = MaybeResetMethod<CommonMethod>(MethodTag::COMMON_METHOD);
2019     if (commonMethod.IsValid()) {
2020         commonMethod.Focus(focusableController_, shouldFocus);
2021     }
2022 }
2023 
OnScrollBy(double dx,double dy,bool isSmooth)2024 void Declaration::OnScrollBy(double dx, double dy, bool isSmooth)
2025 {
2026     auto& commonMethod = MaybeResetMethod<CommonMethod>(MethodTag::COMMON_METHOD);
2027     if (commonMethod.IsValid()) {
2028         commonMethod.ScrollBy(positionController_, dx, dy, isSmooth);
2029     }
2030 }
2031 
SetPaddingOverall(const std::string & value,Declaration & declaration)2032 void Declaration::SetPaddingOverall(const std::string& value, Declaration& declaration)
2033 {
2034     auto& paddingStyle = declaration.MaybeResetStyle<CommonPaddingStyle>(StyleTag::COMMON_PADDING_STYLE);
2035     if (!paddingStyle.IsValid()) {
2036         return;
2037     }
2038 
2039     std::vector<std::string> offsets;
2040     StringUtils::StringSplitter(value, ' ', offsets);
2041     switch (offsets.size()) {
2042         case 1:
2043             paddingStyle.padding.SetLeft(declaration.ParseDimension(offsets[0]));
2044             paddingStyle.padding.SetRight(declaration.ParseDimension(offsets[0]));
2045             paddingStyle.padding.SetTop(declaration.ParseDimension(offsets[0]));
2046             paddingStyle.padding.SetBottom(declaration.ParseDimension(offsets[0]));
2047             break;
2048         case 2:
2049             paddingStyle.padding.SetLeft(declaration.ParseDimension(offsets[1]));
2050             paddingStyle.padding.SetRight(declaration.ParseDimension(offsets[1]));
2051             paddingStyle.padding.SetTop(declaration.ParseDimension(offsets[0]));
2052             paddingStyle.padding.SetBottom(declaration.ParseDimension(offsets[0]));
2053             break;
2054         case 3:
2055             paddingStyle.padding.SetLeft(declaration.ParseDimension(offsets[1]));
2056             paddingStyle.padding.SetRight(declaration.ParseDimension(offsets[1]));
2057             paddingStyle.padding.SetTop(declaration.ParseDimension(offsets[0]));
2058             paddingStyle.padding.SetBottom(declaration.ParseDimension(offsets[2]));
2059             break;
2060         case 4:
2061             paddingStyle.padding.SetLeft(declaration.ParseDimension(offsets[3]));
2062             paddingStyle.padding.SetRight(declaration.ParseDimension(offsets[1]));
2063             paddingStyle.padding.SetTop(declaration.ParseDimension(offsets[0]));
2064             paddingStyle.padding.SetBottom(declaration.ParseDimension(offsets[2]));
2065             break;
2066         default:
2067             break;
2068     }
2069     declaration.hasBoxStyle_ = true;
2070 }
2071 
SetMarginOverall(const std::string & value,Declaration & declaration)2072 void Declaration::SetMarginOverall(const std::string& value, Declaration& declaration)
2073 {
2074     auto& marginStyle = declaration.MaybeResetStyle<CommonMarginStyle>(StyleTag::COMMON_MARGIN_STYLE);
2075     if (!marginStyle.IsValid()) {
2076         return;
2077     }
2078 
2079     std::vector<std::string> offsets;
2080     StringUtils::StringSplitter(value, ' ', offsets);
2081     switch (offsets.size()) {
2082         case 1:
2083             marginStyle.margin.SetLeft(declaration.ParseDimension(offsets[0]));
2084             marginStyle.margin.SetRight(declaration.ParseDimension(offsets[0]));
2085             marginStyle.margin.SetTop(declaration.ParseDimension(offsets[0]));
2086             marginStyle.margin.SetBottom(declaration.ParseDimension(offsets[0]));
2087             break;
2088         case 2:
2089             marginStyle.margin.SetLeft(declaration.ParseDimension(offsets[1]));
2090             marginStyle.margin.SetRight(declaration.ParseDimension(offsets[1]));
2091             marginStyle.margin.SetTop(declaration.ParseDimension(offsets[0]));
2092             marginStyle.margin.SetBottom(declaration.ParseDimension(offsets[0]));
2093             break;
2094         case 3:
2095             marginStyle.margin.SetLeft(declaration.ParseDimension(offsets[1]));
2096             marginStyle.margin.SetRight(declaration.ParseDimension(offsets[1]));
2097             marginStyle.margin.SetTop(declaration.ParseDimension(offsets[0]));
2098             marginStyle.margin.SetBottom(declaration.ParseDimension(offsets[2]));
2099             break;
2100         case 4:
2101             marginStyle.margin.SetLeft(declaration.ParseDimension(offsets[3]));
2102             marginStyle.margin.SetRight(declaration.ParseDimension(offsets[1]));
2103             marginStyle.margin.SetTop(declaration.ParseDimension(offsets[0]));
2104             marginStyle.margin.SetBottom(declaration.ParseDimension(offsets[2]));
2105             break;
2106         default:
2107             break;
2108     }
2109     declaration.hasBoxStyle_ = true;
2110 }
2111 
SetBorderImageWidthForFourEdges(const std::string & value,Declaration & declaration)2112 void Declaration::SetBorderImageWidthForFourEdges(const std::string& value, Declaration& declaration)
2113 {
2114     auto& bgStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2115     if (!bgStyle.IsValid()) {
2116         return;
2117     }
2118     std::vector<std::string> offsets;
2119     StringUtils::StringSplitter(value, ' ', offsets);
2120     switch (offsets.size()) {
2121         case 1:
2122             bgStyle.borderImage->SetEdgeWidth(BorderImageDirection::TOP, declaration.ParseDimension(offsets[0]));
2123             bgStyle.borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, declaration.ParseDimension(offsets[0]));
2124             bgStyle.borderImage->SetEdgeWidth(BorderImageDirection::LEFT, declaration.ParseDimension(offsets[0]));
2125             bgStyle.borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, declaration.ParseDimension(offsets[0]));
2126             declaration.backDecoration_->SetHasBorderImageWidth(true);
2127             break;
2128         case 2:
2129             bgStyle.borderImage->SetEdgeWidth(BorderImageDirection::TOP, declaration.ParseDimension(offsets[0]));
2130             bgStyle.borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, declaration.ParseDimension(offsets[0]));
2131             bgStyle.borderImage->SetEdgeWidth(BorderImageDirection::LEFT, declaration.ParseDimension(offsets[1]));
2132             bgStyle.borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, declaration.ParseDimension(offsets[1]));
2133             declaration.backDecoration_->SetHasBorderImageWidth(true);
2134             break;
2135         case 3:
2136             bgStyle.borderImage->SetEdgeWidth(BorderImageDirection::TOP, declaration.ParseDimension(offsets[0]));
2137             bgStyle.borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, declaration.ParseDimension(offsets[2]));
2138             bgStyle.borderImage->SetEdgeWidth(BorderImageDirection::LEFT, declaration.ParseDimension(offsets[1]));
2139             bgStyle.borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, declaration.ParseDimension(offsets[1]));
2140             declaration.backDecoration_->SetHasBorderImageWidth(true);
2141             break;
2142         case 4:
2143             bgStyle.borderImage->SetEdgeWidth(BorderImageDirection::TOP, declaration.ParseDimension(offsets[0]));
2144             bgStyle.borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, declaration.ParseDimension(offsets[1]));
2145             bgStyle.borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, declaration.ParseDimension(offsets[2]));
2146             bgStyle.borderImage->SetEdgeWidth(BorderImageDirection::LEFT, declaration.ParseDimension(offsets[3]));
2147             declaration.backDecoration_->SetHasBorderImageWidth(true);
2148             break;
2149         default:
2150             bgStyle.borderImage->SetEdgeWidth(BorderImageDirection::TOP, declaration.ParseDimension(value));
2151             bgStyle.borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, declaration.ParseDimension(value));
2152             bgStyle.borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, declaration.ParseDimension(value));
2153             bgStyle.borderImage->SetEdgeWidth(BorderImageDirection::LEFT, declaration.ParseDimension(value));
2154             declaration.backDecoration_->SetHasBorderImageWidth(false);
2155             break;
2156     }
2157     declaration.backDecoration_->SetBorderImage(bgStyle.borderImage);
2158     declaration.hasDecorationStyle_ = true;
2159     declaration.hasBorderStyle_ = true;
2160 }
2161 
SetBorderImageSliceForFourEdges(const std::string & value,Declaration & declaration)2162 void Declaration::SetBorderImageSliceForFourEdges(const std::string& value, Declaration& declaration)
2163 {
2164     auto& bgStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2165     if (!bgStyle.IsValid()) {
2166         return;
2167     }
2168     std::vector<std::string> offsets;
2169     StringUtils::StringSplitter(value, ' ', offsets);
2170     switch (offsets.size()) {
2171         case 1:
2172             bgStyle.borderImage->SetEdgeSlice(BorderImageDirection::LEFT, declaration.ParseDimension(offsets[0]));
2173             bgStyle.borderImage->SetEdgeSlice(BorderImageDirection::TOP, declaration.ParseDimension(offsets[0]));
2174             bgStyle.borderImage->SetEdgeSlice(BorderImageDirection::RIGHT, declaration.ParseDimension(offsets[0]));
2175             bgStyle.borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, declaration.ParseDimension(offsets[0]));
2176             declaration.backDecoration_->SetHasBorderImageSlice(true);
2177             break;
2178         case 2:
2179             bgStyle.borderImage->SetEdgeSlice(BorderImageDirection::LEFT, declaration.ParseDimension(offsets[1]));
2180             bgStyle.borderImage->SetEdgeSlice(BorderImageDirection::TOP, declaration.ParseDimension(offsets[0]));
2181             bgStyle.borderImage->SetEdgeSlice(BorderImageDirection::RIGHT, declaration.ParseDimension(offsets[1]));
2182             bgStyle.borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, declaration.ParseDimension(offsets[0]));
2183             declaration.backDecoration_->SetHasBorderImageSlice(true);
2184             break;
2185         case 3:
2186             bgStyle.borderImage->SetEdgeSlice(BorderImageDirection::LEFT, declaration.ParseDimension(offsets[1]));
2187             bgStyle.borderImage->SetEdgeSlice(BorderImageDirection::TOP, declaration.ParseDimension(offsets[0]));
2188             bgStyle.borderImage->SetEdgeSlice(BorderImageDirection::RIGHT, declaration.ParseDimension(offsets[1]));
2189             bgStyle.borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, declaration.ParseDimension(offsets[2]));
2190             declaration.backDecoration_->SetHasBorderImageSlice(true);
2191             break;
2192         case 4:
2193             bgStyle.borderImage->SetEdgeSlice(BorderImageDirection::LEFT, declaration.ParseDimension(offsets[3]));
2194             bgStyle.borderImage->SetEdgeSlice(BorderImageDirection::TOP, declaration.ParseDimension(offsets[0]));
2195             bgStyle.borderImage->SetEdgeSlice(BorderImageDirection::RIGHT, declaration.ParseDimension(offsets[1]));
2196             bgStyle.borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, declaration.ParseDimension(offsets[2]));
2197             declaration.backDecoration_->SetHasBorderImageSlice(true);
2198             break;
2199         default:
2200             bgStyle.borderImage->SetEdgeSlice(BorderImageDirection::LEFT, declaration.ParseDimension(value));
2201             bgStyle.borderImage->SetEdgeSlice(BorderImageDirection::TOP, declaration.ParseDimension(value));
2202             bgStyle.borderImage->SetEdgeSlice(BorderImageDirection::RIGHT, declaration.ParseDimension(value));
2203             bgStyle.borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, declaration.ParseDimension(value));
2204             declaration.backDecoration_->SetHasBorderImageSlice(false);
2205             break;
2206     }
2207     declaration.backDecoration_->SetBorderImage(bgStyle.borderImage);
2208     declaration.hasDecorationStyle_ = true;
2209     declaration.hasBorderStyle_ = true;
2210 }
2211 
SetBorderImageOutSetForFourEdges(const std::string & value,Declaration & declaration)2212 void Declaration::SetBorderImageOutSetForFourEdges(const std::string& value, Declaration& declaration)
2213 {
2214     auto& bgStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2215     if (!bgStyle.IsValid()) {
2216         return;
2217     }
2218     std::vector<std::string> offsets;
2219     StringUtils::StringSplitter(value, ' ', offsets);
2220     switch (offsets.size()) {
2221         case 1:
2222             bgStyle.borderImage->SetEdgeOutset(BorderImageDirection::TOP, declaration.ParseDimension(offsets[0]));
2223             bgStyle.borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, declaration.ParseDimension(offsets[0]));
2224             bgStyle.borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, declaration.ParseDimension(offsets[0]));
2225             bgStyle.borderImage->SetEdgeOutset(BorderImageDirection::LEFT, declaration.ParseDimension(offsets[0]));
2226             declaration.backDecoration_->SetHasBorderImageOutset(true);
2227             break;
2228         case 2:
2229             bgStyle.borderImage->SetEdgeOutset(BorderImageDirection::TOP, declaration.ParseDimension(offsets[0]));
2230             bgStyle.borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, declaration.ParseDimension(offsets[1]));
2231             bgStyle.borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, declaration.ParseDimension(offsets[0]));
2232             bgStyle.borderImage->SetEdgeOutset(BorderImageDirection::LEFT, declaration.ParseDimension(offsets[1]));
2233             declaration.backDecoration_->SetHasBorderImageOutset(true);
2234             break;
2235         case 3:
2236             bgStyle.borderImage->SetEdgeOutset(BorderImageDirection::TOP, declaration.ParseDimension(offsets[0]));
2237             bgStyle.borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, declaration.ParseDimension(offsets[1]));
2238             bgStyle.borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, declaration.ParseDimension(offsets[2]));
2239             bgStyle.borderImage->SetEdgeOutset(BorderImageDirection::LEFT, declaration.ParseDimension(offsets[1]));
2240             declaration.backDecoration_->SetHasBorderImageOutset(true);
2241             break;
2242         case 4:
2243             bgStyle.borderImage->SetEdgeOutset(BorderImageDirection::TOP, declaration.ParseDimension(offsets[0]));
2244             bgStyle.borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, declaration.ParseDimension(offsets[1]));
2245             bgStyle.borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, declaration.ParseDimension(offsets[2]));
2246             bgStyle.borderImage->SetEdgeOutset(BorderImageDirection::LEFT, declaration.ParseDimension(offsets[3]));
2247             declaration.backDecoration_->SetHasBorderImageOutset(true);
2248             break;
2249         default:
2250             bgStyle.borderImage->SetEdgeOutset(BorderImageDirection::TOP, declaration.ParseDimension(value));
2251             bgStyle.borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, declaration.ParseDimension(value));
2252             bgStyle.borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, declaration.ParseDimension(value));
2253             bgStyle.borderImage->SetEdgeOutset(BorderImageDirection::LEFT, declaration.ParseDimension(value));
2254             declaration.backDecoration_->SetHasBorderImageOutset(false);
2255             break;
2256     }
2257     declaration.backDecoration_->SetBorderImage(bgStyle.borderImage);
2258     declaration.hasDecorationStyle_ = true;
2259     declaration.hasBorderStyle_ = true;
2260 }
2261 
SetBorderImageRepeatForFourEdges(const std::string & value,Declaration & declaration)2262 void Declaration::SetBorderImageRepeatForFourEdges(const std::string& value, Declaration& declaration)
2263 {
2264     auto& bgStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2265     if (bgStyle.IsValid()) {
2266         bgStyle.borderImage->SetRepeatMode(ConvertStrToBorderImageRepeat(value));
2267         declaration.backDecoration_->SetBorderImage(bgStyle.borderImage);
2268         declaration.backDecoration_->SetHasBorderImageRepeat(true);
2269         declaration.hasDecorationStyle_ = true;
2270         declaration.hasBorderStyle_ = true;
2271     }
2272 }
2273 
SetBorderImage(const std::string & value,Declaration & declaration)2274 void Declaration::SetBorderImage(const std::string& value, Declaration& declaration)
2275 {
2276     declaration.backDecoration_->SetHasBorderImageSource(false);
2277     declaration.backDecoration_->SetHasBorderImageGradient(false);
2278 
2279     auto borderImageJson = JsonUtil::ParseJsonString(value);
2280     if (!borderImageJson->IsObject()) {
2281         LOGE("borderImageJson json is not Object");
2282         return;
2283     }
2284     if (borderImageJson->Contains(DOM_VALUES) && borderImageJson->GetValue(DOM_VALUES)->IsArray() &&
2285         borderImageJson->GetValue(DOM_VALUES)->GetArraySize() > 0) {
2286 
2287         auto values = borderImageJson->GetValue(DOM_VALUES)->GetArrayItem(0);
2288 
2289         if (values->Contains("url")) {
2290             SetBorderImageUrl(values, declaration);
2291         } else {
2292             SetBorderImageGradient(values, declaration);
2293         }
2294     }
2295 }
2296 
SetBorderImageGradient(const std::unique_ptr<JsonValue> & values,Declaration & declaration)2297 void Declaration::SetBorderImageGradient(const std::unique_ptr<JsonValue>& values, Declaration& declaration)
2298 {
2299     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2300     backgroundStyle.gradientBorderImage = Gradient();
2301     if (values->Contains(DOM_GRADIENT_TYPE) && values->GetValue(DOM_GRADIENT_TYPE)->IsString()) {
2302         SetBorderImageGradientType(values->GetValue(DOM_GRADIENT_TYPE)->GetString(), declaration);
2303     }
2304     if (values->Contains(DOM_GRADIENT_DIRECTIONS) && values->GetValue(DOM_GRADIENT_DIRECTIONS)->IsArray()) {
2305         SetBorderImageGradientDirections(values->GetValue(DOM_GRADIENT_DIRECTIONS), declaration);
2306     }
2307     if (values->Contains(DOM_GRADIENT_VALUES) && values->GetValue(DOM_GRADIENT_VALUES)->IsArray()) {
2308         SetBorderImageGradientColor(values->GetValue(DOM_GRADIENT_VALUES), declaration);
2309     }
2310     if (values->Contains("slice") && values->GetValue("slice")->IsArray()) {
2311         std::unique_ptr<JsonValue> sliceItem = values->GetValue("slice");
2312         std::string sliceStr;
2313         for (int32_t i = 0; i < sliceItem->GetArraySize(); i++) {
2314             sliceStr += sliceItem->GetArrayItem(i)->GetString() + " ";
2315         }
2316         SetBorderImageSliceForFourEdges(sliceStr, declaration);
2317     }
2318     declaration.backDecoration_->SetHasBorderImageGradient(true);
2319     declaration.hasDecorationStyle_ = true;
2320     declaration.hasBorderStyle_ = true;
2321 }
2322 
SetBorderImageUrl(const std::unique_ptr<JsonValue> & values,Declaration & declaration)2323 void Declaration::SetBorderImageUrl(const std::unique_ptr<JsonValue>& values, Declaration& declaration)
2324 {
2325     if (values->Contains("url") && values->GetValue("url")->IsString()) {
2326         SetBorderImageFindUrl(values->GetValue("url")->GetString(), declaration);
2327     }
2328     if (values->Contains("slice") && values->GetValue("slice")->IsArray()) {
2329         std::unique_ptr<JsonValue> sliceItem = values->GetValue("slice");
2330         std::string sliceStr;
2331         for (int32_t i = 0; i < sliceItem->GetArraySize(); i++) {
2332             sliceStr += sliceItem->GetArrayItem(i)->GetString() + " ";
2333         }
2334         SetBorderImageSliceForFourEdges(sliceStr, declaration);
2335     }
2336     if (values->Contains("width") && values->GetValue("width")->IsArray()) {
2337         std::unique_ptr<JsonValue> widthItem = values->GetValue("width");
2338 
2339         std::string widthStr;
2340         for (int32_t i = 0; i < widthItem->GetArraySize(); i++) {
2341             widthStr += widthItem->GetArrayItem(i)->GetString() + " ";
2342         }
2343         SetBorderImageWidthForFourEdges(widthStr, declaration);
2344     }
2345     if (values->Contains("outset") && values->GetValue("outset")->IsArray()) {
2346         std::unique_ptr<JsonValue> outsetItem = values->GetValue("outset");
2347 
2348         std::string outsetStr;
2349         for (int32_t i = 0; i < outsetItem->GetArraySize(); i++) {
2350             outsetStr += outsetItem->GetArrayItem(i)->GetString() + " ";
2351         }
2352         SetBorderImageOutSetForFourEdges(outsetStr, declaration);
2353     }
2354     if (values->Contains("repeat") && values->GetValue("repeat")->IsString()) {
2355         SetBorderImageRepeatForFourEdges(values->GetValue("repeat")->GetString(), declaration);
2356     }
2357     declaration.hasDecorationStyle_ = true;
2358     declaration.hasBorderStyle_ = true;
2359 }
2360 
SetBorderImageFindUrl(const std::string & value,Declaration & declaration)2361 void Declaration::SetBorderImageFindUrl(const std::string& value, Declaration& declaration)
2362 {
2363     auto& backgroundStyle =
2364                     declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2365     if (backgroundStyle.IsValid()) {
2366         backgroundStyle.borderImage->SetSrc(value);
2367         declaration.backDecoration_->SetBorderImage(backgroundStyle.borderImage);
2368         declaration.backDecoration_->SetHasBorderImageSource(true);
2369         declaration.hasDecorationStyle_ = true;
2370     }
2371 }
2372 
SetBorderImageGradientType(const std::string & gradientType,Declaration & declaration)2373 void Declaration::SetBorderImageGradientType(const std::string& gradientType, Declaration& declaration)
2374 {
2375     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2376     if (!backgroundStyle.IsValid()) {
2377         return;
2378     }
2379     // default: LINEAR
2380     backgroundStyle.gradientBorderImage.SetType(GradientType::LINEAR);
2381     if (gradientType == DOM_RADIAL_GRADIENT || gradientType == DOM_REPEATING_RADIAL_GRADIENT) {
2382         backgroundStyle.gradientBorderImage.SetType(GradientType::RADIAL);
2383     } else if (gradientType == DOM_SWEEP_GRADIENT || gradientType == DOM_REPEATING_SWEEP_GRADIENT) {
2384         backgroundStyle.gradientBorderImage.SetType(GradientType::SWEEP);
2385     }
2386 
2387     if (gradientType == DOM_REPEATING_LINEAR_GRADIENT || gradientType == DOM_REPEATING_RADIAL_GRADIENT ||
2388         gradientType == DOM_REPEATING_SWEEP_GRADIENT) {
2389         backgroundStyle.gradientBorderImage.SetRepeat(true);
2390     }
2391     declaration.hasDecorationStyle_ = true;
2392 }
2393 
SetBorderImageGradientDirections(const std::unique_ptr<JsonValue> & gradientDirections,Declaration & declaration)2394 void Declaration::SetBorderImageGradientDirections(const std::unique_ptr<JsonValue>& gradientDirections,
2395     Declaration& declaration)
2396 {
2397     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2398     if (!backgroundStyle.IsValid()) {
2399         return;
2400     }
2401 
2402     std::unique_ptr<JsonValue> angleItem;
2403     std::unique_ptr<JsonValue> sideItem;
2404     std::unique_ptr<JsonValue> cornerItem;
2405     GradientDirection direction;
2406     switch (gradientDirections->GetArraySize()) {
2407         case DIRECTION_ANGLE:
2408             angleItem = gradientDirections->GetArrayItem(0);
2409             if (angleItem->IsString()) {
2410                 LinearGradient linearGradient;
2411                 linearGradient.angle = AnimatableDimension(StringToDouble(angleItem->GetString()));
2412                 backgroundStyle.gradientBorderImage.SetLinearGradient(linearGradient);
2413                 declaration.hasDecorationStyle_ = true;
2414             }
2415             break;
2416         case DIRECTION_SIDE:
2417             sideItem = gradientDirections->GetArrayItem(1);
2418             if (sideItem->IsString()) {
2419                 direction = StrToGradientDirection(sideItem->GetString());
2420                 LinearGradient linearGradient;
2421                 if (LinearGradient::IsXAxis(direction)) {
2422                     linearGradient.linearX = direction;
2423                 } else {
2424                     linearGradient.linearY = direction;
2425                 }
2426                 backgroundStyle.gradientBorderImage.SetLinearGradient(linearGradient);
2427                 declaration.hasDecorationStyle_ = true;
2428             }
2429             break;
2430         case DIRECTION_CORNER:
2431             sideItem = gradientDirections->GetArrayItem(1);
2432             cornerItem = gradientDirections->GetArrayItem(2);
2433             if (sideItem->IsString() && cornerItem->IsString()) {
2434                 LinearGradient linearGradient;
2435                 auto direction1 = StrToGradientDirection(sideItem->GetString());
2436                 auto direction2 = StrToGradientDirection(cornerItem->GetString());
2437                 if ((LinearGradient::IsXAxis(direction1) && LinearGradient::IsXAxis(direction2)) ||
2438                     (!LinearGradient::IsXAxis(direction1) && !LinearGradient::IsXAxis(direction2))) {
2439                     linearGradient.linearY = GradientDirection::BOTTOM;
2440                     break;
2441                 } else {
2442                     if (LinearGradient::IsXAxis(direction1)) {
2443                         linearGradient.linearX = direction1;
2444                         linearGradient.linearY = direction2;
2445                     } else {
2446                         linearGradient.linearY = direction1;
2447                         linearGradient.linearX = direction2;
2448                     }
2449                 }
2450                 backgroundStyle.gradientBorderImage.SetLinearGradient(linearGradient);
2451                 declaration.hasDecorationStyle_ = true;
2452             }
2453             break;
2454         default:
2455             LOGE("gradientDirectionsLength error");
2456             break;
2457     }
2458 }
2459 
SetBorderImageGradientColor(const std::unique_ptr<JsonValue> & gradientColorValues,Declaration & declaration)2460 void Declaration::SetBorderImageGradientColor(const std::unique_ptr<JsonValue>& gradientColorValues,
2461     Declaration& declaration)
2462 {
2463     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2464     if (!backgroundStyle.IsValid()) {
2465         return;
2466     }
2467     backgroundStyle.gradientBorderImage.ClearColors();
2468     int32_t gradientColorValuesLength = gradientColorValues->GetArraySize();
2469     for (int32_t i = 0; i < gradientColorValuesLength; i++) {
2470         std::string gradientColorValue = gradientColorValues->GetArrayItem(i)->GetString();
2471         GradientColor gradientColor;
2472         RemoveHeadTailSpace(gradientColorValue);
2473         auto index = gradientColorValue.find(' ');
2474         if (index != std::string::npos && index != 0) {
2475             std::string color = gradientColorValue.substr(0, index);
2476             std::string area = gradientColorValue.substr(index + 1, gradientColorValue.size() - index - 1);
2477             gradientColor.SetColor(declaration.ParseColor(color));
2478             gradientColor.SetHasValue(true);
2479             if (area.find("px") != std::string::npos) {
2480                 gradientColor.SetDimension(StringToDouble(area), DimensionUnit::PX);
2481             } else if (area.find('%') != std::string::npos) {
2482                 gradientColor.SetDimension(StringToDouble(area), DimensionUnit::PERCENT);
2483             } else {
2484                 LOGW("gradientColor DimensionUnit is incorrect)");
2485                 gradientColor.SetHasValue(false);
2486             }
2487         } else {
2488             gradientColor.SetHasValue(false);
2489             gradientColor.SetColor(declaration.ParseColor(gradientColorValue));
2490         }
2491         backgroundStyle.gradientBorderImage.AddColor(gradientColor);
2492         declaration.hasDecorationStyle_ = true;
2493     }
2494 }
2495 
SetBorderOverall(const std::string & value,Declaration & declaration)2496 void Declaration::SetBorderOverall(const std::string& value, Declaration& declaration)
2497 {
2498     auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
2499     if (!borderStyle.IsValid()) {
2500         return;
2501     }
2502 
2503     std::vector<std::string> offsets;
2504     StringUtils::StringSplitter(value, ' ', offsets);
2505     switch (offsets.size()) {
2506         case 1:
2507             if (offsets[0].find("px") != std::string::npos) {
2508                 SetBorderWidthForFourEdges(offsets[0], declaration);
2509             } else if (offsets[0] == "solid" || offsets[0] == "dotted" || offsets[0] == "dashed") {
2510                 SetBorderStyleForFourEdges(offsets[0], declaration);
2511             } else {
2512                 SetBorderColorForFourEdges(offsets[0], declaration);
2513             }
2514             break;
2515         case 2:
2516             SetBorderWidthForFourEdges(offsets[0], declaration);
2517             SetBorderStyleForFourEdges(offsets[1], declaration);
2518             break;
2519         case 3:
2520             SetBorderWidthForFourEdges(offsets[0], declaration);
2521             SetBorderStyleForFourEdges(offsets[1], declaration);
2522             SetBorderColorForFourEdges(offsets[2], declaration);
2523             break;
2524         default:
2525             break;
2526     }
2527 }
2528 
SetBorderWidthForFourEdges(const std::string & value,Declaration & declaration)2529 void Declaration::SetBorderWidthForFourEdges(const std::string& value, Declaration& declaration)
2530 {
2531     auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
2532     if (borderStyle.IsValid()) {
2533         borderStyle.border.SetWidth(declaration.ParseDimension(value));
2534         declaration.hasDecorationStyle_ = true;
2535         declaration.hasBorderStyle_ = true;
2536     }
2537 }
2538 
SetBorderColorForFourEdges(const std::string & value,Declaration & declaration)2539 void Declaration::SetBorderColorForFourEdges(const std::string& value, Declaration& declaration)
2540 {
2541     auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
2542     if (borderStyle.IsValid()) {
2543         borderStyle.border.SetColor(declaration.ParseColor(value));
2544         declaration.hasDecorationStyle_ = true;
2545         declaration.hasBorderStyle_ = true;
2546     }
2547 }
2548 
SetBorderStyleForFourEdges(const std::string & value,Declaration & declaration)2549 void Declaration::SetBorderStyleForFourEdges(const std::string& value, Declaration& declaration)
2550 {
2551     auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
2552     if (borderStyle.IsValid()) {
2553         borderStyle.border.SetStyle(ConvertStrToBorderStyle(value));
2554         declaration.hasDecorationStyle_ = true;
2555         declaration.hasBorderStyle_ = true;
2556     }
2557 }
2558 
SetMaskGradient(const std::string & value,Declaration & declaration)2559 void Declaration::SetMaskGradient(const std::string& value, Declaration& declaration)
2560 {
2561     Declaration::SetBackground(value, declaration);
2562 }
2563 
SetBackground(const std::string & value,Declaration & declaration)2564 void Declaration::SetBackground(const std::string& value, Declaration& declaration)
2565 {
2566     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2567     if (!backgroundStyle.IsValid()) {
2568         return;
2569     }
2570 
2571     auto backgroundJson = JsonUtil::ParseJsonString(value);
2572     if (!backgroundJson->IsObject()) {
2573         LOGE("background json is not Object");
2574         return;
2575     }
2576     if (backgroundJson->Contains(DOM_VALUES) && backgroundJson->GetValue(DOM_VALUES)->IsArray() &&
2577         backgroundJson->GetValue(DOM_VALUES)->GetArraySize() > 0) {
2578         backgroundStyle.gradient = Gradient();
2579         auto values = backgroundJson->GetValue(DOM_VALUES)->GetArrayItem(0);
2580         // gradient type and repeating
2581         if (values->Contains(DOM_GRADIENT_TYPE) && values->GetValue(DOM_GRADIENT_TYPE)->IsString()) {
2582             SetGradientType(values->GetValue(DOM_GRADIENT_TYPE)->GetString(), declaration);
2583         }
2584         // linearGradient direction
2585         if (values->Contains(DOM_GRADIENT_DIRECTIONS) && values->GetValue(DOM_GRADIENT_DIRECTIONS)->IsArray()) {
2586             SetGradientDirections(values->GetValue(DOM_GRADIENT_DIRECTIONS), declaration);
2587         }
2588         // radialGradient shape
2589         if (values->Contains(DOM_GRADIENT_SHAPE) && values->GetValue(DOM_GRADIENT_SHAPE)->IsString()) {
2590             SetGradientShape(values->GetValue(DOM_GRADIENT_SHAPE)->GetString(), declaration);
2591         }
2592         // radialGradient size
2593         if (values->Contains(DOM_GRADIENT_SIZE) && values->GetValue(DOM_GRADIENT_SIZE)->IsString()) {
2594             SetGradientSize(values->GetValue(DOM_GRADIENT_SIZE)->GetString(), declaration);
2595         }
2596         // radialGradient or sweepGradient position
2597         if (values->Contains(DOM_GRADIENT_POSITION) && values->GetValue(DOM_GRADIENT_POSITION)->IsString()) {
2598             SetGradientPosition(values->GetValue(DOM_GRADIENT_POSITION)->GetString(), declaration);
2599         }
2600         // sweepGradient startAngle and endAngle
2601         if (values->Contains(DOM_GRADIENT_ANGLE) && values->GetValue(DOM_GRADIENT_ANGLE)->IsString()) {
2602             SetGradientAngle(values->GetValue(DOM_GRADIENT_ANGLE)->GetString(), declaration);
2603         }
2604         // sweepGradient rotation
2605         if (values->Contains(DOM_GRADIENT_ROTATION) && values->GetValue(DOM_GRADIENT_ROTATION)->IsString()) {
2606             SetGradientRotation(values->GetValue(DOM_GRADIENT_ROTATION)->GetString(), declaration);
2607         }
2608         // gradient color stops
2609         if (values->Contains(DOM_GRADIENT_VALUES) && values->GetValue(DOM_GRADIENT_VALUES)->IsArray()) {
2610             SetGradientColor(values->GetValue(DOM_GRADIENT_VALUES), declaration);
2611         }
2612     }
2613     declaration.hasDecorationStyle_ = true;
2614     declaration.hasBackGroundColor_ = true;
2615 }
2616 
SetGradientType(const std::string & gradientType,Declaration & declaration)2617 void Declaration::SetGradientType(const std::string& gradientType, Declaration& declaration)
2618 {
2619     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2620     if (!backgroundStyle.IsValid()) {
2621         return;
2622     }
2623     // default: LINEAR
2624     backgroundStyle.gradient.SetType(GradientType::LINEAR);
2625     if (gradientType == DOM_RADIAL_GRADIENT || gradientType == DOM_REPEATING_RADIAL_GRADIENT) {
2626         backgroundStyle.gradient.SetType(GradientType::RADIAL);
2627     } else if (gradientType == DOM_SWEEP_GRADIENT || gradientType == DOM_REPEATING_SWEEP_GRADIENT) {
2628         backgroundStyle.gradient.SetType(GradientType::SWEEP);
2629     }
2630 
2631     if (gradientType == DOM_REPEATING_LINEAR_GRADIENT || gradientType == DOM_REPEATING_RADIAL_GRADIENT ||
2632         gradientType == DOM_REPEATING_SWEEP_GRADIENT) {
2633         backgroundStyle.gradient.SetRepeat(true);
2634     }
2635     declaration.hasDecorationStyle_ = true;
2636 }
2637 
SetGradientDirections(const std::unique_ptr<JsonValue> & gradientDirections,Declaration & declaration)2638 void Declaration::SetGradientDirections(const std::unique_ptr<JsonValue>& gradientDirections, Declaration& declaration)
2639 {
2640     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2641     if (!backgroundStyle.IsValid()) {
2642         return;
2643     }
2644 
2645     std::unique_ptr<JsonValue> angleItem;
2646     std::unique_ptr<JsonValue> sideItem;
2647     std::unique_ptr<JsonValue> cornerItem;
2648     GradientDirection direction;
2649     switch (gradientDirections->GetArraySize()) {
2650         case DIRECTION_ANGLE:
2651             angleItem = gradientDirections->GetArrayItem(0);
2652             if (angleItem->IsString()) {
2653                 LinearGradient linearGradient;
2654                 linearGradient.angle = AnimatableDimension(StringToDouble(angleItem->GetString()));
2655                 backgroundStyle.gradient.SetLinearGradient(linearGradient);
2656                 declaration.hasDecorationStyle_ = true;
2657             }
2658             break;
2659         case DIRECTION_SIDE:
2660             sideItem = gradientDirections->GetArrayItem(1);
2661             if (sideItem->IsString()) {
2662                 direction = StrToGradientDirection(sideItem->GetString());
2663                 LinearGradient linearGradient;
2664                 if (LinearGradient::IsXAxis(direction)) {
2665                     linearGradient.linearX = direction;
2666                 } else {
2667                     linearGradient.linearY = direction;
2668                 }
2669                 backgroundStyle.gradient.SetLinearGradient(linearGradient);
2670                 declaration.hasDecorationStyle_ = true;
2671             }
2672             break;
2673         case DIRECTION_CORNER:
2674             sideItem = gradientDirections->GetArrayItem(1);
2675             cornerItem = gradientDirections->GetArrayItem(2);
2676             if (sideItem->IsString() && cornerItem->IsString()) {
2677                 LinearGradient linearGradient;
2678                 auto direction1 = StrToGradientDirection(sideItem->GetString());
2679                 auto direction2 = StrToGradientDirection(cornerItem->GetString());
2680                 if ((LinearGradient::IsXAxis(direction1) && LinearGradient::IsXAxis(direction2)) ||
2681                     (!LinearGradient::IsXAxis(direction1) && !LinearGradient::IsXAxis(direction2))) {
2682                     linearGradient.linearY = GradientDirection::BOTTOM;
2683                     break;
2684                 } else {
2685                     if (LinearGradient::IsXAxis(direction1)) {
2686                         linearGradient.linearX = direction1;
2687                         linearGradient.linearY = direction2;
2688                     } else {
2689                         linearGradient.linearY = direction1;
2690                         linearGradient.linearX = direction2;
2691                     }
2692                 }
2693                 backgroundStyle.gradient.SetLinearGradient(linearGradient);
2694                 declaration.hasDecorationStyle_ = true;
2695             }
2696             break;
2697         default:
2698             LOGE("gradientDirectionsLength error");
2699             break;
2700     }
2701 }
2702 
SetGradientColor(const std::unique_ptr<JsonValue> & gradientColorValues,Declaration & declaration)2703 void Declaration::SetGradientColor(const std::unique_ptr<JsonValue>& gradientColorValues, Declaration& declaration)
2704 {
2705     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2706     if (!backgroundStyle.IsValid()) {
2707         return;
2708     }
2709 
2710     backgroundStyle.gradient.ClearColors();
2711     int32_t gradientColorValuesLength = gradientColorValues->GetArraySize();
2712     for (int32_t i = 0; i < gradientColorValuesLength; i++) {
2713         std::string gradientColorValue = gradientColorValues->GetArrayItem(i)->GetString();
2714         GradientColor gradientColor;
2715         RemoveHeadTailSpace(gradientColorValue);
2716         auto index = gradientColorValue.find(' ');
2717         if (index != std::string::npos && index != 0) {
2718             std::string color = gradientColorValue.substr(0, index);
2719             std::string area = gradientColorValue.substr(index + 1, gradientColorValue.size() - index - 1);
2720             gradientColor.SetColor(declaration.ParseColor(color));
2721             gradientColor.SetHasValue(true);
2722             if (area.find("px") != std::string::npos) {
2723                 gradientColor.SetDimension(StringToDouble(area), DimensionUnit::PX);
2724             } else if (area.find('%') != std::string::npos) {
2725                 gradientColor.SetDimension(StringToDouble(area), DimensionUnit::PERCENT);
2726             } else {
2727                 LOGW("gradientColor DimensionUnit is incorrect)");
2728                 gradientColor.SetHasValue(false);
2729             }
2730         } else {
2731             gradientColor.SetHasValue(false);
2732             gradientColor.SetColor(declaration.ParseColor(gradientColorValue));
2733         }
2734         backgroundStyle.gradient.AddColor(gradientColor);
2735         declaration.hasDecorationStyle_ = true;
2736     }
2737 }
2738 
SetGradientShape(const std::string & gradientShape,Declaration & declaration)2739 void Declaration::SetGradientShape(const std::string& gradientShape, Declaration& declaration)
2740 {
2741     // if empty do nothing, If shape is omitted, the ending shape defaults to a circle if the <size> is a single
2742     // <length>, and to an ellipse otherwise.
2743     if (gradientShape.empty()) {
2744         return;
2745     }
2746     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2747     if (!backgroundStyle.IsValid()) {
2748         return;
2749     }
2750 
2751     if (gradientShape == DOM_GRADIENT_SHAPE_ELLIPSE) {
2752         backgroundStyle.gradient.GetRadialGradient().radialShape = RadialShapeType::ELLIPSE;
2753     } else {
2754         backgroundStyle.gradient.GetRadialGradient().radialShape = RadialShapeType::CIRCLE;
2755     }
2756     declaration.hasDecorationStyle_ = true;
2757 }
2758 
SetGradientSize(const std::string & gradientSize,Declaration & declaration)2759 void Declaration::SetGradientSize(const std::string& gradientSize, Declaration& declaration)
2760 {
2761     if (gradientSize.empty()) {
2762         return;
2763     }
2764     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2765     if (!backgroundStyle.IsValid()) {
2766         return;
2767     }
2768     // 1. closest-corner | closest-side | farthest-corner | farthest-side
2769     auto extent = ParseRadialGradientSize(gradientSize);
2770     if (extent) {
2771         backgroundStyle.gradient.GetRadialGradient().radialSizeType = extent;
2772         declaration.hasDecorationStyle_ = true;
2773         return;
2774     }
2775 
2776     std::vector<std::string> offsets;
2777     StringUtils::StringSplitter(gradientSize, ' ', offsets);
2778     if (offsets.size() == 1) {
2779         // 2. if circle: <length>
2780         auto circleSize = StringToDimension(offsets[0]);
2781 
2782         if (circleSize.Unit() != DimensionUnit::PX) {
2783             LOGE("circle only support length");
2784             return;
2785         }
2786         if (backgroundStyle.gradient.GetRadialGradient().radialShape &&
2787             backgroundStyle.gradient.GetRadialGradient().radialShape != RadialShapeType::CIRCLE) {
2788             LOGE("only circle support one size");
2789             return;
2790         }
2791         backgroundStyle.gradient.GetRadialGradient().radialVerticalSize = circleSize;
2792         backgroundStyle.gradient.GetRadialGradient().radialShape = RadialShapeType::CIRCLE;
2793         declaration.hasDecorationStyle_ = true;
2794     } else if (offsets.size() == 2) {
2795         // 3. if ellipse: <length-percentage>{2}
2796         auto horizontalSize = StringToDimension(offsets[0]);
2797         auto verticalSize = StringToDimension(offsets[1]);
2798 
2799         if (backgroundStyle.gradient.GetRadialGradient().radialShape &&
2800             backgroundStyle.gradient.GetRadialGradient().radialShape != RadialShapeType::ELLIPSE) {
2801             LOGE("only ellipse support two size");
2802             return;
2803         }
2804         backgroundStyle.gradient.GetRadialGradient().radialHorizontalSize = horizontalSize;
2805         backgroundStyle.gradient.GetRadialGradient().radialVerticalSize = verticalSize;
2806         backgroundStyle.gradient.GetRadialGradient().radialShape = RadialShapeType::ELLIPSE;
2807         declaration.hasDecorationStyle_ = true;
2808     } else {
2809         LOGE("unsupported offset size");
2810     }
2811 }
2812 
SetGradientPosition(const std::string & gradientPosition,Declaration & declaration)2813 void Declaration::SetGradientPosition(const std::string& gradientPosition, Declaration& declaration)
2814 {
2815     if (gradientPosition.empty()) {
2816         return;
2817     }
2818     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2819     if (!backgroundStyle.IsValid()) {
2820         return;
2821     }
2822     // position determines the center of gradient default is center
2823     BackgroundImagePosition position;
2824     if (ParseBackgroundImagePosition(gradientPosition, position)) {
2825         auto xAxisPosition = Dimension(position.GetSizeValueX(),
2826             position.GetSizeTypeX() == BackgroundImagePositionType::PX ? DimensionUnit::PX : DimensionUnit::PERCENT);
2827         auto yAxisPosition = Dimension(position.GetSizeValueY(),
2828             position.GetSizeTypeY() == BackgroundImagePositionType::PX ? DimensionUnit::PX : DimensionUnit::PERCENT);
2829         if (backgroundStyle.gradient.GetType() == GradientType::RADIAL) {
2830             backgroundStyle.gradient.GetRadialGradient().radialCenterX = xAxisPosition;
2831             backgroundStyle.gradient.GetRadialGradient().radialCenterY = yAxisPosition;
2832             declaration.hasDecorationStyle_ = true;
2833         } else if (backgroundStyle.gradient.GetType() == GradientType::SWEEP) {
2834             backgroundStyle.gradient.GetSweepGradient().centerX = xAxisPosition;
2835             backgroundStyle.gradient.GetSweepGradient().centerY = yAxisPosition;
2836             declaration.hasDecorationStyle_ = true;
2837         }
2838     } else {
2839         LOGE("ParseBackgroundImagePosition failed");
2840     }
2841 }
2842 
SetGradientAngle(const std::string & gradientAngle,Declaration & declaration)2843 void Declaration::SetGradientAngle(const std::string& gradientAngle, Declaration& declaration)
2844 {
2845     if (gradientAngle.empty()) {
2846         return;
2847     }
2848     auto backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2849     if (!backgroundStyle.IsValid()) {
2850         LOGE("backgroundStyle is invalid");
2851         return;
2852     }
2853     std::vector<std::string> offsets;
2854     StringUtils::StringSplitter(gradientAngle, ' ', offsets);
2855     if (!offsets.empty()) {
2856         auto startAngle = StringUtils::StringToDegree(offsets[0]);
2857         backgroundStyle.gradient.GetSweepGradient().startAngle = AnimatableDimension(startAngle);
2858         if (offsets.size() > 1) {
2859             auto endAngle = StringUtils::StringToDegree(offsets[1]);
2860             backgroundStyle.gradient.GetSweepGradient().endAngle = AnimatableDimension(endAngle);
2861         }
2862         declaration.hasDecorationStyle_ = true;
2863     }
2864 }
2865 
SetGradientRotation(const std::string & gradientRotation,Declaration & declaration)2866 void Declaration::SetGradientRotation(const std::string& gradientRotation, Declaration& declaration)
2867 {
2868     if (gradientRotation.empty()) {
2869         return;
2870     }
2871     auto backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2872     if (!backgroundStyle.IsValid()) {
2873         return;
2874     }
2875     std::vector<std::string> offsets;
2876     StringUtils::StringSplitter(gradientRotation, ' ', offsets);
2877     if (!offsets.empty()) {
2878         auto rotationAngle = StringUtils::StringToDegree(offsets[0]);
2879         backgroundStyle.gradient.GetSweepGradient().rotation = AnimatableDimension(rotationAngle);
2880         declaration.hasDecorationStyle_ = true;
2881     }
2882 }
2883 
SetBgImgSizeX(const BackgroundImageSizeType type,const double value,BackgroundImageSize & bgImgSize)2884 void SetBgImgSizeX(const BackgroundImageSizeType type, const double value, BackgroundImageSize& bgImgSize)
2885 {
2886     bgImgSize.SetSizeTypeX(type);
2887     bgImgSize.SetSizeValueX(value);
2888 }
2889 
SetBgImgSizeY(const BackgroundImageSizeType type,const double value,BackgroundImageSize & bgImgSize)2890 void SetBgImgSizeY(const BackgroundImageSizeType type, const double value, BackgroundImageSize& bgImgSize)
2891 {
2892     bgImgSize.SetSizeTypeY(type);
2893     bgImgSize.SetSizeValueY(value);
2894 }
2895 
SetBackgroundImageSize(const std::string & value,Declaration & declaration)2896 void Declaration::SetBackgroundImageSize(const std::string& value, Declaration& declaration)
2897 {
2898     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2899     if (!backgroundStyle.IsValid()) {
2900         return;
2901     }
2902 
2903     static const LinearMapNode<BackgroundImageSizeType> bgImageSizeType[] = {
2904         { DOM_BACKGROUND_IMAGE_SIZE_AUTO, BackgroundImageSizeType::AUTO },
2905         { DOM_BACKGROUND_IMAGE_SIZE_CONTAIN, BackgroundImageSizeType::CONTAIN },
2906         { DOM_BACKGROUND_IMAGE_SIZE_COVER, BackgroundImageSizeType::COVER },
2907     };
2908     BackgroundImageSize bgImgSize;
2909     auto spaceIndex = value.find(' ', 0);
2910     if (spaceIndex != std::string::npos) {
2911         std::string valueX = value.substr(0, spaceIndex);
2912         std::string valueY = value.substr(spaceIndex + 1, value.size() - spaceIndex - 1);
2913         if (valueX.find("px") != std::string::npos) {
2914             SetBgImgSizeX(BackgroundImageSizeType::LENGTH, StringToDouble(valueX), bgImgSize);
2915         } else if (valueX.find('%') != std::string::npos) {
2916             SetBgImgSizeX(BackgroundImageSizeType::PERCENT, StringToDouble(valueX), bgImgSize);
2917         } else {
2918             bgImgSize.SetSizeTypeX(BackgroundImageSizeType::AUTO);
2919         }
2920         if (valueY.find("px") != std::string::npos) {
2921             SetBgImgSizeY(BackgroundImageSizeType::LENGTH, StringToDouble(valueY), bgImgSize);
2922         } else if (valueY.find('%') != std::string::npos) {
2923             SetBgImgSizeY(BackgroundImageSizeType::PERCENT, StringToDouble(valueY), bgImgSize);
2924         } else {
2925             bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
2926         }
2927     } else {
2928         auto sizeTypeIter = BinarySearchFindIndex(bgImageSizeType, ArraySize(bgImageSizeType), value.c_str());
2929         if (sizeTypeIter != -1) {
2930             bgImgSize.SetSizeTypeX(bgImageSizeType[sizeTypeIter].value);
2931             bgImgSize.SetSizeTypeY(bgImageSizeType[sizeTypeIter].value);
2932         } else if (value.find("px") != std::string::npos) {
2933             SetBgImgSizeX(BackgroundImageSizeType::LENGTH, StringToDouble(value), bgImgSize);
2934             bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
2935         } else if (value.find('%') != std::string::npos) {
2936             SetBgImgSizeX(BackgroundImageSizeType::PERCENT, StringToDouble(value), bgImgSize);
2937             bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
2938         } else {
2939             bgImgSize.SetSizeTypeX(BackgroundImageSizeType::AUTO);
2940             bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
2941         }
2942     }
2943     backgroundStyle.backgroundImage->SetImageSize(
2944         bgImgSize.GetSizeTypeX(), bgImgSize.GetSizeValueX(), bgImgSize.GetSizeTypeY(), bgImgSize.GetSizeValueY());
2945     declaration.hasDecorationStyle_ = true;
2946 }
2947 
SetBgImgPositionX(const BackgroundImagePositionType type,const double value,BackgroundImagePosition & bgImgPosition)2948 void SetBgImgPositionX(
2949     const BackgroundImagePositionType type, const double value, BackgroundImagePosition& bgImgPosition)
2950 {
2951     bgImgPosition.SetSizeTypeX(type);
2952     bgImgPosition.SetSizeValueX(value);
2953 }
2954 
SetBgImgPositionY(const BackgroundImagePositionType type,const double value,BackgroundImagePosition & bgImgPosition)2955 void SetBgImgPositionY(
2956     const BackgroundImagePositionType type, const double value, BackgroundImagePosition& bgImgPosition)
2957 {
2958     bgImgPosition.SetSizeTypeY(type);
2959     bgImgPosition.SetSizeValueY(value);
2960 }
2961 
SetBgImgPosition(const BackgroundImagePositionType type,const double value,BackgroundImagePosition & bgImgPosition)2962 void SetBgImgPosition(
2963     const BackgroundImagePositionType type, const double value, BackgroundImagePosition& bgImgPosition)
2964 {
2965     SetBgImgPositionX(type, value, bgImgPosition);
2966     SetBgImgPositionY(type, value, bgImgPosition);
2967 }
2968 
BgImgPositionIsValid(const std::string & posX,const std::string & posY)2969 bool BgImgPositionIsValid(const std::string& posX, const std::string& posY)
2970 {
2971     if ((std::strcmp(posX.c_str(), DOM_BACKGROUND_IMAGE_POSITION_CENTER) == 0) ||
2972         (std::strcmp(posY.c_str(), DOM_BACKGROUND_IMAGE_POSITION_CENTER) == 0)) {
2973         return true;
2974     }
2975 
2976     static const std::unordered_set<std::string> horizonSet = {
2977         DOM_BACKGROUND_IMAGE_POSITION_LEFT,
2978         DOM_BACKGROUND_IMAGE_POSITION_RIGHT,
2979     };
2980     static const std::unordered_set<std::string> verticalSet = {
2981         DOM_BACKGROUND_IMAGE_POSITION_TOP,
2982         DOM_BACKGROUND_IMAGE_POSITION_BOTTOM,
2983     };
2984 
2985     // posX and posY are not strictly corresponding to horizontal or vertical, but they must not conflict,
2986     // for example both of them are "top" is invalid.
2987     if (posX.find("px") != std::string::npos || posX.find('%') != std::string::npos ||
2988         horizonSet.find(posX) != horizonSet.end()) {
2989         if (posY.find("px") != std::string::npos || posY.find('%') != std::string::npos ||
2990             verticalSet.find(posY) != verticalSet.end()) {
2991             return true;
2992         }
2993     }
2994 
2995     return verticalSet.find(posX) != verticalSet.end() && horizonSet.find(posY) != horizonSet.end();
2996 }
2997 
SetBackgroundImagePosition(const std::string & value,Declaration & declaration)2998 void Declaration::SetBackgroundImagePosition(const std::string& value, Declaration& declaration)
2999 {
3000     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
3001     if (!backgroundStyle.IsValid()) {
3002         return;
3003     }
3004 
3005     static const LinearMapNode<void (*)(BackgroundImagePosition&)> backGroundPositionOperators[] = {
3006         { DOM_BACKGROUND_IMAGE_POSITION_BOTTOM,
3007             [](BackgroundImagePosition& backgroundImagePosition) {
3008                 SetBgImgPositionY(BackgroundImagePositionType::PERCENT, 100.0, backgroundImagePosition);
3009             } },
3010         { DOM_BACKGROUND_IMAGE_POSITION_LEFT,
3011             [](BackgroundImagePosition& backgroundImagePosition) {
3012                 SetBgImgPositionX(BackgroundImagePositionType::PERCENT, 0.0, backgroundImagePosition);
3013             } },
3014         { DOM_BACKGROUND_IMAGE_POSITION_RIGHT,
3015             [](BackgroundImagePosition& backgroundImagePosition) {
3016                 SetBgImgPositionX(BackgroundImagePositionType::PERCENT, 100.0, backgroundImagePosition);
3017             } },
3018         { DOM_BACKGROUND_IMAGE_POSITION_TOP,
3019             [](BackgroundImagePosition& backgroundImagePosition) {
3020                 SetBgImgPositionY(BackgroundImagePositionType::PERCENT, 0.0, backgroundImagePosition);
3021             } },
3022     };
3023     BackgroundImagePosition backgroundImagePosition;
3024 
3025     auto index = value.find(' ', 0);
3026     if (index != std::string::npos) {
3027         std::string valueX = value.substr(0, index);
3028         std::string valueY = value.substr(index + 1, value.size() - index - 1);
3029         if (!BgImgPositionIsValid(valueX, valueY)) {
3030             return;
3031         }
3032         // The input is valid,so set the default is (center,center),
3033         // if the value is different, the default value is overwritten.
3034         SetBgImgPosition(BackgroundImagePositionType::PERCENT, 50.0, backgroundImagePosition);
3035         if (valueX.find("px") != std::string::npos) {
3036             SetBgImgPositionX(BackgroundImagePositionType::PX, StringToDouble(valueX), backgroundImagePosition);
3037         } else if (valueX.find('%') != std::string::npos) {
3038             SetBgImgPositionX(BackgroundImagePositionType::PERCENT, StringToDouble(valueX), backgroundImagePosition);
3039         } else {
3040             auto operatorIterX = BinarySearchFindIndex(
3041                 backGroundPositionOperators, ArraySize(backGroundPositionOperators), valueX.c_str());
3042             if (operatorIterX != -1) {
3043                 backGroundPositionOperators[operatorIterX].value(backgroundImagePosition);
3044             }
3045         }
3046         if (valueY.find("px") != std::string::npos) {
3047             SetBgImgPositionY(BackgroundImagePositionType::PX, StringToDouble(valueY), backgroundImagePosition);
3048         } else if (valueY.find('%') != std::string::npos) {
3049             SetBgImgPositionY(BackgroundImagePositionType::PERCENT, StringToDouble(valueY), backgroundImagePosition);
3050         } else {
3051             auto operatorIterY = BinarySearchFindIndex(
3052                 backGroundPositionOperators, ArraySize(backGroundPositionOperators), valueY.c_str());
3053             if (operatorIterY != -1) {
3054                 backGroundPositionOperators[operatorIterY].value(backgroundImagePosition);
3055             }
3056         }
3057     } else {
3058         SetBgImgPosition(BackgroundImagePositionType::PERCENT, 50.0, backgroundImagePosition);
3059         if (value.find("px") != std::string::npos) {
3060             SetBgImgPositionX(BackgroundImagePositionType::PX, StringToDouble(value), backgroundImagePosition);
3061         } else if (value.find('%') != std::string::npos) {
3062             SetBgImgPositionX(BackgroundImagePositionType::PERCENT, StringToDouble(value), backgroundImagePosition);
3063         } else {
3064             auto operatorIter = BinarySearchFindIndex(
3065                 backGroundPositionOperators, ArraySize(backGroundPositionOperators), value.c_str());
3066             if (operatorIter != -1) {
3067                 backGroundPositionOperators[operatorIter].value(backgroundImagePosition);
3068             }
3069         }
3070     }
3071     backgroundStyle.backgroundImage->SetImagePosition(backgroundImagePosition.GetSizeTypeX(),
3072         backgroundImagePosition.GetSizeValueX(), backgroundImagePosition.GetSizeTypeY(),
3073         backgroundImagePosition.GetSizeValueY());
3074     declaration.hasDecorationStyle_ = true;
3075 }
3076 
BindPipelineContext(const WeakPtr<PipelineBase> & pipelineContext)3077 void Declaration::BindPipelineContext(const WeakPtr<PipelineBase>& pipelineContext)
3078 {
3079     pipelineContext_ = pipelineContext;
3080 }
3081 
ResetDefaultStyles()3082 void Declaration::ResetDefaultStyles()
3083 {
3084     auto& sizeStyle = static_cast<CommonSizeStyle&>(GetStyle(StyleTag::COMMON_SIZE_STYLE));
3085     if (sizeStyle.IsValid() && !sizeStyle.IsShared()) {
3086         sizeStyle.width = Dimension(-1.0, DimensionUnit::PX);
3087         sizeStyle.height = Dimension(-1.0, DimensionUnit::PX);
3088         sizeStyle.minWidth = Dimension(0.0);
3089         sizeStyle.minHeight = Dimension(0.0);
3090         sizeStyle.maxWidth = Dimension(Size::INFINITE_SIZE);
3091         sizeStyle.maxHeight = Dimension(Size::INFINITE_SIZE);
3092         sizeStyle.aspectRatio = -1.0;
3093     }
3094 
3095     auto& paddingStyle = static_cast<CommonPaddingStyle&>(GetStyle(StyleTag::COMMON_PADDING_STYLE));
3096     if (paddingStyle.IsValid() && !paddingStyle.IsShared()) {
3097         paddingStyle.padding = Edge(Dimension(0.0));
3098     }
3099 
3100     auto& marginStyle = static_cast<CommonMarginStyle&>(GetStyle(StyleTag::COMMON_MARGIN_STYLE));
3101     if (marginStyle.IsValid() && !marginStyle.IsShared()) {
3102         marginStyle.margin = Edge(Dimension(0.0));
3103     }
3104 
3105     auto& flexStyle = static_cast<CommonFlexStyle&>(GetStyle(StyleTag::COMMON_FLEX_STYLE));
3106     if (flexStyle.IsValid() && !flexStyle.IsShared()) {
3107         flexStyle.flexGrow = 0.0;
3108         flexStyle.flexShrink = 1.0;
3109         flexStyle.flexBasis = 0.0_px;
3110         flexStyle.flexWeight = 0.0;
3111         flexStyle.displayIndex = 1;
3112     }
3113 
3114     auto& opacityStyle = static_cast<CommonOpacityStyle&>(GetStyle(StyleTag::COMMON_OPACITY_STYLE));
3115     if (opacityStyle.IsValid() && !opacityStyle.IsShared()) {
3116         opacityStyle.opacity = 1.0;
3117     }
3118 
3119     auto& displayStyle = static_cast<CommonDisplayStyle&>(GetStyle(StyleTag::COMMON_DISPLAY_STYLE));
3120     if (displayStyle.IsValid() && !displayStyle.IsShared()) {
3121         displayStyle.display = DisplayType::NO_SETTING;
3122     }
3123     hasDisplayStyle_ = false;
3124 
3125     auto& visibilityStyle = static_cast<CommonVisibilityStyle&>(GetStyle(StyleTag::COMMON_VISIBILITY_STYLE));
3126     if (visibilityStyle.IsValid() && !visibilityStyle.IsShared()) {
3127         visibilityStyle.visibility = VisibilityType::NO_SETTING;
3128     }
3129 
3130     auto& borderStyle = static_cast<CommonBorderStyle&>(GetStyle(StyleTag::COMMON_BORDER_STYLE));
3131     if (borderStyle.IsValid() && !borderStyle.IsShared()) {
3132         borderStyle.border.SetBorderEdge(BorderEdge(Color::BLACK, Dimension(), BorderStyle::SOLID));
3133     }
3134 
3135     auto& borderImageStyle = static_cast<CommonBorderStyle&>(GetStyle(StyleTag::COMMON_BORDER_STYLE));
3136     if (borderImageStyle.IsValid() && !borderImageStyle.IsShared()) {
3137         borderImageStyle.border.SetBorderImageEdge(
3138             BorderImageEdge(Dimension(), Dimension(), Dimension(), BorderImageRepeat::STRETCH));
3139     }
3140 
3141     auto& background = static_cast<CommonBackgroundStyle&>(GetStyle(StyleTag::COMMON_BACKGROUND_STYLE));
3142     if (background.IsValid() && !background.IsShared()) {
3143         background.gradient = Gradient();
3144         background.gradientBorderImage = Gradient();
3145         background.backgroundImage = AceType::MakeRefPtr<BackgroundImage>();
3146         background.borderImage = AceType::MakeRefPtr<BorderImage>();
3147     }
3148 
3149     auto& renderAttr = static_cast<CommonRenderAttribute&>(GetAttribute(AttributeTag::COMMON_RENDER_ATTR));
3150     if (renderAttr.IsValid() && !renderAttr.IsShared() && !renderAttr.show.empty()) {
3151         hasDisplayStyle_ = true;
3152         SetShowAttr(renderAttr.show);
3153     }
3154 
3155     backDecoration_ = AceType::MakeRefPtr<Decoration>();
3156     frontDecoration_ = AceType::MakeRefPtr<Decoration>();
3157 }
3158 
3159 // Convert transform style to json format, such as rotate(50deg) to {"rotate":"50deg"}
GetTransformJsonValue(const std::string & value)3160 std::string Declaration::GetTransformJsonValue(const std::string& value)
3161 {
3162     auto rightIndex = value.find('(');
3163     auto leftIndex = value.find(')');
3164     std::string jsonValue = value;
3165 
3166     if (rightIndex != std::string::npos && leftIndex != std::string::npos && (leftIndex - 1 - rightIndex > 0)) {
3167         std::string transformType = value.substr(0, rightIndex);
3168         std::string transformValue = value.substr(rightIndex + 1, leftIndex - 1 - rightIndex);
3169         jsonValue = "{\"" + transformType + "\":\"" + transformValue + "\"}";
3170     }
3171 
3172     return jsonValue;
3173 }
3174 
GetTransformType(const std::unique_ptr<JsonValue> & transformJson)3175 std::string Declaration::GetTransformType(const std::unique_ptr<JsonValue>& transformJson)
3176 {
3177     if (transformJson->IsNull()) {
3178         LOGE("transformJson is null");
3179         return "";
3180     }
3181     return transformJson->GetKey();
3182 }
3183 
GetTransformTypeValue(const std::unique_ptr<JsonValue> & transformJson)3184 std::string Declaration::GetTransformTypeValue(const std::unique_ptr<JsonValue>& transformJson)
3185 {
3186     if (transformJson->IsNull()) {
3187         LOGE("transformJson is null");
3188         return "";
3189     }
3190     std::string jsonValue = transformJson->GetString();
3191     if (jsonValue.empty()) {
3192         double jsonDouble = transformJson->GetDouble();
3193         return std::to_string(jsonDouble);
3194     }
3195     return jsonValue;
3196 }
3197 
GetThemeManager() const3198 RefPtr<ThemeManager> Declaration::GetThemeManager() const
3199 {
3200     auto context = pipelineContext_.Upgrade();
3201     if (!context) {
3202         return nullptr;
3203     }
3204     return context->GetThemeManager();
3205 }
3206 
GetThemeConstants() const3207 RefPtr<ThemeConstants> Declaration::GetThemeConstants() const
3208 {
3209     auto themeManager = GetThemeManager();
3210     if (!themeManager) {
3211         return nullptr;
3212     }
3213     return themeManager->GetThemeConstants();
3214 }
3215 
ParseColor(const std::string & value,uint32_t maskAlpha) const3216 Color Declaration::ParseColor(const std::string& value, uint32_t maskAlpha) const
3217 {
3218     auto themeConstants = GetThemeConstants();
3219     auto&& noRefFunc = [&value, maskAlpha = maskAlpha]() { return Color::FromString(value, maskAlpha); };
3220     auto&& idRefFunc = [constants = themeConstants](uint32_t refId) { return constants->GetColor(refId); };
3221     return ParseThemeReference<Color>(value, noRefFunc, idRefFunc, Color::TRANSPARENT);
3222 }
3223 
ParseDouble(const std::string & value) const3224 double Declaration::ParseDouble(const std::string& value) const
3225 {
3226     auto themeConstants = GetThemeConstants();
3227     auto&& noRefFunc = [&value]() { return StringUtils::StringToDouble(value); };
3228     auto&& idRefFunc = [constants = themeConstants](uint32_t refId) { return constants->GetDouble(refId); };
3229     return ParseThemeReference<double>(value, noRefFunc, idRefFunc, 0.0);
3230 }
3231 
ParseDimension(const std::string & value,bool useVp) const3232 Dimension Declaration::ParseDimension(const std::string& value, bool useVp) const
3233 {
3234     auto themeConstants = GetThemeConstants();
3235     auto&& noRefFunc = [&value, useVp]() { return StringUtils::StringToDimension(value, useVp); };
3236     auto&& idRefFunc = [constants = themeConstants](uint32_t refId) { return constants->GetDimension(refId); };
3237     return ParseThemeReference<Dimension>(value, noRefFunc, idRefFunc, Dimension());
3238 }
3239 
ParseCalcDimension(const std::string & value,bool useVp) const3240 CalcDimension Declaration::ParseCalcDimension(const std::string& value, bool useVp) const
3241 {
3242     if (value.find("calc") != std::string::npos) {
3243         return StringUtils::StringToCalcDimension(value, useVp);
3244     } else {
3245         return ParseDimension(value, useVp);
3246     }
3247 }
3248 
ParseLineHeight(const std::string & value) const3249 Dimension Declaration::ParseLineHeight(const std::string& value) const
3250 {
3251     auto themeConstants = GetThemeConstants();
3252     const auto& parseResult = ThemeUtils::ParseThemeIdReference(value, themeConstants);
3253     if (!parseResult.parseSuccess) {
3254         return StringUtils::StringToDimension(value);
3255     }
3256     auto&& noRefFunc = [&value]() { return StringUtils::StringToDouble(value); };
3257     auto&& idRefFunc = [constants = themeConstants](uint32_t refId) { return constants->GetDouble(refId); };
3258     auto lineHeightScale = ParseThemeReference<double>(value, noRefFunc, idRefFunc, 1.0);
3259     // If got 0.0 from ThemeConstants, use default 1.0
3260     lineHeightScale = NearZero(lineHeightScale) ? 1.0 : lineHeightScale;
3261     return Dimension(lineHeightScale, DimensionUnit::PERCENT);
3262 }
3263 
ParseFontFamilies(const std::string & value) const3264 std::vector<std::string> Declaration::ParseFontFamilies(const std::string& value) const
3265 {
3266     std::vector<std::string> fontFamilies;
3267     std::stringstream stream(value);
3268     std::string fontFamily;
3269 
3270     auto themeConstants = GetThemeConstants();
3271     auto&& idRefFunc = [constants = themeConstants](uint32_t refId) { return constants->GetString(refId); };
3272 
3273     while (getline(stream, fontFamily, ',')) {
3274         auto&& noRefFunc = [&fontFamily]() { return fontFamily; };
3275         fontFamilies.emplace_back(ParseThemeReference<std::string>(fontFamily, noRefFunc, idRefFunc, fontFamily));
3276     }
3277     return fontFamilies;
3278 }
3279 
ParsePreferFontSizes(const std::string & value) const3280 std::vector<Dimension> Declaration::ParsePreferFontSizes(const std::string& value) const
3281 {
3282     std::vector<Dimension> prefers;
3283     std::stringstream stream(value);
3284     std::string fontSize;
3285     while (getline(stream, fontSize, ',')) {
3286         prefers.emplace_back(ParseDimension(fontSize));
3287     }
3288     std::sort(prefers.begin(), prefers.end(),
3289         [](const Dimension& left, const Dimension& right) { return left.Value() > right.Value(); });
3290     return prefers;
3291 }
3292 
ParseImageSrc(const std::string & imgSrc) const3293 std::string Declaration::ParseImageSrc(const std::string& imgSrc) const
3294 {
3295     return ThemeUtils::ProcessImageSource(imgSrc, GetThemeConstants());
3296 }
3297 
IsRightToLeft() const3298 bool Declaration::IsRightToLeft() const
3299 {
3300     bool isRightToLeft = false;
3301     auto& commonAttr = static_cast<CommonAttribute&>(GetAttribute(AttributeTag::COMMON_ATTR));
3302     if (commonAttr.IsValid()) {
3303         isRightToLeft = commonAttr.isRightToLeft;
3304     }
3305     return isRightToLeft;
3306 }
3307 
SetClickEvent(const EventMarker & onClick)3308 void Declaration::SetClickEvent(const EventMarker& onClick)
3309 {
3310     auto& gestureEvent = MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
3311     if (gestureEvent.IsValid()) {
3312         gestureEvent.click.eventMarker = onClick;
3313         gestureEvent.click.eventMarker.SetCatchMode(false);
3314         gestureEvent.click.isRefreshed = true;
3315     }
3316 }
3317 
SetRemoteMessageEvent(const EventMarker & remoteMessage)3318 void Declaration::SetRemoteMessageEvent(const EventMarker& remoteMessage)
3319 {
3320     LOGI("Declaration::SetRemoteMessageEvent");
3321     auto& gestureEvent = MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_REMOTE_MESSAGE_GESTURE_EVENT);
3322     if (gestureEvent.IsValid()) {
3323         LOGI("Declaration::SetRemoteMessageEvent IsValid");
3324         gestureEvent.click.eventMarker = remoteMessage;
3325         gestureEvent.click.eventMarker.SetCatchMode(false);
3326         gestureEvent.click.isRefreshed = true;
3327     }
3328 }
3329 
3330 } // namespace OHOS::Ace
3331