• 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                     LOGD("don't support animation style");
1474                     return;
1475                 }
1476 
1477                 std::vector<std::string> offsets;
1478                 StringUtils::StringSplitter(val, ' ', offsets);
1479                 if (offsets.size() == TRANSFORM_SINGLE) {
1480                     Dimension originDimensionX = TRANSFORM_ORIGIN_DEFAULT;
1481                     Dimension originDimensionY = TRANSFORM_ORIGIN_DEFAULT;
1482                     // for Enum
1483                     if (CheckTransformEnum(val)) {
1484                         auto resultX = ConvertStrToTransformOrigin(val, Axis::HORIZONTAL);
1485                         if (resultX.first) {
1486                             originDimensionX = resultX.second;
1487                         }
1488                         auto resultY = ConvertStrToTransformOrigin(val, Axis::VERTICAL);
1489                         if (resultY.first) {
1490                             originDimensionY = resultY.second;
1491                         }
1492                     } else {
1493                         // for Dimension
1494                         originDimensionX = declaration.ParseDimension(val);
1495                     }
1496                     animationStyle.tweenOption.SetTransformOrigin(originDimensionX, originDimensionY);
1497                     animationStyle.transformOriginX = originDimensionX;
1498                     animationStyle.transformOriginY = originDimensionY;
1499                 } else if (offsets.size() == TRANSFORM_DUAL) {
1500                     Dimension originDimensionX = TRANSFORM_ORIGIN_DEFAULT;
1501                     Dimension originDimensionY = TRANSFORM_ORIGIN_DEFAULT;
1502                     if (CheckTransformEnum(offsets[0])) {
1503                         auto result = ConvertStrToTransformOrigin(offsets[0], Axis::HORIZONTAL);
1504                         if (result.first) {
1505                             originDimensionX = result.second;
1506                         }
1507                     } else {
1508                         originDimensionX = declaration.ParseDimension(offsets[0]);
1509                     }
1510 
1511                     if (CheckTransformEnum(offsets[1])) {
1512                         auto result = ConvertStrToTransformOrigin(offsets[1], Axis::VERTICAL);
1513                         if (result.first) {
1514                             originDimensionY = result.second;
1515                         }
1516                     } else {
1517                         originDimensionY = declaration.ParseDimension(offsets[1]);
1518                     }
1519                     animationStyle.tweenOption.SetTransformOrigin(originDimensionX, originDimensionY);
1520                     animationStyle.transformOriginX = originDimensionX;
1521                     animationStyle.transformOriginY = originDimensionY;
1522                 }
1523                 declaration.hasTransformOriginStyle_ = true;
1524             } },
1525         { DOM_TRANSITION_DURATION,
1526             [](const std::string& value, Declaration& declaration) {
1527                 auto& pageTransitionStyle =
1528                     declaration.MaybeResetStyle<CommonPageTransitionStyle>(StyleTag::COMMON_PAGE_TRANSITION_STYLE);
1529                 if (pageTransitionStyle.IsValid()) {
1530                     if (value.find("ms") != std::string::npos) {
1531                         pageTransitionStyle.transitionDuration = StringUtils::StringToInt(value);
1532                     } else if (value.find('s') != std::string::npos) {
1533                         pageTransitionStyle.transitionDuration = StringUtils::StringToInt(value) * MS_TO_S;
1534                     } else {
1535                         // default unit is ms
1536                         pageTransitionStyle.transitionDuration = StringUtils::StringToInt(value);
1537                     }
1538                     pageTransitionStyle.transitionEnterOption.SetDuration(pageTransitionStyle.transitionDuration);
1539                     pageTransitionStyle.transitionExitOption.SetDuration(pageTransitionStyle.transitionDuration);
1540                 }
1541             } },
1542         // card transition
1543         { DOM_TRANSITION_EFFECT,
1544             [](const std::string& value, Declaration& declaration) {
1545                 declaration.hasTransitionAnimation_ = true;
1546                 auto& cardTransitionStyle =
1547                     declaration.MaybeResetStyle<CommonCardTransitionStyle>(StyleTag::COMMON_CARD_TRANSITION_STYLE);
1548                 if (cardTransitionStyle.IsValid()) {
1549                     declaration.hasTransformStyle_ = true;
1550                     cardTransitionStyle.transitionEffect = ParseTransitionEffect(value);
1551                 }
1552             } },
1553         { DOM_TRANSITION_TIMING_FUNCTION,
1554             [](const std::string& value, Declaration& declaration) {
1555                 auto& pageTransitionStyle =
1556                     declaration.MaybeResetStyle<CommonPageTransitionStyle>(StyleTag::COMMON_PAGE_TRANSITION_STYLE);
1557                 if (pageTransitionStyle.IsValid()) {
1558                     pageTransitionStyle.curve = CreateCurve(value);
1559                     pageTransitionStyle.transitionEnterOption.SetCurve(pageTransitionStyle.curve);
1560                     pageTransitionStyle.transitionExitOption.SetCurve(pageTransitionStyle.curve);
1561                 }
1562             } },
1563         { DOM_VISIBILITY,
1564             [](const std::string& value, Declaration& declaration) {
1565                 auto& visibilityStyle =
1566                     declaration.MaybeResetStyle<CommonVisibilityStyle>(StyleTag::COMMON_VISIBILITY_STYLE);
1567                 if (visibilityStyle.IsValid()) {
1568                     visibilityStyle.visibility =
1569                         (value == DOM_VISIBILITY_HIDDEN) ? VisibilityType::HIDDEN : VisibilityType::VISIBLE;
1570                     declaration.hasDisplayStyle_ = true;
1571                 }
1572             } },
1573         { DOM_WIDTH,
1574             [](const std::string& value, Declaration& declaration) {
1575                 auto& sizeStyle = declaration.MaybeResetStyle<CommonSizeStyle>(StyleTag::COMMON_SIZE_STYLE);
1576                 if (sizeStyle.IsValid()) {
1577                     sizeStyle.width = declaration.ParseCalcDimension(value);
1578                     declaration.hasBoxStyle_ = true;
1579                 }
1580             } },
1581         { DOM_WINDOW_FILTER,
1582             [](const std::string& value, Declaration& declaration) {
1583                 declaration.hasDecorationStyle_ = true;
1584                 std::vector<std::string> offsets;
1585                 StringUtils::StringSplitter(value, ' ', offsets);
1586                 // progress
1587                 if (offsets.size() >= 1) {
1588                     auto parseValue = ParseFunctionValue<Dimension>(offsets[0], DOM_BLUR, StringToDimension);
1589                     if (parseValue.Unit() == DimensionUnit::PERCENT) {
1590                         auto progress = parseValue.Value();
1591                         if (GreatNotEqual(progress, 0.0) && LessOrEqual(progress, 1.0)) {
1592                             declaration.backDecoration_->SetWindowBlurProgress(static_cast<float>(progress));
1593                         }
1594                     } else {
1595                         declaration.backDecoration_->SetWindowBlurProgress(static_cast<float>(0.0f));
1596                     }
1597                 }
1598                 // style
1599                 if (offsets.size() >= 2) {
1600                     auto windowBlurStyle = StrToWindowBlurStyle(offsets[1]);
1601                     declaration.backDecoration_->SetWindowBlurStyle(windowBlurStyle);
1602                 }
1603             } },
1604         { DOM_ZINDEX,
1605             [](const std::string& value, Declaration& declaration) {
1606                 auto& commonStyle = declaration.MaybeResetStyle<CommonStyle>(StyleTag::COMMON_STYLE);
1607                 if (commonStyle.IsValid()) {
1608                     commonStyle.zIndex = StringToInt(value);
1609                 }
1610             } },
1611     };
1612 
1613     auto operatorIter = BinarySearchFindIndex(styleSetter, ArraySize(styleSetter), style.first.c_str());
1614     if (operatorIter != -1) {
1615         styleSetter[operatorIter].value(style.second, *this);
1616     }
1617 
1618     auto& renderAttr = static_cast<CommonRenderAttribute&>(GetAttribute(AttributeTag::COMMON_RENDER_ATTR));
1619     static const std::unordered_set<std::string> displayStyleSet = { DOM_OPACITY, DOM_DISPLAY, DOM_VISIBILITY };
1620     if (displayStyleSet.find(style.first) != displayStyleSet.end() &&
1621         AceApplicationInfo::GetInstance().GetIsCardType() && renderAttr.show == "false") {
1622         SetShowAttr(renderAttr.show);
1623     }
1624 }
1625 
AddEvent(int32_t pageId,const std::string & eventId,const std::vector<std::string> & events)1626 void Declaration::AddEvent(int32_t pageId, const std::string& eventId, const std::vector<std::string>& events)
1627 {
1628     ACE_SCOPED_TRACE("Declaration::AddEvent");
1629     static const LinearMapNode<void (*)(int32_t, const std::string&, Declaration&)> eventSetters[] = {
1630         { DOM_BLUR,
1631             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1632                 auto& focusableEvent = declaration.MaybeResetEvent<CommonFocusEvent>(EventTag::COMMON_FOCUS_EVENT);
1633                 if (focusableEvent.IsValid()) {
1634                     focusableEvent.blur.eventMarker = EventMarker(eventId, DOM_BLUR, pageId);
1635                     focusableEvent.blur.isRefreshed = true;
1636                 }
1637             } },
1638         { DOM_CAPTURE_TOUCH_CANCEL,
1639             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1640                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1641                 if (rawEvent.IsValid()) {
1642                     rawEvent.captureTouchCancel.eventMarker = EventMarker(eventId, DOM_CAPTURE_TOUCH_CANCEL, pageId);
1643                     rawEvent.captureTouchCancel.isRefreshed = true;
1644                 }
1645             } },
1646         { DOM_CAPTURE_TOUCH_END,
1647             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1648                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1649                 if (rawEvent.IsValid()) {
1650                     rawEvent.captureTouchEnd.eventMarker = EventMarker(eventId, DOM_CAPTURE_TOUCH_END, pageId);
1651                     rawEvent.captureTouchEnd.isRefreshed = true;
1652                 }
1653             } },
1654         { DOM_CAPTURE_TOUCH_MOVE,
1655             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1656                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1657                 if (rawEvent.IsValid()) {
1658                     rawEvent.captureTouchMove.eventMarker = EventMarker(eventId, DOM_CAPTURE_TOUCH_MOVE, pageId);
1659                     rawEvent.captureTouchMove.isRefreshed = true;
1660                 }
1661             } },
1662         { DOM_CAPTURE_TOUCH_START,
1663             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1664                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1665                 if (rawEvent.IsValid()) {
1666                     rawEvent.captureTouchStart.eventMarker = EventMarker(eventId, DOM_CAPTURE_TOUCH_START, pageId);
1667                     rawEvent.captureTouchStart.isRefreshed = true;
1668                 }
1669             } },
1670         { DOM_CATCH_BUBBLE_CLICK,
1671             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1672                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1673                 if (gestureEvent.IsValid()) {
1674                     gestureEvent.click.eventMarker = EventMarker(eventId, DOM_CATCH_BUBBLE_CLICK, pageId);
1675                     gestureEvent.click.eventMarker.SetCatchMode(true);
1676                     gestureEvent.click.isRefreshed = true;
1677                 }
1678             } },
1679         { DOM_CATCH_BUBBLE_DOUBLE_CLICK,
1680             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1681                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1682                 if (gestureEvent.IsValid()) {
1683                     gestureEvent.doubleClick.eventMarker = EventMarker(eventId, DOM_CATCH_BUBBLE_DOUBLE_CLICK, pageId);
1684                     gestureEvent.doubleClick.eventMarker.SetCatchMode(true);
1685                     gestureEvent.doubleClick.isRefreshed = true;
1686                 }
1687             } },
1688         { DOM_CATCH_BUBBLE_LONG_PRESS,
1689             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1690                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1691                 if (gestureEvent.IsValid()) {
1692                     gestureEvent.longPress.eventMarker = EventMarker(eventId, DOM_CATCH_BUBBLE_LONG_PRESS, pageId);
1693                     gestureEvent.longPress.eventMarker.SetCatchMode(true);
1694                     gestureEvent.longPress.isRefreshed = true;
1695                 }
1696             } },
1697         { DOM_CATCH_BUBBLE_SWIPE,
1698             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1699                 auto& swipeEvent = declaration.MaybeResetEvent<CommonSwipeEvent>(EventTag::COMMON_SWIPE_EVENT);
1700                 if (swipeEvent.IsValid()) {
1701                     swipeEvent.catchBubbleSwipe.eventMarker = EventMarker(eventId, DOM_CATCH_BUBBLE_SWIPE, pageId);
1702                     swipeEvent.catchBubbleSwipe.isRefreshed = true;
1703                 }
1704             } },
1705         { DOM_CATCH_BUBBLE_TOUCH_CANCEL,
1706             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1707                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1708                 if (rawEvent.IsValid()) {
1709                     rawEvent.catchBubbleTouchCancel.eventMarker =
1710                         EventMarker(eventId, DOM_CATCH_BUBBLE_TOUCH_CANCEL, pageId);
1711                     rawEvent.catchBubbleTouchCancel.isRefreshed = true;
1712                 }
1713             } },
1714         { DOM_CATCH_BUBBLE_TOUCH_END,
1715             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1716                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1717                 if (rawEvent.IsValid()) {
1718                     rawEvent.catchBubbleTouchEnd.eventMarker = EventMarker(eventId, DOM_CATCH_BUBBLE_TOUCH_END, pageId);
1719                     rawEvent.catchBubbleTouchEnd.isRefreshed = true;
1720                 }
1721             } },
1722         { DOM_CATCH_BUBBLE_TOUCH_MOVE,
1723             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1724                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1725                 if (rawEvent.IsValid()) {
1726                     rawEvent.catchBubbleTouchMove.eventMarker =
1727                         EventMarker(eventId, DOM_CATCH_BUBBLE_TOUCH_MOVE, pageId);
1728                     rawEvent.catchBubbleTouchMove.isRefreshed = true;
1729                 }
1730             } },
1731         { DOM_CATCH_BUBBLE_TOUCH_START,
1732             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1733                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1734                 if (rawEvent.IsValid()) {
1735                     rawEvent.catchBubbleTouchStart.eventMarker =
1736                         EventMarker(eventId, DOM_CATCH_BUBBLE_TOUCH_START, pageId);
1737                     rawEvent.catchBubbleTouchStart.isRefreshed = true;
1738                 }
1739             } },
1740         { DOM_CATCH_CAPTURE_TOUCH_CANCEL,
1741             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1742                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1743                 if (rawEvent.IsValid()) {
1744                     rawEvent.catchCaptureTouchCancel.eventMarker =
1745                         EventMarker(eventId, DOM_CATCH_CAPTURE_TOUCH_CANCEL, pageId);
1746                     rawEvent.catchCaptureTouchCancel.isRefreshed = true;
1747                 }
1748             } },
1749         { DOM_CATCH_CAPTURE_TOUCH_END,
1750             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1751                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1752                 if (rawEvent.IsValid()) {
1753                     rawEvent.catchCaptureTouchEnd.eventMarker =
1754                         EventMarker(eventId, DOM_CATCH_CAPTURE_TOUCH_END, pageId);
1755                     rawEvent.catchCaptureTouchEnd.isRefreshed = true;
1756                 }
1757             } },
1758         { DOM_CATCH_CAPTURE_TOUCH_MOVE,
1759             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1760                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1761                 if (rawEvent.IsValid()) {
1762                     rawEvent.catchCaptureTouchMove.eventMarker =
1763                         EventMarker(eventId, DOM_CATCH_CAPTURE_TOUCH_MOVE, pageId);
1764                     rawEvent.catchCaptureTouchMove.isRefreshed = true;
1765                 }
1766             } },
1767         { DOM_CATCH_CAPTURE_TOUCH_START,
1768             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1769                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1770                 if (rawEvent.IsValid()) {
1771                     rawEvent.catchCaptureTouchStart.eventMarker =
1772                         EventMarker(eventId, DOM_CATCH_CAPTURE_TOUCH_START, pageId);
1773                     rawEvent.catchCaptureTouchStart.isRefreshed = true;
1774                 }
1775             } },
1776         { DOM_CLICK,
1777             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1778                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1779                 if (gestureEvent.IsValid()) {
1780                     gestureEvent.click.eventMarker = EventMarker(eventId, DOM_CLICK, pageId);
1781                     gestureEvent.click.eventMarker.SetCatchMode(false);
1782                     gestureEvent.click.isRefreshed = true;
1783                 }
1784             } },
1785         { DOM_DOUBLE_CLICK,
1786             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1787                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1788                 if (gestureEvent.IsValid()) {
1789                     gestureEvent.doubleClick.eventMarker = EventMarker(eventId, DOM_DOUBLE_CLICK, pageId);
1790                     gestureEvent.doubleClick.eventMarker.SetCatchMode(false);
1791                     gestureEvent.doubleClick.isRefreshed = true;
1792                 }
1793             } },
1794         { DOM_DRAG,
1795             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1796                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1797                 if (gestureEvent.IsValid()) {
1798                     gestureEvent.drag.eventMarker = EventMarker(eventId, DOM_DRAG, pageId);
1799                     gestureEvent.drag.isRefreshed = true;
1800                 }
1801             } },
1802         { DOM_DRAG_END,
1803             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1804                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1805                 if (gestureEvent.IsValid()) {
1806                     gestureEvent.dragEnd.eventMarker = EventMarker(eventId, DOM_DRAG_END, pageId);
1807                     gestureEvent.dragEnd.isRefreshed = true;
1808                 }
1809             } },
1810         { DOM_DRAG_ENTER,
1811             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1812                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1813                 if (gestureEvent.IsValid()) {
1814                     gestureEvent.dragEnter.eventMarker = EventMarker(eventId, DOM_DRAG_ENTER, pageId);
1815                     gestureEvent.dragEnter.isRefreshed = true;
1816                 }
1817             } },
1818         { DOM_DRAG_LEAVE,
1819             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1820                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1821                 if (gestureEvent.IsValid()) {
1822                     gestureEvent.dragLeave.eventMarker = EventMarker(eventId, DOM_DRAG_LEAVE, pageId);
1823                     gestureEvent.dragLeave.isRefreshed = true;
1824                 }
1825             } },
1826         { DOM_DRAG_OVER,
1827             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1828                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1829                 if (gestureEvent.IsValid()) {
1830                     gestureEvent.dragOver.eventMarker = EventMarker(eventId, DOM_DRAG_OVER, pageId);
1831                     gestureEvent.dragOver.isRefreshed = true;
1832                 }
1833             } },
1834         { DOM_DRAG_START,
1835             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1836                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1837                 if (gestureEvent.IsValid()) {
1838                     gestureEvent.dragStart.eventMarker = EventMarker(eventId, DOM_DRAG_START, pageId);
1839                     gestureEvent.dragStart.isRefreshed = true;
1840                 }
1841             } },
1842         { DOM_DRAG_DROP,
1843             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1844                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1845                 if (gestureEvent.IsValid()) {
1846                     gestureEvent.dragDrop.eventMarker = EventMarker(eventId, DOM_DRAG_DROP, pageId);
1847                     gestureEvent.dragDrop.isRefreshed = true;
1848                 }
1849             } },
1850         { DOM_FOCUS,
1851             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1852                 auto& focusEvent = declaration.MaybeResetEvent<CommonFocusEvent>(EventTag::COMMON_FOCUS_EVENT);
1853                 if (focusEvent.IsValid()) {
1854                     focusEvent.focus.eventMarker = EventMarker(eventId, DOM_FOCUS, pageId);
1855                     focusEvent.focus.isRefreshed = true;
1856                 }
1857             } },
1858         { DOM_HOVER,
1859             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1860                 auto& mouseEvent = declaration.MaybeResetEvent<CommonMouseEvent>(EventTag::COMMON_MOUSE_EVENT);
1861                 if (mouseEvent.IsValid()) {
1862                     mouseEvent.mouseHover.eventMarker = EventMarker(eventId, DOM_HOVER, pageId);
1863                     mouseEvent.mouseHover.isRefreshed = true;
1864                 }
1865             } },
1866         { DOM_KEY,
1867             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1868                 auto& keyEvent = declaration.MaybeResetEvent<CommonKeyEvent>(EventTag::COMMON_KEY_EVENT);
1869                 if (keyEvent.IsValid()) {
1870                     keyEvent.key.eventMarker = EventMarker(eventId, DOM_KEY, pageId);
1871                     keyEvent.key.isRefreshed = true;
1872                 }
1873             } },
1874         { DOM_LONG_PRESS,
1875             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1876                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1877                 if (gestureEvent.IsValid()) {
1878                     gestureEvent.longPress.eventMarker = EventMarker(eventId, DOM_LONG_PRESS, pageId);
1879                     gestureEvent.longPress.eventMarker.SetCatchMode(false);
1880                     gestureEvent.longPress.isRefreshed = true;
1881                 }
1882             } },
1883         { DOM_MOUSE,
1884             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1885                 auto& mouseEvent = declaration.MaybeResetEvent<CommonMouseEvent>(EventTag::COMMON_MOUSE_EVENT);
1886                 if (mouseEvent.IsValid()) {
1887                     mouseEvent.mouse.eventMarker = EventMarker(eventId, DOM_MOUSE, pageId);
1888                     mouseEvent.mouse.isRefreshed = true;
1889                 }
1890             } },
1891         { DOM_PINCH_CANCEL,
1892             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1893                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1894                 if (gestureEvent.IsValid()) {
1895                     gestureEvent.pinchCancel.eventMarker = EventMarker(eventId, DOM_PINCH_CANCEL, pageId);
1896                     gestureEvent.pinchCancel.isRefreshed = true;
1897                 }
1898             } },
1899         { DOM_PINCH_END,
1900             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1901                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1902                 if (gestureEvent.IsValid()) {
1903                     gestureEvent.pinchEnd.eventMarker = EventMarker(eventId, DOM_PINCH_END, pageId);
1904                     gestureEvent.pinchEnd.isRefreshed = true;
1905                 }
1906             } },
1907         { DOM_PINCH_START,
1908             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1909                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1910                 if (gestureEvent.IsValid()) {
1911                     gestureEvent.pinchStart.eventMarker = EventMarker(eventId, DOM_PINCH_START, pageId);
1912                     gestureEvent.pinchStart.isRefreshed = true;
1913                 }
1914             } },
1915         { DOM_PINCH_UPDATE,
1916             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1917                 auto& gestureEvent = declaration.MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
1918                 if (gestureEvent.IsValid()) {
1919                     gestureEvent.pinchUpdate.eventMarker = EventMarker(eventId, DOM_PINCH_UPDATE, pageId);
1920                     gestureEvent.pinchUpdate.isRefreshed = true;
1921                 }
1922             } },
1923         { DOM_CROWN_ROTATE,
1924             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1925                 auto& crownEvent = declaration.MaybeResetEvent<CommonCrownEvent>(EventTag::COMMON_CROWN_EVENT);
1926                 if (crownEvent.IsValid()) {
1927                     crownEvent.rotate.eventMarker = EventMarker(eventId, DOM_CROWN_ROTATE, pageId);
1928                     crownEvent.rotate.isRefreshed = true;
1929                 }
1930             } },
1931         { DOM_SWIPE,
1932             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1933                 auto& swipeEvent = declaration.MaybeResetEvent<CommonSwipeEvent>(EventTag::COMMON_SWIPE_EVENT);
1934                 if (swipeEvent.IsValid()) {
1935                     swipeEvent.swipe.eventMarker = EventMarker(eventId, DOM_SWIPE, pageId);
1936                     swipeEvent.swipe.eventMarker.SetCatchMode(false);
1937                     swipeEvent.swipe.isRefreshed = true;
1938                 }
1939             } },
1940         { DOM_TOUCH_CANCEL,
1941             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1942                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1943                 if (rawEvent.IsValid()) {
1944                     rawEvent.touchCancel.eventMarker = EventMarker(eventId, DOM_TOUCH_CANCEL, pageId);
1945                     rawEvent.touchCancel.isRefreshed = true;
1946                 }
1947             } },
1948         { DOM_TOUCH_END,
1949             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1950                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1951                 if (rawEvent.IsValid()) {
1952                     rawEvent.touchEnd.eventMarker = EventMarker(eventId, DOM_TOUCH_END, pageId);
1953                     rawEvent.touchEnd.isRefreshed = true;
1954                 }
1955             } },
1956         { DOM_TOUCH_MOVE,
1957             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1958                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1959                 if (rawEvent.IsValid()) {
1960                     rawEvent.touchMove.eventMarker = EventMarker(eventId, DOM_TOUCH_MOVE, pageId);
1961                     rawEvent.touchMove.isRefreshed = true;
1962                 }
1963             } },
1964         { DOM_TOUCH_START,
1965             [](int32_t pageId, const std::string& eventId, Declaration& declaration) {
1966                 auto& rawEvent = declaration.MaybeResetEvent<CommonRawEvent>(EventTag::COMMON_RAW_EVENT);
1967                 if (rawEvent.IsValid()) {
1968                     rawEvent.touchStart.eventMarker = EventMarker(eventId, DOM_TOUCH_START, pageId);
1969                     rawEvent.touchStart.isRefreshed = true;
1970                 }
1971             } },
1972     };
1973     for (const auto& event : events) {
1974         if (SetSpecializedEvent(pageId, eventId, event)) {
1975             continue;
1976         }
1977         auto setterIter = BinarySearchFindIndex(eventSetters, ArraySize(eventSetters), event.c_str());
1978         if (setterIter != -1) {
1979             eventSetters[setterIter].value(pageId, eventId, *this);
1980         }
1981     }
1982 }
1983 
CallMethod(const std::string & method,const std::string & args)1984 void Declaration::CallMethod(const std::string& method, const std::string& args)
1985 {
1986     if (method == COMMON_METHOD_FOCUS) {
1987         if (!focusableController_) {
1988             LOGE("CallMethod: call focus method failed, focusableController_ is null");
1989             return;
1990         }
1991 
1992         bool shouldFocus = true;
1993         std::unique_ptr<JsonValue> argsValue = JsonUtil::ParseJsonString(args);
1994         if (argsValue && argsValue->IsArray() && argsValue->GetArraySize() == COMMON_METHOD_FOCUS_ARGS_SIZE) {
1995             std::unique_ptr<JsonValue> focusValue = argsValue->GetArrayItem(0)->GetValue(COMMON_METHOD_FOCUS);
1996             if (focusValue && focusValue->IsBool()) {
1997                 shouldFocus = focusValue->GetBool();
1998             }
1999         }
2000         OnRequestFocus(shouldFocus);
2001     } else if (method == DOM_LIST_METHOD_SCROLL_BY) {
2002         std::unique_ptr<JsonValue> argsValue = JsonUtil::ParseJsonString(args);
2003         if (!argsValue || !argsValue->IsArray() || argsValue->GetArraySize() != 1) {
2004             LOGE("parse args error");
2005             return;
2006         }
2007         std::unique_ptr<JsonValue> scrollByPara = argsValue->GetArrayItem(0);
2008         double x = scrollByPara->GetDouble("dx", 0.0);
2009         double y = scrollByPara->GetDouble("dy", 0.0);
2010         bool isSmooth = scrollByPara->GetBool("smooth", true);
2011         OnScrollBy(x, y, isSmooth);
2012     } else {
2013         CallSpecializedMethod(method, args);
2014     }
2015 }
2016 
OnRequestFocus(bool shouldFocus)2017 void Declaration::OnRequestFocus(bool shouldFocus)
2018 {
2019     auto& commonMethod = MaybeResetMethod<CommonMethod>(MethodTag::COMMON_METHOD);
2020     if (commonMethod.IsValid()) {
2021         commonMethod.Focus(focusableController_, shouldFocus);
2022     }
2023 }
2024 
OnScrollBy(double dx,double dy,bool isSmooth)2025 void Declaration::OnScrollBy(double dx, double dy, bool isSmooth)
2026 {
2027     auto& commonMethod = MaybeResetMethod<CommonMethod>(MethodTag::COMMON_METHOD);
2028     if (commonMethod.IsValid()) {
2029         commonMethod.ScrollBy(positionController_, dx, dy, isSmooth);
2030     }
2031 }
2032 
SetPaddingOverall(const std::string & value,Declaration & declaration)2033 void Declaration::SetPaddingOverall(const std::string& value, Declaration& declaration)
2034 {
2035     auto& paddingStyle = declaration.MaybeResetStyle<CommonPaddingStyle>(StyleTag::COMMON_PADDING_STYLE);
2036     if (!paddingStyle.IsValid()) {
2037         LOGD("don't support padding");
2038         return;
2039     }
2040 
2041     std::vector<std::string> offsets;
2042     StringUtils::StringSplitter(value, ' ', offsets);
2043     switch (offsets.size()) {
2044         case 1:
2045             paddingStyle.padding.SetLeft(declaration.ParseDimension(offsets[0]));
2046             paddingStyle.padding.SetRight(declaration.ParseDimension(offsets[0]));
2047             paddingStyle.padding.SetTop(declaration.ParseDimension(offsets[0]));
2048             paddingStyle.padding.SetBottom(declaration.ParseDimension(offsets[0]));
2049             break;
2050         case 2:
2051             paddingStyle.padding.SetLeft(declaration.ParseDimension(offsets[1]));
2052             paddingStyle.padding.SetRight(declaration.ParseDimension(offsets[1]));
2053             paddingStyle.padding.SetTop(declaration.ParseDimension(offsets[0]));
2054             paddingStyle.padding.SetBottom(declaration.ParseDimension(offsets[0]));
2055             break;
2056         case 3:
2057             paddingStyle.padding.SetLeft(declaration.ParseDimension(offsets[1]));
2058             paddingStyle.padding.SetRight(declaration.ParseDimension(offsets[1]));
2059             paddingStyle.padding.SetTop(declaration.ParseDimension(offsets[0]));
2060             paddingStyle.padding.SetBottom(declaration.ParseDimension(offsets[2]));
2061             break;
2062         case 4:
2063             paddingStyle.padding.SetLeft(declaration.ParseDimension(offsets[3]));
2064             paddingStyle.padding.SetRight(declaration.ParseDimension(offsets[1]));
2065             paddingStyle.padding.SetTop(declaration.ParseDimension(offsets[0]));
2066             paddingStyle.padding.SetBottom(declaration.ParseDimension(offsets[2]));
2067             break;
2068         default:
2069             break;
2070     }
2071     declaration.hasBoxStyle_ = true;
2072 }
2073 
SetMarginOverall(const std::string & value,Declaration & declaration)2074 void Declaration::SetMarginOverall(const std::string& value, Declaration& declaration)
2075 {
2076     auto& marginStyle = declaration.MaybeResetStyle<CommonMarginStyle>(StyleTag::COMMON_MARGIN_STYLE);
2077     if (!marginStyle.IsValid()) {
2078         LOGD("don't support margin");
2079         return;
2080     }
2081 
2082     std::vector<std::string> offsets;
2083     StringUtils::StringSplitter(value, ' ', offsets);
2084     switch (offsets.size()) {
2085         case 1:
2086             marginStyle.margin.SetLeft(declaration.ParseDimension(offsets[0]));
2087             marginStyle.margin.SetRight(declaration.ParseDimension(offsets[0]));
2088             marginStyle.margin.SetTop(declaration.ParseDimension(offsets[0]));
2089             marginStyle.margin.SetBottom(declaration.ParseDimension(offsets[0]));
2090             break;
2091         case 2:
2092             marginStyle.margin.SetLeft(declaration.ParseDimension(offsets[1]));
2093             marginStyle.margin.SetRight(declaration.ParseDimension(offsets[1]));
2094             marginStyle.margin.SetTop(declaration.ParseDimension(offsets[0]));
2095             marginStyle.margin.SetBottom(declaration.ParseDimension(offsets[0]));
2096             break;
2097         case 3:
2098             marginStyle.margin.SetLeft(declaration.ParseDimension(offsets[1]));
2099             marginStyle.margin.SetRight(declaration.ParseDimension(offsets[1]));
2100             marginStyle.margin.SetTop(declaration.ParseDimension(offsets[0]));
2101             marginStyle.margin.SetBottom(declaration.ParseDimension(offsets[2]));
2102             break;
2103         case 4:
2104             marginStyle.margin.SetLeft(declaration.ParseDimension(offsets[3]));
2105             marginStyle.margin.SetRight(declaration.ParseDimension(offsets[1]));
2106             marginStyle.margin.SetTop(declaration.ParseDimension(offsets[0]));
2107             marginStyle.margin.SetBottom(declaration.ParseDimension(offsets[2]));
2108             break;
2109         default:
2110             break;
2111     }
2112     declaration.hasBoxStyle_ = true;
2113 }
2114 
SetBorderImageWidthForFourEdges(const std::string & value,Declaration & declaration)2115 void Declaration::SetBorderImageWidthForFourEdges(const std::string& value, Declaration& declaration)
2116 {
2117     auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
2118     std::vector<std::string> offsets;
2119     StringUtils::StringSplitter(value, ' ', offsets);
2120     switch (offsets.size()) {
2121         case 1:
2122             borderStyle.border.SetBorderImageWidth(declaration.ParseDimension(offsets[0]), BorderImageDirection::TOP);
2123             borderStyle.border.SetBorderImageWidth(declaration.ParseDimension(offsets[0]),
2124                 BorderImageDirection::BOTTOM);
2125             borderStyle.border.SetBorderImageWidth(declaration.ParseDimension(offsets[0]), BorderImageDirection::LEFT);
2126             borderStyle.border.SetBorderImageWidth(declaration.ParseDimension(offsets[0]), BorderImageDirection::RIGHT);
2127             declaration.backDecoration_->SetHasBorderImageWidth(true);
2128             break;
2129         case 2:
2130             borderStyle.border.SetBorderImageWidth(declaration.ParseDimension(offsets[0]), BorderImageDirection::TOP);
2131             borderStyle.border.SetBorderImageWidth(declaration.ParseDimension(offsets[0]),
2132                 BorderImageDirection::BOTTOM);
2133             borderStyle.border.SetBorderImageWidth(declaration.ParseDimension(offsets[1]), BorderImageDirection::LEFT);
2134             borderStyle.border.SetBorderImageWidth(declaration.ParseDimension(offsets[1]), BorderImageDirection::RIGHT);
2135             declaration.backDecoration_->SetHasBorderImageWidth(true);
2136             break;
2137         case 3:
2138             borderStyle.border.SetBorderImageWidth(declaration.ParseDimension(offsets[0]), BorderImageDirection::TOP);
2139             borderStyle.border.SetBorderImageWidth(declaration.ParseDimension(offsets[2]),
2140                 BorderImageDirection::BOTTOM);
2141             borderStyle.border.SetBorderImageWidth(declaration.ParseDimension(offsets[1]), BorderImageDirection::LEFT);
2142             borderStyle.border.SetBorderImageWidth(declaration.ParseDimension(offsets[1]), BorderImageDirection::RIGHT);
2143             declaration.backDecoration_->SetHasBorderImageWidth(true);
2144             break;
2145         case 4:
2146             borderStyle.border.SetBorderImageWidth(declaration.ParseDimension(offsets[0]), BorderImageDirection::TOP);
2147             borderStyle.border.SetBorderImageWidth(declaration.ParseDimension(offsets[2]),
2148                 BorderImageDirection::BOTTOM);
2149             borderStyle.border.SetBorderImageWidth(declaration.ParseDimension(offsets[1]), BorderImageDirection::LEFT);
2150             borderStyle.border.SetBorderImageWidth(declaration.ParseDimension(offsets[3]), BorderImageDirection::RIGHT);
2151             declaration.backDecoration_->SetHasBorderImageWidth(true);
2152             break;
2153         default:
2154             borderStyle.border.SetBorderImageWidth(declaration.ParseDimension(value), BorderImageDirection::TOP);
2155             borderStyle.border.SetBorderImageWidth(declaration.ParseDimension(value),
2156                 BorderImageDirection::BOTTOM);
2157             borderStyle.border.SetBorderImageWidth(declaration.ParseDimension(value), BorderImageDirection::LEFT);
2158             borderStyle.border.SetBorderImageWidth(declaration.ParseDimension(value), BorderImageDirection::RIGHT);
2159             declaration.backDecoration_->SetHasBorderImageWidth(false);
2160             break;
2161     }
2162     declaration.hasDecorationStyle_ = true;
2163     declaration.hasBorderStyle_ = true;
2164 }
2165 
SetBorderImageSliceForFourEdges(const std::string & value,Declaration & declaration)2166 void Declaration::SetBorderImageSliceForFourEdges(const std::string& value, Declaration& declaration)
2167 {
2168     auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
2169     std::vector<std::string> offsets;
2170     StringUtils::StringSplitter(value, ' ', offsets);
2171     switch (offsets.size()) {
2172         case 1:
2173             borderStyle.border.SetBorderImageSlice(declaration.ParseDimension(offsets[0]), BorderImageDirection::LEFT);
2174             borderStyle.border.SetBorderImageSlice(declaration.ParseDimension(offsets[0]), BorderImageDirection::TOP);
2175             borderStyle.border.SetBorderImageSlice(declaration.ParseDimension(offsets[0]), BorderImageDirection::RIGHT);
2176             borderStyle.border.SetBorderImageSlice(declaration.ParseDimension(offsets[0]),
2177                 BorderImageDirection::BOTTOM);
2178             declaration.backDecoration_->SetHasBorderImageSlice(true);
2179             break;
2180         case 2:
2181             borderStyle.border.SetBorderImageSlice(declaration.ParseDimension(offsets[1]), BorderImageDirection::LEFT);
2182             borderStyle.border.SetBorderImageSlice(declaration.ParseDimension(offsets[0]), BorderImageDirection::TOP);
2183             borderStyle.border.SetBorderImageSlice(declaration.ParseDimension(offsets[1]), BorderImageDirection::RIGHT);
2184             borderStyle.border.SetBorderImageSlice(declaration.ParseDimension(offsets[0]),
2185                 BorderImageDirection::BOTTOM);
2186             declaration.backDecoration_->SetHasBorderImageSlice(true);
2187             break;
2188         case 3:
2189             borderStyle.border.SetBorderImageSlice(declaration.ParseDimension(offsets[1]), BorderImageDirection::LEFT);
2190             borderStyle.border.SetBorderImageSlice(declaration.ParseDimension(offsets[0]), BorderImageDirection::TOP);
2191             borderStyle.border.SetBorderImageSlice(declaration.ParseDimension(offsets[1]), BorderImageDirection::RIGHT);
2192             borderStyle.border.SetBorderImageSlice(declaration.ParseDimension(offsets[2]),
2193                 BorderImageDirection::BOTTOM);
2194             declaration.backDecoration_->SetHasBorderImageSlice(true);
2195             break;
2196         case 4:
2197             borderStyle.border.SetBorderImageSlice(declaration.ParseDimension(offsets[3]), BorderImageDirection::LEFT);
2198             borderStyle.border.SetBorderImageSlice(declaration.ParseDimension(offsets[0]), BorderImageDirection::TOP);
2199             borderStyle.border.SetBorderImageSlice(declaration.ParseDimension(offsets[1]), BorderImageDirection::RIGHT);
2200             borderStyle.border.SetBorderImageSlice(declaration.ParseDimension(offsets[2]),
2201                 BorderImageDirection::BOTTOM);
2202             declaration.backDecoration_->SetHasBorderImageSlice(true);
2203             break;
2204         default:
2205             borderStyle.border.SetBorderImageSlice(declaration.ParseDimension(value), BorderImageDirection::LEFT);
2206             borderStyle.border.SetBorderImageSlice(declaration.ParseDimension(value), BorderImageDirection::TOP);
2207             borderStyle.border.SetBorderImageSlice(declaration.ParseDimension(value), BorderImageDirection::RIGHT);
2208             borderStyle.border.SetBorderImageSlice(declaration.ParseDimension(value),
2209                 BorderImageDirection::BOTTOM);
2210             declaration.backDecoration_->SetHasBorderImageSlice(false);
2211             break;
2212     }
2213     declaration.hasDecorationStyle_ = true;
2214     declaration.hasBorderStyle_ = true;
2215 }
2216 
SetBorderImageOutSetForFourEdges(const std::string & value,Declaration & declaration)2217 void Declaration::SetBorderImageOutSetForFourEdges(const std::string& value, Declaration& declaration)
2218 {
2219     auto& bs = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
2220     std::vector<std::string> offsets;
2221     StringUtils::StringSplitter(value, ' ', offsets);
2222     switch (offsets.size()) {
2223         case 1:
2224             bs.border.SetBorderImageOutset(declaration.ParseDimension(offsets[0]), BorderImageDirection::LEFT);
2225             bs.border.SetBorderImageOutset(declaration.ParseDimension(offsets[0]), BorderImageDirection::TOP);
2226             bs.border.SetBorderImageOutset(declaration.ParseDimension(offsets[0]), BorderImageDirection::RIGHT);
2227             bs.border.SetBorderImageOutset(declaration.ParseDimension(offsets[0]), BorderImageDirection::BOTTOM);
2228             declaration.backDecoration_->SetHasBorderImageOutset(true);
2229             break;
2230         case 2:
2231             bs.border.SetBorderImageOutset(declaration.ParseDimension(offsets[1]), BorderImageDirection::LEFT);
2232             bs.border.SetBorderImageOutset(declaration.ParseDimension(offsets[0]), BorderImageDirection::TOP);
2233             bs.border.SetBorderImageOutset(declaration.ParseDimension(offsets[1]), BorderImageDirection::RIGHT);
2234             bs.border.SetBorderImageOutset(declaration.ParseDimension(offsets[0]), BorderImageDirection::BOTTOM);
2235             declaration.backDecoration_->SetHasBorderImageOutset(true);
2236             break;
2237         case 3:
2238             bs.border.SetBorderImageOutset(declaration.ParseDimension(offsets[1]), BorderImageDirection::LEFT);
2239             bs.border.SetBorderImageOutset(declaration.ParseDimension(offsets[0]), BorderImageDirection::TOP);
2240             bs.border.SetBorderImageOutset(declaration.ParseDimension(offsets[1]), BorderImageDirection::RIGHT);
2241             bs.border.SetBorderImageOutset(declaration.ParseDimension(offsets[2]), BorderImageDirection::BOTTOM);
2242             declaration.backDecoration_->SetHasBorderImageOutset(true);
2243             break;
2244         case 4:
2245             bs.border.SetBorderImageOutset(declaration.ParseDimension(offsets[3]), BorderImageDirection::LEFT);
2246             bs.border.SetBorderImageOutset(declaration.ParseDimension(offsets[0]), BorderImageDirection::TOP);
2247             bs.border.SetBorderImageOutset(declaration.ParseDimension(offsets[1]), BorderImageDirection::RIGHT);
2248             bs.border.SetBorderImageOutset(declaration.ParseDimension(offsets[2]), BorderImageDirection::BOTTOM);
2249             declaration.backDecoration_->SetHasBorderImageOutset(true);
2250             break;
2251         default:
2252             bs.border.SetBorderImageOutset(declaration.ParseDimension(value), BorderImageDirection::LEFT);
2253             bs.border.SetBorderImageOutset(declaration.ParseDimension(value), BorderImageDirection::TOP);
2254             bs.border.SetBorderImageOutset(declaration.ParseDimension(value), BorderImageDirection::RIGHT);
2255             bs.border.SetBorderImageOutset(declaration.ParseDimension(value), BorderImageDirection::BOTTOM);
2256             declaration.backDecoration_->SetHasBorderImageOutset(false);
2257             break;
2258     }
2259     declaration.hasDecorationStyle_ = true;
2260     declaration.hasBorderStyle_ = true;
2261 }
2262 
SetBorderImageRepeatForFourEdges(const std::string & value,Declaration & declaration)2263 void Declaration::SetBorderImageRepeatForFourEdges(const std::string& value, Declaration& declaration)
2264 {
2265     auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
2266     borderStyle.border.SetBorderImageRepeat(ConvertStrToBorderImageRepeat(value));
2267     borderStyle.border.SetBorderImageRepeat(ConvertStrToBorderImageRepeat(value));
2268     borderStyle.border.SetBorderImageRepeat(ConvertStrToBorderImageRepeat(value));
2269     borderStyle.border.SetBorderImageRepeat(ConvertStrToBorderImageRepeat(value));
2270     declaration.backDecoration_->SetHasBorderImageRepeat(true);
2271     declaration.hasDecorationStyle_ = true;
2272     declaration.hasBorderStyle_ = true;
2273 }
2274 
SetBorderImage(const std::string & value,Declaration & declaration)2275 void Declaration::SetBorderImage(const std::string& value, Declaration& declaration)
2276 {
2277     declaration.backDecoration_->SetHasBorderImageSource(false);
2278     declaration.backDecoration_->SetHasBorderImageGradient(false);
2279     SetBorderImageSliceForFourEdges("", declaration);
2280     SetBorderImageWidthForFourEdges("", declaration);
2281     SetBorderImageOutSetForFourEdges("", declaration);
2282     SetBorderImageRepeatForFourEdges("", declaration);
2283 
2284     auto borderImageJson = JsonUtil::ParseJsonString(value);
2285     if (!borderImageJson->IsObject()) {
2286         LOGE("borderImageJson json is not Object");
2287         return;
2288     }
2289     if (borderImageJson->Contains(DOM_VALUES) && borderImageJson->GetValue(DOM_VALUES)->IsArray() &&
2290         borderImageJson->GetValue(DOM_VALUES)->GetArraySize() > 0) {
2291 
2292         auto values = borderImageJson->GetValue(DOM_VALUES)->GetArrayItem(0);
2293 
2294         if (values->Contains("url")) {
2295             SetBorderImageUrl(values, declaration);
2296         } else {
2297             SetBorderImageGradient(values, declaration);
2298         }
2299     }
2300 }
2301 
SetBorderImageGradient(const std::unique_ptr<JsonValue> & values,Declaration & declaration)2302 void Declaration::SetBorderImageGradient(const std::unique_ptr<JsonValue>& values, Declaration& declaration)
2303 {
2304     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2305     backgroundStyle.gradientBorderImage = Gradient();
2306     if (values->Contains(DOM_GRADIENT_TYPE) && values->GetValue(DOM_GRADIENT_TYPE)->IsString()) {
2307         SetBorderImageGradientType(values->GetValue(DOM_GRADIENT_TYPE)->GetString(), declaration);
2308     }
2309     if (values->Contains(DOM_GRADIENT_DIRECTIONS) && values->GetValue(DOM_GRADIENT_DIRECTIONS)->IsArray()) {
2310         SetBorderImageGradientDirections(values->GetValue(DOM_GRADIENT_DIRECTIONS), declaration);
2311     }
2312     if (values->Contains(DOM_GRADIENT_VALUES) && values->GetValue(DOM_GRADIENT_VALUES)->IsArray()) {
2313         SetBorderImageGradientColor(values->GetValue(DOM_GRADIENT_VALUES), declaration);
2314     }
2315     if (values->Contains("slice") && values->GetValue("slice")->IsArray()) {
2316         std::unique_ptr<JsonValue> sliceItem = values->GetValue("slice");
2317         std::string sliceStr;
2318         for (int32_t i = 0; i < sliceItem->GetArraySize(); i++) {
2319             sliceStr += sliceItem->GetArrayItem(i)->GetString() + " ";
2320         }
2321         SetBorderImageSliceForFourEdges(sliceStr, declaration);
2322     }
2323     declaration.backDecoration_->SetHasBorderImageGradient(true);
2324     declaration.hasDecorationStyle_ = true;
2325     declaration.hasBorderStyle_ = true;
2326 }
2327 
SetBorderImageUrl(const std::unique_ptr<JsonValue> & values,Declaration & declaration)2328 void Declaration::SetBorderImageUrl(const std::unique_ptr<JsonValue>& values, Declaration& declaration)
2329 {
2330     if (values->Contains("url") && values->GetValue("url")->IsString()) {
2331         SetBorderImageFindUrl(values->GetValue("url")->GetString(), declaration);
2332     }
2333     if (values->Contains("slice") && values->GetValue("slice")->IsArray()) {
2334         std::unique_ptr<JsonValue> sliceItem = values->GetValue("slice");
2335         std::string sliceStr;
2336         for (int32_t i = 0; i < sliceItem->GetArraySize(); i++) {
2337             sliceStr += sliceItem->GetArrayItem(i)->GetString() + " ";
2338         }
2339         SetBorderImageSliceForFourEdges(sliceStr, declaration);
2340     }
2341     if (values->Contains("width") && values->GetValue("width")->IsArray()) {
2342         std::unique_ptr<JsonValue> widthItem = values->GetValue("width");
2343 
2344         std::string widthStr;
2345         for (int32_t i = 0; i < widthItem->GetArraySize(); i++) {
2346             widthStr += widthItem->GetArrayItem(i)->GetString() + " ";
2347         }
2348         SetBorderImageWidthForFourEdges(widthStr, declaration);
2349     }
2350     if (values->Contains("outset") && values->GetValue("outset")->IsArray()) {
2351         std::unique_ptr<JsonValue> outsetItem = values->GetValue("outset");
2352 
2353         std::string outsetStr;
2354         for (int32_t i = 0; i < outsetItem->GetArraySize(); i++) {
2355             outsetStr += outsetItem->GetArrayItem(i)->GetString() + " ";
2356         }
2357         SetBorderImageOutSetForFourEdges(outsetStr, declaration);
2358     }
2359     if (values->Contains("repeat") && values->GetValue("repeat")->IsString()) {
2360         SetBorderImageRepeatForFourEdges(values->GetValue("repeat")->GetString(), declaration);
2361     }
2362     declaration.hasDecorationStyle_ = true;
2363     declaration.hasBorderStyle_ = true;
2364 }
2365 
SetBorderImageFindUrl(const std::string & value,Declaration & declaration)2366 void Declaration::SetBorderImageFindUrl(const std::string& value, Declaration& declaration)
2367 {
2368     auto& backgroundStyle =
2369                     declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2370     if (backgroundStyle.IsValid()) {
2371         backgroundStyle.borderImage->SetSrc(value);
2372         declaration.backDecoration_->SetBorderImage(backgroundStyle.borderImage);
2373         declaration.backDecoration_->SetHasBorderImageSource(true);
2374         declaration.hasDecorationStyle_ = true;
2375     }
2376 }
2377 
SetBorderImageGradientType(const std::string & gradientType,Declaration & declaration)2378 void Declaration::SetBorderImageGradientType(const std::string& gradientType, Declaration& declaration)
2379 {
2380     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2381     if (!backgroundStyle.IsValid()) {
2382         return;
2383     }
2384     // default: LINEAR
2385     backgroundStyle.gradientBorderImage.SetType(GradientType::LINEAR);
2386     if (gradientType == DOM_RADIAL_GRADIENT || gradientType == DOM_REPEATING_RADIAL_GRADIENT) {
2387         backgroundStyle.gradientBorderImage.SetType(GradientType::RADIAL);
2388     } else if (gradientType == DOM_SWEEP_GRADIENT || gradientType == DOM_REPEATING_SWEEP_GRADIENT) {
2389         backgroundStyle.gradientBorderImage.SetType(GradientType::SWEEP);
2390     }
2391 
2392     if (gradientType == DOM_REPEATING_LINEAR_GRADIENT || gradientType == DOM_REPEATING_RADIAL_GRADIENT ||
2393         gradientType == DOM_REPEATING_SWEEP_GRADIENT) {
2394         backgroundStyle.gradientBorderImage.SetRepeat(true);
2395     }
2396     declaration.hasDecorationStyle_ = true;
2397 }
2398 
SetBorderImageGradientDirections(const std::unique_ptr<JsonValue> & gradientDirections,Declaration & declaration)2399 void Declaration::SetBorderImageGradientDirections(const std::unique_ptr<JsonValue>& gradientDirections,
2400     Declaration& declaration)
2401 {
2402     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2403     if (!backgroundStyle.IsValid()) {
2404         return;
2405     }
2406 
2407     std::unique_ptr<JsonValue> angleItem;
2408     std::unique_ptr<JsonValue> sideItem;
2409     std::unique_ptr<JsonValue> cornerItem;
2410     GradientDirection direction;
2411     switch (gradientDirections->GetArraySize()) {
2412         case DIRECTION_ANGLE:
2413             angleItem = gradientDirections->GetArrayItem(0);
2414             if (angleItem->IsString()) {
2415                 LinearGradient linearGradient;
2416                 linearGradient.angle = AnimatableDimension(StringToDouble(angleItem->GetString()));
2417                 backgroundStyle.gradientBorderImage.SetLinearGradient(linearGradient);
2418                 declaration.hasDecorationStyle_ = true;
2419             }
2420             break;
2421         case DIRECTION_SIDE:
2422             sideItem = gradientDirections->GetArrayItem(1);
2423             if (sideItem->IsString()) {
2424                 direction = StrToGradientDirection(sideItem->GetString());
2425                 LinearGradient linearGradient;
2426                 if (LinearGradient::IsXAxis(direction)) {
2427                     linearGradient.linearX = direction;
2428                 } else {
2429                     linearGradient.linearY = direction;
2430                 }
2431                 backgroundStyle.gradientBorderImage.SetLinearGradient(linearGradient);
2432                 declaration.hasDecorationStyle_ = true;
2433             }
2434             break;
2435         case DIRECTION_CORNER:
2436             sideItem = gradientDirections->GetArrayItem(1);
2437             cornerItem = gradientDirections->GetArrayItem(2);
2438             if (sideItem->IsString() && cornerItem->IsString()) {
2439                 LinearGradient linearGradient;
2440                 auto direction1 = StrToGradientDirection(sideItem->GetString());
2441                 auto direction2 = StrToGradientDirection(cornerItem->GetString());
2442                 if ((LinearGradient::IsXAxis(direction1) && LinearGradient::IsXAxis(direction2)) ||
2443                     (!LinearGradient::IsXAxis(direction1) && !LinearGradient::IsXAxis(direction2))) {
2444                     linearGradient.linearY = GradientDirection::BOTTOM;
2445                     break;
2446                 } else {
2447                     if (LinearGradient::IsXAxis(direction1)) {
2448                         linearGradient.linearX = direction1;
2449                         linearGradient.linearY = direction2;
2450                     } else {
2451                         linearGradient.linearY = direction1;
2452                         linearGradient.linearX = direction2;
2453                     }
2454                 }
2455                 backgroundStyle.gradientBorderImage.SetLinearGradient(linearGradient);
2456                 declaration.hasDecorationStyle_ = true;
2457             }
2458             break;
2459         default:
2460             LOGE("gradientDirectionsLength error");
2461             break;
2462     }
2463 }
2464 
SetBorderImageGradientColor(const std::unique_ptr<JsonValue> & gradientColorValues,Declaration & declaration)2465 void Declaration::SetBorderImageGradientColor(const std::unique_ptr<JsonValue>& gradientColorValues,
2466     Declaration& declaration)
2467 {
2468     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2469     if (!backgroundStyle.IsValid()) {
2470         return;
2471     }
2472     backgroundStyle.gradientBorderImage.ClearColors();
2473     int32_t gradientColorValuesLength = gradientColorValues->GetArraySize();
2474     for (int32_t i = 0; i < gradientColorValuesLength; i++) {
2475         std::string gradientColorValue = gradientColorValues->GetArrayItem(i)->GetString();
2476         GradientColor gradientColor;
2477         RemoveHeadTailSpace(gradientColorValue);
2478         auto index = gradientColorValue.find(' ');
2479         if (index != std::string::npos && index != 0) {
2480             std::string color = gradientColorValue.substr(0, index);
2481             std::string area = gradientColorValue.substr(index + 1, gradientColorValue.size() - index - 1);
2482             gradientColor.SetColor(declaration.ParseColor(color));
2483             gradientColor.SetHasValue(true);
2484             if (area.find("px") != std::string::npos) {
2485                 gradientColor.SetDimension(StringToDouble(area), DimensionUnit::PX);
2486             } else if (area.find('%') != std::string::npos) {
2487                 gradientColor.SetDimension(StringToDouble(area), DimensionUnit::PERCENT);
2488             } else {
2489                 LOGW("gradientColor DimensionUnit is incorrect)");
2490                 gradientColor.SetHasValue(false);
2491             }
2492         } else {
2493             gradientColor.SetHasValue(false);
2494             gradientColor.SetColor(declaration.ParseColor(gradientColorValue));
2495         }
2496         backgroundStyle.gradientBorderImage.AddColor(gradientColor);
2497         declaration.hasDecorationStyle_ = true;
2498     }
2499 }
2500 
SetBorderOverall(const std::string & value,Declaration & declaration)2501 void Declaration::SetBorderOverall(const std::string& value, Declaration& declaration)
2502 {
2503     auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
2504     if (!borderStyle.IsValid()) {
2505         LOGD("don't support border");
2506         return;
2507     }
2508 
2509     std::vector<std::string> offsets;
2510     StringUtils::StringSplitter(value, ' ', offsets);
2511     switch (offsets.size()) {
2512         case 1:
2513             if (offsets[0].find("px") != std::string::npos) {
2514                 SetBorderWidthForFourEdges(offsets[0], declaration);
2515             } else if (offsets[0] == "solid" || offsets[0] == "dotted" || offsets[0] == "dashed") {
2516                 SetBorderStyleForFourEdges(offsets[0], declaration);
2517             } else {
2518                 SetBorderColorForFourEdges(offsets[0], declaration);
2519             }
2520             break;
2521         case 2:
2522             SetBorderWidthForFourEdges(offsets[0], declaration);
2523             SetBorderStyleForFourEdges(offsets[1], declaration);
2524             break;
2525         case 3:
2526             SetBorderWidthForFourEdges(offsets[0], declaration);
2527             SetBorderStyleForFourEdges(offsets[1], declaration);
2528             SetBorderColorForFourEdges(offsets[2], declaration);
2529             break;
2530         default:
2531             break;
2532     }
2533 }
2534 
SetBorderWidthForFourEdges(const std::string & value,Declaration & declaration)2535 void Declaration::SetBorderWidthForFourEdges(const std::string& value, Declaration& declaration)
2536 {
2537     auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
2538     if (borderStyle.IsValid()) {
2539         borderStyle.border.SetWidth(declaration.ParseDimension(value));
2540         declaration.hasDecorationStyle_ = true;
2541         declaration.hasBorderStyle_ = true;
2542     }
2543 }
2544 
SetBorderColorForFourEdges(const std::string & value,Declaration & declaration)2545 void Declaration::SetBorderColorForFourEdges(const std::string& value, Declaration& declaration)
2546 {
2547     auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
2548     if (borderStyle.IsValid()) {
2549         borderStyle.border.SetColor(declaration.ParseColor(value));
2550         declaration.hasDecorationStyle_ = true;
2551         declaration.hasBorderStyle_ = true;
2552     }
2553 }
2554 
SetBorderStyleForFourEdges(const std::string & value,Declaration & declaration)2555 void Declaration::SetBorderStyleForFourEdges(const std::string& value, Declaration& declaration)
2556 {
2557     auto& borderStyle = declaration.MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
2558     if (borderStyle.IsValid()) {
2559         borderStyle.border.SetStyle(ConvertStrToBorderStyle(value));
2560         declaration.hasDecorationStyle_ = true;
2561         declaration.hasBorderStyle_ = true;
2562     }
2563 }
2564 
SetMaskGradient(const std::string & value,Declaration & declaration)2565 void Declaration::SetMaskGradient(const std::string& value, Declaration& declaration)
2566 {
2567     Declaration::SetBackground(value, declaration);
2568 }
2569 
SetBackground(const std::string & value,Declaration & declaration)2570 void Declaration::SetBackground(const std::string& value, Declaration& declaration)
2571 {
2572     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2573     if (!backgroundStyle.IsValid()) {
2574         LOGD("don't support background style");
2575         return;
2576     }
2577 
2578     LOGD("Declaration::SetBackground value:%{private}s", value.c_str());
2579     auto backgroundJson = JsonUtil::ParseJsonString(value);
2580     if (!backgroundJson->IsObject()) {
2581         LOGE("background json is not Object");
2582         return;
2583     }
2584     if (backgroundJson->Contains(DOM_VALUES) && backgroundJson->GetValue(DOM_VALUES)->IsArray() &&
2585         backgroundJson->GetValue(DOM_VALUES)->GetArraySize() > 0) {
2586         backgroundStyle.gradient = Gradient();
2587         auto values = backgroundJson->GetValue(DOM_VALUES)->GetArrayItem(0);
2588         // gradient type and repeating
2589         if (values->Contains(DOM_GRADIENT_TYPE) && values->GetValue(DOM_GRADIENT_TYPE)->IsString()) {
2590             SetGradientType(values->GetValue(DOM_GRADIENT_TYPE)->GetString(), declaration);
2591         }
2592         // linearGradient direction
2593         if (values->Contains(DOM_GRADIENT_DIRECTIONS) && values->GetValue(DOM_GRADIENT_DIRECTIONS)->IsArray()) {
2594             SetGradientDirections(values->GetValue(DOM_GRADIENT_DIRECTIONS), declaration);
2595         }
2596         // radialGradient shape
2597         if (values->Contains(DOM_GRADIENT_SHAPE) && values->GetValue(DOM_GRADIENT_SHAPE)->IsString()) {
2598             SetGradientShape(values->GetValue(DOM_GRADIENT_SHAPE)->GetString(), declaration);
2599         }
2600         // radialGradient size
2601         if (values->Contains(DOM_GRADIENT_SIZE) && values->GetValue(DOM_GRADIENT_SIZE)->IsString()) {
2602             SetGradientSize(values->GetValue(DOM_GRADIENT_SIZE)->GetString(), declaration);
2603         }
2604         // radialGradient or sweepGradient position
2605         if (values->Contains(DOM_GRADIENT_POSITION) && values->GetValue(DOM_GRADIENT_POSITION)->IsString()) {
2606             SetGradientPosition(values->GetValue(DOM_GRADIENT_POSITION)->GetString(), declaration);
2607         }
2608         // sweepGradient startAngle and endAngle
2609         if (values->Contains(DOM_GRADIENT_ANGLE) && values->GetValue(DOM_GRADIENT_ANGLE)->IsString()) {
2610             SetGradientAngle(values->GetValue(DOM_GRADIENT_ANGLE)->GetString(), declaration);
2611         }
2612         // sweepGradient rotation
2613         if (values->Contains(DOM_GRADIENT_ROTATION) && values->GetValue(DOM_GRADIENT_ROTATION)->IsString()) {
2614             SetGradientRotation(values->GetValue(DOM_GRADIENT_ROTATION)->GetString(), declaration);
2615         }
2616         // gradient color stops
2617         if (values->Contains(DOM_GRADIENT_VALUES) && values->GetValue(DOM_GRADIENT_VALUES)->IsArray()) {
2618             SetGradientColor(values->GetValue(DOM_GRADIENT_VALUES), declaration);
2619         }
2620     }
2621     declaration.hasDecorationStyle_ = true;
2622     declaration.hasBackGroundColor_ = true;
2623 }
2624 
SetGradientType(const std::string & gradientType,Declaration & declaration)2625 void Declaration::SetGradientType(const std::string& gradientType, Declaration& declaration)
2626 {
2627     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2628     if (!backgroundStyle.IsValid()) {
2629         return;
2630     }
2631     // default: LINEAR
2632     backgroundStyle.gradient.SetType(GradientType::LINEAR);
2633     if (gradientType == DOM_RADIAL_GRADIENT || gradientType == DOM_REPEATING_RADIAL_GRADIENT) {
2634         backgroundStyle.gradient.SetType(GradientType::RADIAL);
2635     } else if (gradientType == DOM_SWEEP_GRADIENT || gradientType == DOM_REPEATING_SWEEP_GRADIENT) {
2636         backgroundStyle.gradient.SetType(GradientType::SWEEP);
2637     }
2638 
2639     if (gradientType == DOM_REPEATING_LINEAR_GRADIENT || gradientType == DOM_REPEATING_RADIAL_GRADIENT ||
2640         gradientType == DOM_REPEATING_SWEEP_GRADIENT) {
2641         backgroundStyle.gradient.SetRepeat(true);
2642     }
2643     declaration.hasDecorationStyle_ = true;
2644 }
2645 
SetGradientDirections(const std::unique_ptr<JsonValue> & gradientDirections,Declaration & declaration)2646 void Declaration::SetGradientDirections(const std::unique_ptr<JsonValue>& gradientDirections, Declaration& declaration)
2647 {
2648     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2649     if (!backgroundStyle.IsValid()) {
2650         return;
2651     }
2652 
2653     std::unique_ptr<JsonValue> angleItem;
2654     std::unique_ptr<JsonValue> sideItem;
2655     std::unique_ptr<JsonValue> cornerItem;
2656     GradientDirection direction;
2657     switch (gradientDirections->GetArraySize()) {
2658         case DIRECTION_ANGLE:
2659             angleItem = gradientDirections->GetArrayItem(0);
2660             if (angleItem->IsString()) {
2661                 LinearGradient linearGradient;
2662                 linearGradient.angle = AnimatableDimension(StringToDouble(angleItem->GetString()));
2663                 backgroundStyle.gradient.SetLinearGradient(linearGradient);
2664                 declaration.hasDecorationStyle_ = true;
2665             }
2666             break;
2667         case DIRECTION_SIDE:
2668             sideItem = gradientDirections->GetArrayItem(1);
2669             if (sideItem->IsString()) {
2670                 direction = StrToGradientDirection(sideItem->GetString());
2671                 LinearGradient linearGradient;
2672                 if (LinearGradient::IsXAxis(direction)) {
2673                     linearGradient.linearX = direction;
2674                 } else {
2675                     linearGradient.linearY = direction;
2676                 }
2677                 backgroundStyle.gradient.SetLinearGradient(linearGradient);
2678                 declaration.hasDecorationStyle_ = true;
2679             }
2680             break;
2681         case DIRECTION_CORNER:
2682             sideItem = gradientDirections->GetArrayItem(1);
2683             cornerItem = gradientDirections->GetArrayItem(2);
2684             if (sideItem->IsString() && cornerItem->IsString()) {
2685                 LinearGradient linearGradient;
2686                 auto direction1 = StrToGradientDirection(sideItem->GetString());
2687                 auto direction2 = StrToGradientDirection(cornerItem->GetString());
2688                 if ((LinearGradient::IsXAxis(direction1) && LinearGradient::IsXAxis(direction2)) ||
2689                     (!LinearGradient::IsXAxis(direction1) && !LinearGradient::IsXAxis(direction2))) {
2690                     linearGradient.linearY = GradientDirection::BOTTOM;
2691                     break;
2692                 } else {
2693                     if (LinearGradient::IsXAxis(direction1)) {
2694                         linearGradient.linearX = direction1;
2695                         linearGradient.linearY = direction2;
2696                     } else {
2697                         linearGradient.linearY = direction1;
2698                         linearGradient.linearX = direction2;
2699                     }
2700                 }
2701                 backgroundStyle.gradient.SetLinearGradient(linearGradient);
2702                 declaration.hasDecorationStyle_ = true;
2703             }
2704             break;
2705         default:
2706             LOGE("gradientDirectionsLength error");
2707             break;
2708     }
2709 }
2710 
SetGradientColor(const std::unique_ptr<JsonValue> & gradientColorValues,Declaration & declaration)2711 void Declaration::SetGradientColor(const std::unique_ptr<JsonValue>& gradientColorValues, Declaration& declaration)
2712 {
2713     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2714     if (!backgroundStyle.IsValid()) {
2715         return;
2716     }
2717 
2718     backgroundStyle.gradient.ClearColors();
2719     int32_t gradientColorValuesLength = gradientColorValues->GetArraySize();
2720     for (int32_t i = 0; i < gradientColorValuesLength; i++) {
2721         std::string gradientColorValue = gradientColorValues->GetArrayItem(i)->GetString();
2722         GradientColor gradientColor;
2723         RemoveHeadTailSpace(gradientColorValue);
2724         auto index = gradientColorValue.find(' ');
2725         if (index != std::string::npos && index != 0) {
2726             std::string color = gradientColorValue.substr(0, index);
2727             std::string area = gradientColorValue.substr(index + 1, gradientColorValue.size() - index - 1);
2728             gradientColor.SetColor(declaration.ParseColor(color));
2729             gradientColor.SetHasValue(true);
2730             if (area.find("px") != std::string::npos) {
2731                 gradientColor.SetDimension(StringToDouble(area), DimensionUnit::PX);
2732             } else if (area.find('%') != std::string::npos) {
2733                 gradientColor.SetDimension(StringToDouble(area), DimensionUnit::PERCENT);
2734             } else {
2735                 LOGW("gradientColor DimensionUnit is incorrect)");
2736                 gradientColor.SetHasValue(false);
2737             }
2738         } else {
2739             gradientColor.SetHasValue(false);
2740             gradientColor.SetColor(declaration.ParseColor(gradientColorValue));
2741         }
2742         backgroundStyle.gradient.AddColor(gradientColor);
2743         declaration.hasDecorationStyle_ = true;
2744     }
2745 }
2746 
SetGradientShape(const std::string & gradientShape,Declaration & declaration)2747 void Declaration::SetGradientShape(const std::string& gradientShape, Declaration& declaration)
2748 {
2749     // if empty do nothing, If shape is omitted, the ending shape defaults to a circle if the <size> is a single
2750     // <length>, and to an ellipse otherwise.
2751     if (gradientShape.empty()) {
2752         return;
2753     }
2754     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2755     if (!backgroundStyle.IsValid()) {
2756         return;
2757     }
2758 
2759     if (gradientShape == DOM_GRADIENT_SHAPE_ELLIPSE) {
2760         backgroundStyle.gradient.GetRadialGradient().radialShape = RadialShapeType::ELLIPSE;
2761     } else {
2762         backgroundStyle.gradient.GetRadialGradient().radialShape = RadialShapeType::CIRCLE;
2763     }
2764     declaration.hasDecorationStyle_ = true;
2765 }
2766 
SetGradientSize(const std::string & gradientSize,Declaration & declaration)2767 void Declaration::SetGradientSize(const std::string& gradientSize, Declaration& declaration)
2768 {
2769     if (gradientSize.empty()) {
2770         return;
2771     }
2772     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2773     if (!backgroundStyle.IsValid()) {
2774         return;
2775     }
2776     // 1. closest-corner | closest-side | farthest-corner | farthest-side
2777     auto extent = ParseRadialGradientSize(gradientSize);
2778     if (extent) {
2779         backgroundStyle.gradient.GetRadialGradient().radialSizeType = extent;
2780         declaration.hasDecorationStyle_ = true;
2781         return;
2782     }
2783 
2784     std::vector<std::string> offsets;
2785     StringUtils::StringSplitter(gradientSize, ' ', offsets);
2786     if (offsets.size() == 1) {
2787         // 2. if circle: <length>
2788         auto circleSize = StringToDimension(offsets[0]);
2789 
2790         if (circleSize.Unit() != DimensionUnit::PX) {
2791             LOGE("circle only support length");
2792             return;
2793         }
2794         if (backgroundStyle.gradient.GetRadialGradient().radialShape &&
2795             backgroundStyle.gradient.GetRadialGradient().radialShape != RadialShapeType::CIRCLE) {
2796             LOGE("only circle support one size");
2797             return;
2798         }
2799         backgroundStyle.gradient.GetRadialGradient().radialVerticalSize = circleSize;
2800         backgroundStyle.gradient.GetRadialGradient().radialShape = RadialShapeType::CIRCLE;
2801         declaration.hasDecorationStyle_ = true;
2802     } else if (offsets.size() == 2) {
2803         // 3. if ellipse: <length-percentage>{2}
2804         auto horizontalSize = StringToDimension(offsets[0]);
2805         auto verticalSize = StringToDimension(offsets[1]);
2806 
2807         if (backgroundStyle.gradient.GetRadialGradient().radialShape &&
2808             backgroundStyle.gradient.GetRadialGradient().radialShape != RadialShapeType::ELLIPSE) {
2809             LOGE("only ellipse support two size");
2810             return;
2811         }
2812         backgroundStyle.gradient.GetRadialGradient().radialHorizontalSize = horizontalSize;
2813         backgroundStyle.gradient.GetRadialGradient().radialVerticalSize = verticalSize;
2814         backgroundStyle.gradient.GetRadialGradient().radialShape = RadialShapeType::ELLIPSE;
2815         declaration.hasDecorationStyle_ = true;
2816     } else {
2817         LOGE("unsupported offset size");
2818     }
2819 }
2820 
SetGradientPosition(const std::string & gradientPosition,Declaration & declaration)2821 void Declaration::SetGradientPosition(const std::string& gradientPosition, Declaration& declaration)
2822 {
2823     if (gradientPosition.empty()) {
2824         return;
2825     }
2826     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2827     if (!backgroundStyle.IsValid()) {
2828         return;
2829     }
2830     // position determines the center of gradient default is center
2831     BackgroundImagePosition position;
2832     if (ParseBackgroundImagePosition(gradientPosition, position)) {
2833         auto xAxisPosition = Dimension(position.GetSizeValueX(),
2834             position.GetSizeTypeX() == BackgroundImagePositionType::PX ? DimensionUnit::PX : DimensionUnit::PERCENT);
2835         auto yAxisPosition = Dimension(position.GetSizeValueY(),
2836             position.GetSizeTypeY() == BackgroundImagePositionType::PX ? DimensionUnit::PX : DimensionUnit::PERCENT);
2837         if (backgroundStyle.gradient.GetType() == GradientType::RADIAL) {
2838             backgroundStyle.gradient.GetRadialGradient().radialCenterX = xAxisPosition;
2839             backgroundStyle.gradient.GetRadialGradient().radialCenterY = yAxisPosition;
2840             declaration.hasDecorationStyle_ = true;
2841         } else if (backgroundStyle.gradient.GetType() == GradientType::SWEEP) {
2842             backgroundStyle.gradient.GetSweepGradient().centerX = xAxisPosition;
2843             backgroundStyle.gradient.GetSweepGradient().centerY = yAxisPosition;
2844             declaration.hasDecorationStyle_ = true;
2845         }
2846     } else {
2847         LOGE("ParseBackgroundImagePosition failed");
2848     }
2849 }
2850 
SetGradientAngle(const std::string & gradientAngle,Declaration & declaration)2851 void Declaration::SetGradientAngle(const std::string& gradientAngle, Declaration& declaration)
2852 {
2853     if (gradientAngle.empty()) {
2854         return;
2855     }
2856     auto backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2857     if (!backgroundStyle.IsValid()) {
2858         LOGE("backgroundStyle is invalid");
2859         return;
2860     }
2861     std::vector<std::string> offsets;
2862     StringUtils::StringSplitter(gradientAngle, ' ', offsets);
2863     if (!offsets.empty()) {
2864         auto startAngle = StringUtils::StringToDegree(offsets[0]);
2865         backgroundStyle.gradient.GetSweepGradient().startAngle = AnimatableDimension(startAngle);
2866         if (offsets.size() > 1) {
2867             auto endAngle = StringUtils::StringToDegree(offsets[1]);
2868             backgroundStyle.gradient.GetSweepGradient().endAngle = AnimatableDimension(endAngle);
2869         }
2870         declaration.hasDecorationStyle_ = true;
2871     }
2872 }
2873 
SetGradientRotation(const std::string & gradientRotation,Declaration & declaration)2874 void Declaration::SetGradientRotation(const std::string& gradientRotation, Declaration& declaration)
2875 {
2876     if (gradientRotation.empty()) {
2877         return;
2878     }
2879     auto backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2880     if (!backgroundStyle.IsValid()) {
2881         return;
2882     }
2883     std::vector<std::string> offsets;
2884     StringUtils::StringSplitter(gradientRotation, ' ', offsets);
2885     if (!offsets.empty()) {
2886         auto rotationAngle = StringUtils::StringToDegree(offsets[0]);
2887         backgroundStyle.gradient.GetSweepGradient().rotation = AnimatableDimension(rotationAngle);
2888         declaration.hasDecorationStyle_ = true;
2889     }
2890 }
2891 
SetBgImgSizeX(const BackgroundImageSizeType type,const double value,BackgroundImageSize & bgImgSize)2892 void SetBgImgSizeX(const BackgroundImageSizeType type, const double value, BackgroundImageSize& bgImgSize)
2893 {
2894     bgImgSize.SetSizeTypeX(type);
2895     bgImgSize.SetSizeValueX(value);
2896 }
2897 
SetBgImgSizeY(const BackgroundImageSizeType type,const double value,BackgroundImageSize & bgImgSize)2898 void SetBgImgSizeY(const BackgroundImageSizeType type, const double value, BackgroundImageSize& bgImgSize)
2899 {
2900     bgImgSize.SetSizeTypeY(type);
2901     bgImgSize.SetSizeValueY(value);
2902 }
2903 
SetBackgroundImageSize(const std::string & value,Declaration & declaration)2904 void Declaration::SetBackgroundImageSize(const std::string& value, Declaration& declaration)
2905 {
2906     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
2907     if (!backgroundStyle.IsValid()) {
2908         LOGD("don't support background");
2909         return;
2910     }
2911 
2912     static const LinearMapNode<BackgroundImageSizeType> bgImageSizeType[] = {
2913         { DOM_BACKGROUND_IMAGE_SIZE_AUTO, BackgroundImageSizeType::AUTO },
2914         { DOM_BACKGROUND_IMAGE_SIZE_CONTAIN, BackgroundImageSizeType::CONTAIN },
2915         { DOM_BACKGROUND_IMAGE_SIZE_COVER, BackgroundImageSizeType::COVER },
2916     };
2917     BackgroundImageSize bgImgSize;
2918     auto spaceIndex = value.find(' ', 0);
2919     if (spaceIndex != std::string::npos) {
2920         std::string valueX = value.substr(0, spaceIndex);
2921         std::string valueY = value.substr(spaceIndex + 1, value.size() - spaceIndex - 1);
2922         if (valueX.find("px") != std::string::npos) {
2923             SetBgImgSizeX(BackgroundImageSizeType::LENGTH, StringToDouble(valueX), bgImgSize);
2924         } else if (valueX.find('%') != std::string::npos) {
2925             SetBgImgSizeX(BackgroundImageSizeType::PERCENT, StringToDouble(valueX), bgImgSize);
2926         } else {
2927             bgImgSize.SetSizeTypeX(BackgroundImageSizeType::AUTO);
2928         }
2929         if (valueY.find("px") != std::string::npos) {
2930             SetBgImgSizeY(BackgroundImageSizeType::LENGTH, StringToDouble(valueY), bgImgSize);
2931         } else if (valueY.find('%') != std::string::npos) {
2932             SetBgImgSizeY(BackgroundImageSizeType::PERCENT, StringToDouble(valueY), bgImgSize);
2933         } else {
2934             bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
2935         }
2936     } else {
2937         auto sizeTypeIter = BinarySearchFindIndex(bgImageSizeType, ArraySize(bgImageSizeType), value.c_str());
2938         if (sizeTypeIter != -1) {
2939             bgImgSize.SetSizeTypeX(bgImageSizeType[sizeTypeIter].value);
2940             bgImgSize.SetSizeTypeY(bgImageSizeType[sizeTypeIter].value);
2941         } else if (value.find("px") != std::string::npos) {
2942             SetBgImgSizeX(BackgroundImageSizeType::LENGTH, StringToDouble(value), bgImgSize);
2943             bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
2944         } else if (value.find('%') != std::string::npos) {
2945             SetBgImgSizeX(BackgroundImageSizeType::PERCENT, StringToDouble(value), bgImgSize);
2946             bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
2947         } else {
2948             bgImgSize.SetSizeTypeX(BackgroundImageSizeType::AUTO);
2949             bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
2950         }
2951     }
2952     backgroundStyle.backgroundImage->SetImageSize(
2953         bgImgSize.GetSizeTypeX(), bgImgSize.GetSizeValueX(), bgImgSize.GetSizeTypeY(), bgImgSize.GetSizeValueY());
2954     declaration.hasDecorationStyle_ = true;
2955 }
2956 
SetBgImgPositionX(const BackgroundImagePositionType type,const double value,BackgroundImagePosition & bgImgPosition)2957 void SetBgImgPositionX(
2958     const BackgroundImagePositionType type, const double value, BackgroundImagePosition& bgImgPosition)
2959 {
2960     bgImgPosition.SetSizeTypeX(type);
2961     bgImgPosition.SetSizeValueX(value);
2962 }
2963 
SetBgImgPositionY(const BackgroundImagePositionType type,const double value,BackgroundImagePosition & bgImgPosition)2964 void SetBgImgPositionY(
2965     const BackgroundImagePositionType type, const double value, BackgroundImagePosition& bgImgPosition)
2966 {
2967     bgImgPosition.SetSizeTypeY(type);
2968     bgImgPosition.SetSizeValueY(value);
2969 }
2970 
SetBgImgPosition(const BackgroundImagePositionType type,const double value,BackgroundImagePosition & bgImgPosition)2971 void SetBgImgPosition(
2972     const BackgroundImagePositionType type, const double value, BackgroundImagePosition& bgImgPosition)
2973 {
2974     SetBgImgPositionX(type, value, bgImgPosition);
2975     SetBgImgPositionY(type, value, bgImgPosition);
2976 }
2977 
BgImgPositionIsValid(const std::string & posX,const std::string & posY)2978 bool BgImgPositionIsValid(const std::string& posX, const std::string& posY)
2979 {
2980     if ((std::strcmp(posX.c_str(), DOM_BACKGROUND_IMAGE_POSITION_CENTER) == 0) ||
2981         (std::strcmp(posY.c_str(), DOM_BACKGROUND_IMAGE_POSITION_CENTER) == 0)) {
2982         return true;
2983     }
2984 
2985     static const std::unordered_set<std::string> horizonSet = {
2986         DOM_BACKGROUND_IMAGE_POSITION_LEFT,
2987         DOM_BACKGROUND_IMAGE_POSITION_RIGHT,
2988     };
2989     static const std::unordered_set<std::string> verticalSet = {
2990         DOM_BACKGROUND_IMAGE_POSITION_TOP,
2991         DOM_BACKGROUND_IMAGE_POSITION_BOTTOM,
2992     };
2993 
2994     // posX and posY are not strictly corresponding to horizontal or vertical, but they must not conflict,
2995     // for example both of them are "top" is invalid.
2996     if (posX.find("px") != std::string::npos || posX.find('%') != std::string::npos ||
2997         horizonSet.find(posX) != horizonSet.end()) {
2998         if (posY.find("px") != std::string::npos || posY.find('%') != std::string::npos ||
2999             verticalSet.find(posY) != verticalSet.end()) {
3000             return true;
3001         }
3002     }
3003 
3004     return verticalSet.find(posX) != verticalSet.end() && horizonSet.find(posY) != horizonSet.end();
3005 }
3006 
SetBackgroundImagePosition(const std::string & value,Declaration & declaration)3007 void Declaration::SetBackgroundImagePosition(const std::string& value, Declaration& declaration)
3008 {
3009     auto& backgroundStyle = declaration.MaybeResetStyle<CommonBackgroundStyle>(StyleTag::COMMON_BACKGROUND_STYLE);
3010     if (!backgroundStyle.IsValid()) {
3011         LOGD("don't support background");
3012         return;
3013     }
3014 
3015     static const LinearMapNode<void (*)(BackgroundImagePosition&)> backGroundPositionOperators[] = {
3016         { DOM_BACKGROUND_IMAGE_POSITION_BOTTOM,
3017             [](BackgroundImagePosition& backgroundImagePosition) {
3018                 SetBgImgPositionY(BackgroundImagePositionType::PERCENT, 100.0, backgroundImagePosition);
3019             } },
3020         { DOM_BACKGROUND_IMAGE_POSITION_LEFT,
3021             [](BackgroundImagePosition& backgroundImagePosition) {
3022                 SetBgImgPositionX(BackgroundImagePositionType::PERCENT, 0.0, backgroundImagePosition);
3023             } },
3024         { DOM_BACKGROUND_IMAGE_POSITION_RIGHT,
3025             [](BackgroundImagePosition& backgroundImagePosition) {
3026                 SetBgImgPositionX(BackgroundImagePositionType::PERCENT, 100.0, backgroundImagePosition);
3027             } },
3028         { DOM_BACKGROUND_IMAGE_POSITION_TOP,
3029             [](BackgroundImagePosition& backgroundImagePosition) {
3030                 SetBgImgPositionY(BackgroundImagePositionType::PERCENT, 0.0, backgroundImagePosition);
3031             } },
3032     };
3033     BackgroundImagePosition backgroundImagePosition;
3034 
3035     auto index = value.find(' ', 0);
3036     if (index != std::string::npos) {
3037         std::string valueX = value.substr(0, index);
3038         std::string valueY = value.substr(index + 1, value.size() - index - 1);
3039         if (!BgImgPositionIsValid(valueX, valueY)) {
3040             return;
3041         }
3042         // The input is valid,so set the default is (center,center),
3043         // if the value is different, the default value is overwritten.
3044         SetBgImgPosition(BackgroundImagePositionType::PERCENT, 50.0, backgroundImagePosition);
3045         if (valueX.find("px") != std::string::npos) {
3046             SetBgImgPositionX(BackgroundImagePositionType::PX, StringToDouble(valueX), backgroundImagePosition);
3047         } else if (valueX.find('%') != std::string::npos) {
3048             SetBgImgPositionX(BackgroundImagePositionType::PERCENT, StringToDouble(valueX), backgroundImagePosition);
3049         } else {
3050             auto operatorIterX = BinarySearchFindIndex(
3051                 backGroundPositionOperators, ArraySize(backGroundPositionOperators), valueX.c_str());
3052             if (operatorIterX != -1) {
3053                 backGroundPositionOperators[operatorIterX].value(backgroundImagePosition);
3054             }
3055         }
3056         if (valueY.find("px") != std::string::npos) {
3057             SetBgImgPositionY(BackgroundImagePositionType::PX, StringToDouble(valueY), backgroundImagePosition);
3058         } else if (valueY.find('%') != std::string::npos) {
3059             SetBgImgPositionY(BackgroundImagePositionType::PERCENT, StringToDouble(valueY), backgroundImagePosition);
3060         } else {
3061             auto operatorIterY = BinarySearchFindIndex(
3062                 backGroundPositionOperators, ArraySize(backGroundPositionOperators), valueY.c_str());
3063             if (operatorIterY != -1) {
3064                 backGroundPositionOperators[operatorIterY].value(backgroundImagePosition);
3065             }
3066         }
3067     } else {
3068         SetBgImgPosition(BackgroundImagePositionType::PERCENT, 50.0, backgroundImagePosition);
3069         if (value.find("px") != std::string::npos) {
3070             SetBgImgPositionX(BackgroundImagePositionType::PX, StringToDouble(value), backgroundImagePosition);
3071         } else if (value.find('%') != std::string::npos) {
3072             SetBgImgPositionX(BackgroundImagePositionType::PERCENT, StringToDouble(value), backgroundImagePosition);
3073         } else {
3074             auto operatorIter = BinarySearchFindIndex(
3075                 backGroundPositionOperators, ArraySize(backGroundPositionOperators), value.c_str());
3076             if (operatorIter != -1) {
3077                 backGroundPositionOperators[operatorIter].value(backgroundImagePosition);
3078             }
3079         }
3080     }
3081     backgroundStyle.backgroundImage->SetImagePosition(backgroundImagePosition.GetSizeTypeX(),
3082         backgroundImagePosition.GetSizeValueX(), backgroundImagePosition.GetSizeTypeY(),
3083         backgroundImagePosition.GetSizeValueY());
3084     declaration.hasDecorationStyle_ = true;
3085 }
3086 
BindPipelineContext(const WeakPtr<PipelineContext> & pipelineContext)3087 void Declaration::BindPipelineContext(const WeakPtr<PipelineContext>& pipelineContext)
3088 {
3089     pipelineContext_ = pipelineContext;
3090 }
3091 
ResetDefaultStyles()3092 void Declaration::ResetDefaultStyles()
3093 {
3094     auto& sizeStyle = static_cast<CommonSizeStyle&>(GetStyle(StyleTag::COMMON_SIZE_STYLE));
3095     if (sizeStyle.IsValid() && !sizeStyle.IsShared()) {
3096         sizeStyle.width = Dimension(-1.0, DimensionUnit::PX);
3097         sizeStyle.height = Dimension(-1.0, DimensionUnit::PX);
3098         sizeStyle.minWidth = Dimension(0.0);
3099         sizeStyle.minHeight = Dimension(0.0);
3100         sizeStyle.maxWidth = Dimension(Size::INFINITE_SIZE);
3101         sizeStyle.maxHeight = Dimension(Size::INFINITE_SIZE);
3102         sizeStyle.aspectRatio = -1.0;
3103     }
3104 
3105     auto& paddingStyle = static_cast<CommonPaddingStyle&>(GetStyle(StyleTag::COMMON_PADDING_STYLE));
3106     if (paddingStyle.IsValid() && !paddingStyle.IsShared()) {
3107         paddingStyle.padding = Edge(Dimension(0.0));
3108     }
3109 
3110     auto& marginStyle = static_cast<CommonMarginStyle&>(GetStyle(StyleTag::COMMON_MARGIN_STYLE));
3111     if (marginStyle.IsValid() && !marginStyle.IsShared()) {
3112         marginStyle.margin = Edge(Dimension(0.0));
3113     }
3114 
3115     auto& flexStyle = static_cast<CommonFlexStyle&>(GetStyle(StyleTag::COMMON_FLEX_STYLE));
3116     if (flexStyle.IsValid() && !flexStyle.IsShared()) {
3117         flexStyle.flexGrow = 0.0;
3118         flexStyle.flexShrink = 1.0;
3119         flexStyle.flexBasis = 0.0_px;
3120         flexStyle.flexWeight = 0.0;
3121         flexStyle.displayIndex = 1;
3122     }
3123 
3124     auto& opacityStyle = static_cast<CommonOpacityStyle&>(GetStyle(StyleTag::COMMON_OPACITY_STYLE));
3125     if (opacityStyle.IsValid() && !opacityStyle.IsShared()) {
3126         opacityStyle.opacity = 1.0;
3127     }
3128 
3129     auto& displayStyle = static_cast<CommonDisplayStyle&>(GetStyle(StyleTag::COMMON_DISPLAY_STYLE));
3130     if (displayStyle.IsValid() && !displayStyle.IsShared()) {
3131         displayStyle.display = DisplayType::NO_SETTING;
3132     }
3133     hasDisplayStyle_ = false;
3134 
3135     auto& visibilityStyle = static_cast<CommonVisibilityStyle&>(GetStyle(StyleTag::COMMON_VISIBILITY_STYLE));
3136     if (visibilityStyle.IsValid() && !visibilityStyle.IsShared()) {
3137         visibilityStyle.visibility = VisibilityType::NO_SETTING;
3138     }
3139 
3140     auto& borderStyle = static_cast<CommonBorderStyle&>(GetStyle(StyleTag::COMMON_BORDER_STYLE));
3141     if (borderStyle.IsValid() && !borderStyle.IsShared()) {
3142         borderStyle.border.SetBorderEdge(BorderEdge(Color::BLACK, Dimension(), BorderStyle::SOLID));
3143     }
3144 
3145     auto& borderImageStyle = static_cast<CommonBorderStyle&>(GetStyle(StyleTag::COMMON_BORDER_STYLE));
3146     if (borderImageStyle.IsValid() && !borderImageStyle.IsShared()) {
3147         borderImageStyle.border.SetBorderImageEdge(
3148             BorderImageEdge(Dimension(), Dimension(), Dimension(), BorderImageRepeat::STRETCH));
3149     }
3150 
3151     auto& background = static_cast<CommonBackgroundStyle&>(GetStyle(StyleTag::COMMON_BACKGROUND_STYLE));
3152     if (background.IsValid() && !background.IsShared()) {
3153         background.gradient = Gradient();
3154         background.gradientBorderImage = Gradient();
3155         background.backgroundImage = AceType::MakeRefPtr<BackgroundImage>();
3156         background.borderImage = AceType::MakeRefPtr<BorderImage>();
3157     }
3158 
3159     auto& renderAttr = static_cast<CommonRenderAttribute&>(GetAttribute(AttributeTag::COMMON_RENDER_ATTR));
3160     if (renderAttr.IsValid() && !renderAttr.IsShared() && !renderAttr.show.empty()) {
3161         hasDisplayStyle_ = true;
3162         SetShowAttr(renderAttr.show);
3163     }
3164 
3165     backDecoration_ = AceType::MakeRefPtr<Decoration>();
3166     frontDecoration_ = AceType::MakeRefPtr<Decoration>();
3167 }
3168 
3169 // Convert transform style to json format, such as rotate(50deg) to {"rotate":"50deg"}
GetTransformJsonValue(const std::string & value)3170 std::string Declaration::GetTransformJsonValue(const std::string& value)
3171 {
3172     auto rightIndex = value.find('(');
3173     auto leftIndex = value.find(')');
3174     std::string jsonValue = value;
3175 
3176     if (rightIndex != std::string::npos && leftIndex != std::string::npos && (leftIndex - 1 - rightIndex > 0)) {
3177         std::string transformType = value.substr(0, rightIndex);
3178         std::string transformValue = value.substr(rightIndex + 1, leftIndex - 1 - rightIndex);
3179         jsonValue = "{\"" + transformType + "\":\"" + transformValue + "\"}";
3180     }
3181 
3182     return jsonValue;
3183 }
3184 
GetTransformType(const std::unique_ptr<JsonValue> & transformJson)3185 std::string Declaration::GetTransformType(const std::unique_ptr<JsonValue>& transformJson)
3186 {
3187     if (transformJson->IsNull()) {
3188         LOGE("transformJson is null");
3189         return "";
3190     }
3191     return transformJson->GetKey();
3192 }
3193 
GetTransformTypeValue(const std::unique_ptr<JsonValue> & transformJson)3194 std::string Declaration::GetTransformTypeValue(const std::unique_ptr<JsonValue>& transformJson)
3195 {
3196     if (transformJson->IsNull()) {
3197         LOGE("transformJson is null");
3198         return "";
3199     }
3200     std::string jsonValue = transformJson->GetString();
3201     if (jsonValue.empty()) {
3202         double jsonDouble = transformJson->GetDouble();
3203         return std::to_string(jsonDouble);
3204     }
3205     return jsonValue;
3206 }
3207 
GetThemeManager() const3208 RefPtr<ThemeManager> Declaration::GetThemeManager() const
3209 {
3210     auto context = pipelineContext_.Upgrade();
3211     if (!context) {
3212         return nullptr;
3213     }
3214     return context->GetThemeManager();
3215 }
3216 
GetThemeConstants() const3217 RefPtr<ThemeConstants> Declaration::GetThemeConstants() const
3218 {
3219     auto themeManager = GetThemeManager();
3220     if (!themeManager) {
3221         return nullptr;
3222     }
3223     return themeManager->GetThemeConstants();
3224 }
3225 
ParseColor(const std::string & value,uint32_t maskAlpha) const3226 Color Declaration::ParseColor(const std::string& value, uint32_t maskAlpha) const
3227 {
3228     auto themeConstants = GetThemeConstants();
3229     auto&& noRefFunc = [&value, maskAlpha = maskAlpha]() { return Color::FromString(value, maskAlpha); };
3230     auto&& idRefFunc = [constants = themeConstants](uint32_t refId) { return constants->GetColor(refId); };
3231     return ParseThemeReference<Color>(value, noRefFunc, idRefFunc, Color::TRANSPARENT);
3232 }
3233 
ParseDouble(const std::string & value) const3234 double Declaration::ParseDouble(const std::string& value) const
3235 {
3236     auto themeConstants = GetThemeConstants();
3237     auto&& noRefFunc = [&value]() { return StringUtils::StringToDouble(value); };
3238     auto&& idRefFunc = [constants = themeConstants](uint32_t refId) { return constants->GetDouble(refId); };
3239     return ParseThemeReference<double>(value, noRefFunc, idRefFunc, 0.0);
3240 }
3241 
ParseDimension(const std::string & value,bool useVp) const3242 Dimension Declaration::ParseDimension(const std::string& value, bool useVp) const
3243 {
3244     auto themeConstants = GetThemeConstants();
3245     auto&& noRefFunc = [&value, useVp]() { return StringUtils::StringToDimension(value, useVp); };
3246     auto&& idRefFunc = [constants = themeConstants](uint32_t refId) { return constants->GetDimension(refId); };
3247     return ParseThemeReference<Dimension>(value, noRefFunc, idRefFunc, Dimension());
3248 }
3249 
ParseCalcDimension(const std::string & value,bool useVp) const3250 CalcDimension Declaration::ParseCalcDimension(const std::string& value, bool useVp) const
3251 {
3252     if (value.find("calc") != std::string::npos) {
3253         return StringUtils::StringToCalcDimension(value, useVp);
3254     } else {
3255         return ParseDimension(value, useVp);
3256     }
3257 }
3258 
ParseLineHeight(const std::string & value) const3259 Dimension Declaration::ParseLineHeight(const std::string& value) const
3260 {
3261     auto themeConstants = GetThemeConstants();
3262     const auto& parseResult = ThemeUtils::ParseThemeIdReference(value, themeConstants);
3263     if (!parseResult.parseSuccess) {
3264         return StringUtils::StringToDimension(value);
3265     }
3266     auto&& noRefFunc = [&value]() { return StringUtils::StringToDouble(value); };
3267     auto&& idRefFunc = [constants = themeConstants](uint32_t refId) { return constants->GetDouble(refId); };
3268     auto lineHeightScale = ParseThemeReference<double>(value, noRefFunc, idRefFunc, 1.0);
3269     // If got 0.0 from ThemeConstants, use default 1.0
3270     lineHeightScale = NearZero(lineHeightScale) ? 1.0 : lineHeightScale;
3271     return Dimension(lineHeightScale, DimensionUnit::PERCENT);
3272 }
3273 
ParseFontFamilies(const std::string & value) const3274 std::vector<std::string> Declaration::ParseFontFamilies(const std::string& value) const
3275 {
3276     std::vector<std::string> fontFamilies;
3277     std::stringstream stream(value);
3278     std::string fontFamily;
3279 
3280     auto themeConstants = GetThemeConstants();
3281     auto&& idRefFunc = [constants = themeConstants](uint32_t refId) { return constants->GetString(refId); };
3282 
3283     while (getline(stream, fontFamily, ',')) {
3284         auto&& noRefFunc = [&fontFamily]() { return fontFamily; };
3285         fontFamilies.emplace_back(ParseThemeReference<std::string>(fontFamily, noRefFunc, idRefFunc, fontFamily));
3286     }
3287     return fontFamilies;
3288 }
3289 
ParsePreferFontSizes(const std::string & value) const3290 std::vector<Dimension> Declaration::ParsePreferFontSizes(const std::string& value) const
3291 {
3292     std::vector<Dimension> prefers;
3293     std::stringstream stream(value);
3294     std::string fontSize;
3295     while (getline(stream, fontSize, ',')) {
3296         prefers.emplace_back(ParseDimension(fontSize));
3297     }
3298     std::sort(prefers.begin(), prefers.end(),
3299         [](const Dimension& left, const Dimension& right) { return left.Value() > right.Value(); });
3300     return prefers;
3301 }
3302 
ParseImageSrc(const std::string & imgSrc) const3303 std::string Declaration::ParseImageSrc(const std::string& imgSrc) const
3304 {
3305     return ThemeUtils::ProcessImageSource(imgSrc, GetThemeConstants());
3306 }
3307 
IsRightToLeft() const3308 bool Declaration::IsRightToLeft() const
3309 {
3310     bool isRightToLeft = false;
3311     auto& commonAttr = static_cast<CommonAttribute&>(GetAttribute(AttributeTag::COMMON_ATTR));
3312     if (commonAttr.IsValid()) {
3313         isRightToLeft = commonAttr.isRightToLeft;
3314     }
3315     return isRightToLeft;
3316 }
3317 
SetClickEvent(const EventMarker & onClick)3318 void Declaration::SetClickEvent(const EventMarker& onClick)
3319 {
3320     auto& gestureEvent = MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_GESTURE_EVENT);
3321     if (gestureEvent.IsValid()) {
3322         gestureEvent.click.eventMarker = onClick;
3323         gestureEvent.click.eventMarker.SetCatchMode(false);
3324         gestureEvent.click.isRefreshed = true;
3325     }
3326 }
3327 
SetRemoteMessageEvent(const EventMarker & remoteMessage)3328 void Declaration::SetRemoteMessageEvent(const EventMarker& remoteMessage)
3329 {
3330     LOGI("Declaration::SetRemoteMessageEvent");
3331     auto& gestureEvent = MaybeResetEvent<CommonGestureEvent>(EventTag::COMMON_REMOTE_MESSAGE_GESTURE_EVENT);
3332     if (gestureEvent.IsValid()) {
3333         LOGI("Declaration::SetRemoteMessageEvent IsValid");
3334         gestureEvent.click.eventMarker = remoteMessage;
3335         gestureEvent.click.eventMarker.SetCatchMode(false);
3336         gestureEvent.click.isRefreshed = true;
3337     }
3338 }
3339 
3340 } // namespace OHOS::Ace
3341