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