• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "frameworks/bridge/common/dom/dom_node.h"
17 
18 #include <sstream>
19 #include <unordered_set>
20 
21 #include "base/log/ace_trace.h"
22 #include "core/animation/animatable_data.h"
23 #include "core/common/ace_application_info.h"
24 #include "core/common/frontend.h"
25 #include "core/components/declaration/common/declaration_creator_manager.h"
26 #include "core/components/scroll/scroll_bar_theme.h"
27 #include "core/components/scroll/scroll_fade_effect.h"
28 #include "core/components/scroll/scroll_spring_effect.h"
29 #include "core/components/video/texture_component.h"
30 #include "core/components/web/web_component.h"
31 #include "core/components/xcomponent/xcomponent_component.h"
32 #include "frameworks/bridge/common/dom/dom_div.h"
33 #include "frameworks/bridge/common/utils/utils.h"
34 
35 namespace OHOS::Ace::Framework {
36 namespace {
37 
38 constexpr uint32_t TRANSFORM_SINGLE = 1;
39 constexpr uint32_t TRANSFORM_DUAL = 2;
40 constexpr uint32_t TRANSFORM_SIX = 6;
41 constexpr uint32_t TRANSFORM_SIXTEEN = 16;
42 constexpr uint32_t COMMON_METHOD_FOCUS_ARGS_SIZE = 1;
43 constexpr uint32_t THREE_VALUES = 3;
44 constexpr uint32_t FOUR_VALUES = 4;
45 constexpr int32_t MS_TO_S = 1000;
46 const char COMMON_METHOD_FOCUS[] = "focus";
47 
48 // focusable support list, this list should be updated after the other nodes(checkbox/radio/switch/
49 // grid/dialog/button/input) implemented in frontend.
50 std::unordered_set<std::string> g_focusableNode;
51 
52 // unsupported focusable list.
53 const std::unordered_set<std::string> UNFOCUSABLED_NODE = {
54     DOM_NODE_TAG_SPAN,
55 };
56 
57 static const std::unordered_set<std::string> TRANSITION_PROPERTIES = {
58     DOM_WIDTH,
59     DOM_HEIGHT,
60     DOM_PADDING_TOP,
61     DOM_PADDING_RIGHT,
62     DOM_PADDING_BOTTOM,
63     DOM_PADDING_LEFT,
64     DOM_MARGIN_TOP,
65     DOM_MARGIN_RIGHT,
66     DOM_MARGIN_BOTTOM,
67     DOM_MARGIN_LEFT,
68     DOM_BACKGROUND_COLOR,
69     DOM_OPACITY,
70     DOM_BORDER_LEFT_WIDTH,
71     DOM_BORDER_TOP_WIDTH,
72     DOM_BORDER_RIGHT_WIDTH,
73     DOM_BORDER_BOTTOM_WIDTH,
74     DOM_BORDER_LEFT_COLOR,
75     DOM_BORDER_TOP_COLOR,
76     DOM_BORDER_RIGHT_COLOR,
77     DOM_BORDER_BOTTOM_COLOR
78 };
79 
80 // default flex value
81 constexpr double DEFAULT_FLEX_GROW = 0.0;
82 constexpr double DEFAULT_FLEX_SHRINK = 1.0;
83 constexpr double DEFAULT_FLEX_BASIS = -1.0;
84 constexpr int32_t TRANSITION_NAME_LENGTH = 4;
85 
86 // prefix id of TweenComponent, for differentiation from id of ComposedComponent
87 constexpr char COMPONENT_PREFIX[] = "FrontendTween";
88 constexpr char TRANSITION_COMPONENT_PREFIX[] = "FrontendTransition";
89 
90 } // namespace
91 
DOMNode(NodeId nodeId,const std::string & nodeName)92 DOMNode::DOMNode(NodeId nodeId, const std::string& nodeName) : nodeId_(nodeId), tag_(nodeName)
93 {
94     rootComponent_ = AceType::MakeRefPtr<ComposedComponent>(std::to_string(nodeId), nodeName);
95     boxComponent_ = AceType::MakeRefPtr<BoxComponent>();
96     CreateDeclaration(nodeName);
97 }
98 
~DOMNode()99 DOMNode::~DOMNode()
100 {
101     if (declaration_) {
102         auto& focusEvent = static_cast<CommonFocusEvent&>(declaration_->GetEvent(EventTag::COMMON_FOCUS_EVENT));
103         if (focusEvent.IsValid()) {
104             if (!focusEvent.focus.eventMarker.IsEmpty()) {
105                 BackEndEventManager<void()>::GetInstance().RemoveBackEndEvent(focusEvent.focus.eventMarker);
106             }
107             if (!focusEvent.blur.eventMarker.IsEmpty()) {
108                 BackEndEventManager<void()>::GetInstance().RemoveBackEndEvent(focusEvent.blur.eventMarker);
109             }
110         }
111         auto& mouseEvent = static_cast<CommonMouseEvent&>(declaration_->GetEvent(EventTag::COMMON_MOUSE_EVENT));
112         if (mouseEvent.IsValid()) {
113             if (!mouseEvent.mouseHover.eventMarker.IsEmpty()) {
114                 BackEndEventManager<void()>::GetInstance().RemoveBackEndEvent(mouseEvent.mouseHover.eventMarker);
115             }
116             if (!mouseEvent.mouseHoverExit.eventMarker.IsEmpty()) {
117                 BackEndEventManager<void()>::GetInstance().RemoveBackEndEvent(mouseEvent.mouseHoverExit.eventMarker);
118             }
119         }
120 
121         for (uint32_t eventAction = 0; eventAction < EventAction::SIZE; eventAction++) {
122             for (uint32_t eventStage = 0; eventStage < EventStage::SIZE; eventStage++) {
123                 for (uint32_t touchEventType = 0; touchEventType < EventType::SIZE; touchEventType++) {
124                     const auto& eventMarker = GetTouchId(eventAction, eventStage, touchEventType);
125                     if (!eventMarker.IsEmpty()) {
126                         BackEndEventManager<void()>::GetInstance().RemoveBackEndEvent(eventMarker);
127                     }
128                 }
129             }
130         }
131     }
132 }
133 
Mount(int32_t slot)134 void DOMNode::Mount(int32_t slot)
135 {
136     auto parentNode = parentNode_.Upgrade();
137     if (!parentNode) {
138         return;
139     }
140     // flex-item could be used in div, list-item, tabs
141     static const std::unordered_set<std::string> flexItemParents = {
142         DOM_NODE_TAG_DIV,
143         DOM_NODE_TAG_GRID_COLUMN,
144         DOM_NODE_TAG_LIST_ITEM,
145         DOM_NODE_TAG_LIST_ITEM_GROUP,
146         DOM_NODE_TAG_TABS,
147         DOM_NODE_TAG_REFRESH,
148         DOM_NODE_TAG_STEPPER_ITEM,
149     };
150     if (flexItemParents.count(parentTag_) > 0) {
151         flexItemComponent_ =
152             AceType::MakeRefPtr<FlexItemComponent>(DEFAULT_FLEX_GROW, DEFAULT_FLEX_SHRINK, DEFAULT_FLEX_BASIS);
153         if (boxComponent_) {
154             // span has no box component.
155             boxComponent_->SetDeliverMinToChild(false);
156         }
157     }
158     GenerateComponentNode();
159     if (parentNode->IsRootNode()) {
160         // When parent is root node, parent contains scroll component,
161         // box could handle percent with viewport size.
162         if (boxComponent_) {
163             // span has no box component.
164             boxComponent_->SetPercentFlag(PERCENT_FLAG_USE_VIEW_PORT);
165         }
166     }
167     parentNode->AddNode(AceType::Claim(this), slot);
168     OnMounted(parentNode);
169 }
170 
AddEvent(int32_t pageId,const std::vector<std::string> & events)171 void DOMNode::AddEvent(int32_t pageId, const std::vector<std::string>& events)
172 {
173     std::vector<std::string> tempEvents;
174     for (const auto& event : events) {
175         if (!AddSpecializedEvent(pageId, event)) {
176             tempEvents.emplace_back(event);
177         }
178     }
179     if (declaration_) {
180         declaration_->AddEvent(pageId, GetNodeIdForEvent(), tempEvents);
181     }
182 }
183 
SetAttr(const std::vector<std::pair<std::string,std::string>> & attrs)184 void DOMNode::SetAttr(const std::vector<std::pair<std::string, std::string>>& attrs)
185 {
186     attributesCache_ = attrs;
187     SetAttrInternal(attrs);
188 }
189 
SetAttrInternal(const std::vector<std::pair<std::string,std::string>> & attrs)190 void DOMNode::SetAttrInternal(const std::vector<std::pair<std::string, std::string>>& attrs)
191 {
192     std::vector<std::pair<std::string, std::string>> tempAttrs;
193     for (const auto& attr : attrs) {
194         if (SetSpecializedAttr(attr)) {
195             continue;
196         } else {
197             tempAttrs.emplace_back(attr);
198         }
199     }
200     if (declaration_) {
201         IsSubscriptEnable();
202         declaration_->SetAttr(tempAttrs);
203     }
204 }
205 
CallMethod(const std::string & method,const std::string & args)206 void DOMNode::CallMethod(const std::string& method, const std::string& args)
207 {
208     if (method == COMMON_METHOD_FOCUS) {
209         LOGD("CallMethod: node tag: %{public}s call focus method.", tag_.c_str());
210         if (!focusableEventComponent_) {
211             LOGE("CallMethod: call focus method failed, focusableEventComponent is null");
212             return;
213         }
214 
215         bool shouldFocus = true;
216         std::unique_ptr<JsonValue> argsValue = JsonUtil::ParseJsonString(args);
217         if (argsValue && argsValue->IsArray() && argsValue->GetArraySize() == COMMON_METHOD_FOCUS_ARGS_SIZE) {
218             std::unique_ptr<JsonValue> focusValue = argsValue->GetArrayItem(0)->GetValue(COMMON_METHOD_FOCUS);
219             if (focusValue && focusValue->IsBool()) {
220                 shouldFocus = focusValue->GetBool();
221             }
222         }
223         OnRequestFocus(shouldFocus);
224     } else if (method == DOM_LIST_METHOD_SCROLL_BY) {
225         std::unique_ptr<JsonValue> argsValue = JsonUtil::ParseJsonString(args);
226         if (!argsValue || !argsValue->IsArray() || argsValue->GetArraySize() != 1) {
227             LOGE("parse args error");
228             return;
229         }
230         std::unique_ptr<JsonValue> scrollByPara = argsValue->GetArrayItem(0);
231         double x = scrollByPara->GetDouble("dx", 0.0);
232         double y = scrollByPara->GetDouble("dy", 0.0);
233         bool isSmooth = scrollByPara->GetBool("smooth", true);
234         OnScrollBy(x, y, isSmooth);
235     } else {
236         CallSpecializedMethod(method, args);
237     }
238 }
239 
OnRequestFocus(bool shouldFocus)240 void DOMNode::OnRequestFocus(bool shouldFocus)
241 {
242     auto controller = focusableEventComponent_->GetFocusableController();
243     if (!controller) {
244         return;
245     }
246     controller->RequestFocus(shouldFocus);
247 }
248 
OnScrollBy(double dx,double dy,bool isSmooth)249 void DOMNode::OnScrollBy(double dx, double dy, bool isSmooth)
250 {
251     auto scrollComponent = GetScrollComponent();
252     if (!scrollComponent) {
253         return;
254     }
255     auto positionController = scrollComponent->GetScrollPositionController();
256     if (!positionController) {
257         return;
258     }
259     positionController->ScrollBy(dx, dy, isSmooth);
260 }
261 
SetShowAttr(const std::string & showValue)262 void DOMNode::SetShowAttr(const std::string& showValue)
263 {
264     if (!declaration_) {
265         return;
266     }
267 
268     auto& renderAttr = declaration_->MaybeResetAttribute<CommonRenderAttribute>(AttributeTag::COMMON_RENDER_ATTR);
269     if (renderAttr.IsValid()) {
270         renderAttr.show = showValue;
271     }
272     if (showValue == "false") {
273         SetDisplay(DisplayType::NONE);
274     } else {
275         SetDisplay(DisplayType::NO_SETTING);
276     }
277 }
278 
ParseTransitionPropertyStyle(const std::string & transitionProperty)279 bool DOMNode::ParseTransitionPropertyStyle(const std::string& transitionProperty)
280 {
281     if (TRANSITION_PROPERTIES.find(transitionProperty) == TRANSITION_PROPERTIES.end()) {
282         return false;
283     }
284     transitionPropertyName_ = transitionProperty;
285     CreatePropertyAnimation(transitionPropertyName_);
286     return true;
287 }
288 
ParseTransitionNameStyle(const std::string & transitionName)289 bool DOMNode::ParseTransitionNameStyle(const std::string& transitionName)
290 {
291     std::vector<std::string> transitions;
292     StringUtils::StringSpliter(transitionName, ' ', transitions);
293     if (transitions.size() != TRANSITION_NAME_LENGTH) {
294         LOGE("transition length is invalid");
295         return false;
296     }
297     transitionPropertyName_ = transitions[0];
298     transitionDuration_ = StringUtils::StringToDouble(transitions[1]) * MS_TO_S;
299     transitionTimeFunction_ = transitions[2];
300     transitionDelay_ = StringUtils::StringToDouble(transitions[3]) * MS_TO_S;
301 
302     CreatePropertyAnimation(transitionPropertyName_);
303     return true;
304 }
305 
CreatePropertyAnimation(const std::string & property)306 void DOMNode::CreatePropertyAnimation(const std::string& property)
307 {
308     propertyWidthAnimation_ = AceType::MakeRefPtr<KeyframeAnimation<float>>();
309     propertyHeightAnimation_ = AceType::MakeRefPtr<KeyframeAnimation<float>>();
310     propertyColorAnimation_ = AceType::MakeRefPtr<KeyframeAnimation<Color>>();
311     static const std::unordered_map<std::string, void (*)(DOMNode&)> propertyAnimationMap = {
312         { DOM_WIDTH, [](DOMNode& node) {
313             float widthBegin = 0.0f;
314             float widthEnd = node.GetWidth().Value();
315             node.propertyWidthAnimation_ = node.SetPropertyFloatAnimationKeyframe(widthBegin, widthEnd);
316         } },
317         { DOM_HEIGHT, [](DOMNode& node) {
318             float heightBegin = 0.0f;
319             float heightEnd = node.GetHeight().Value();
320             node.propertyHeightAnimation_ = node.SetPropertyFloatAnimationKeyframe(heightBegin, heightEnd);
321         } },
322         { DOM_TRANSITION_BACKGROUND_COLOR, [](DOMNode& node) {
323             Color backgroundColorBegin = Color::TRANSPARENT;
324             Color backgroundColorEnd = node.GetBackGroundColor();
325             node.propertyColorAnimation_ =
326                     node.SetPropertyColorAnimationKeyframe(backgroundColorBegin, backgroundColorEnd);
327         } },
328     };
329 
330     auto animationIter = propertyAnimationMap.find(property);
331     if (animationIter != propertyAnimationMap.end()) {
332         animationIter->second(*this);
333     }
334     if (property == "all") {
335         for (auto propertyAnimation : propertyAnimationMap) {
336             propertyAnimation.second(*this);
337         }
338     }
339 }
340 
SetPropertyFloatAnimationKeyframe(float begin,float end)341 RefPtr<KeyframeAnimation<float>> DOMNode::SetPropertyFloatAnimationKeyframe(float begin, float end)
342 {
343     auto propertyDimensionAnimation = AceType::MakeRefPtr<KeyframeAnimation<float>>();
344     auto keyframeBegin = AceType::MakeRefPtr<Keyframe<float>>(0.0f, begin);
345     auto keyframeEnd = AceType::MakeRefPtr<Keyframe<float>>(1.0f, end);
346     propertyDimensionAnimation->AddKeyframe(keyframeBegin);
347     propertyDimensionAnimation->AddKeyframe(keyframeEnd);
348     return propertyDimensionAnimation;
349 }
350 
SetPropertyColorAnimationKeyframe(const Color & begin,const Color & end)351 RefPtr<KeyframeAnimation<Color>> DOMNode::SetPropertyColorAnimationKeyframe(const Color& begin, const Color& end)
352 {
353     auto propertyColorAnimation = AceType::MakeRefPtr<KeyframeAnimation<Color>>();
354     auto keyframeBegin = AceType::MakeRefPtr<Keyframe<Color>>(0.0f, begin);
355     auto keyframeEnd = AceType::MakeRefPtr<Keyframe<Color>>(1.0f, end);
356     propertyColorAnimation->AddKeyframe(keyframeBegin);
357     propertyColorAnimation->AddKeyframe(keyframeEnd);
358     return propertyColorAnimation;
359 }
360 
TransitionOptionSetKeyframes(TweenOption & transitionOption)361 void DOMNode::TransitionOptionSetKeyframes(TweenOption& transitionOption)
362 {
363     transitionOption.SetDuration(transitionDuration_);
364     transitionOption.SetFillMode(FillMode::FORWARDS);
365     transitionOption.SetCurve(CreateCurve(transitionTimeFunction_));
366     transitionOption.SetDelay(transitionDelay_);
367     if (propertyWidthAnimation_ && !propertyWidthAnimation_->GetKeyframes().empty()) {
368         transitionOption.SetPropertyAnimationFloat(PropertyAnimatableType::PROPERTY_WIDTH, propertyWidthAnimation_);
369     }
370     if (propertyHeightAnimation_ && !propertyHeightAnimation_->GetKeyframes().empty()) {
371         transitionOption.SetPropertyAnimationFloat(PropertyAnimatableType::PROPERTY_HEIGHT,
372             propertyHeightAnimation_);
373     }
374     if (propertyColorAnimation_ && !propertyColorAnimation_->GetKeyframes().empty()) {
375         transitionOption.SetColorAnimation(propertyColorAnimation_);
376     }
377 }
378 
SetStyle(const std::vector<std::pair<std::string,std::string>> & styles)379 void DOMNode::SetStyle(const std::vector<std::pair<std::string, std::string>>& styles)
380 {
381     std::vector<std::pair<std::string, std::string>> tempStyles;
382     for (const auto& style : styles) {
383         if ((style.first == DOM_TRANSITION_NAME) || (style.first == DOM_TRANSITION_PROPERTY_DURATION)) {
384             transitionStyleUpdated_ = true;
385         }
386         if (style.first == DOM_BACKGROUND_COLOR) {
387             isTransitionColor_ = true;
388         }
389         CachePseudoClassStyle(style);
390         if (style.first.find(DOM_PSEUDO_CLASS_SYMBOL) == std::string::npos) {
391             if (!SetCurrentStyle(style)) {
392                 tempStyles.emplace_back(style);
393             }
394         } else {
395             tempStyles.emplace_back(style);
396         }
397     }
398     if (declaration_) {
399         declaration_->SetStyle(tempStyles);
400     }
401     OnSetStyleFinished();
402 }
403 
SetCurrentStyle(const std::pair<std::string,std::string> & style)404 bool DOMNode::SetCurrentStyle(const std::pair<std::string, std::string>& style)
405 {
406     if (SetSpecializedStyle(style)) {
407         // If the subclass consumes this property, it will no longer look in the general property.
408         return true;
409     }
410     // Operator map for styles
411     static const std::unordered_map<std::string, void (*)(const std::string&, DOMNode&)> styleOperators = {
412         // Set width and height
413         { DOM_TRANSFORM, &DOMNode::SetTransform },
414         { DOM_TRANSITION_PROPERTY,
415             [](const std::string& val, DOMNode& node) {
416                 node.ParseTransitionPropertyStyle(val);
417             } },
418         { DOM_TRANSITION_PROPERTY_DURATION,
419             [](const std::string& val, DOMNode& node) {
420                 node.transitionDuration_ = StringUtils::StringToInt(val) * MS_TO_S;
421             } },
422         { DOM_TRANSITION_PROPERTY_TIMING_FUNCTION,
423             [](const std::string& val, DOMNode& node) {
424                 node.transitionTimeFunction_ = val;
425             } },
426         { DOM_TRANSITION_PROPERTY_DELAY,
427             [](const std::string& val, DOMNode& node) {
428                 node.transitionDelay_ = StringUtils::StringToInt(val) * MS_TO_S;
429             } },
430     };
431     auto operatorIter = styleOperators.find(style.first);
432     if (operatorIter != styleOperators.end()) {
433         operatorIter->second(style.second, *this);
434         return true;
435     }
436     return false;
437 }
438 
OnActive(bool isActive)439 void DOMNode::OnActive(bool isActive)
440 {
441     isActive_ = isActive;
442     UpdatePseudoStyle(true);
443 }
444 
OnFocus(bool isFocus)445 void DOMNode::OnFocus(bool isFocus)
446 {
447     isFocus_ = isFocus;
448     UpdatePseudoStyle(true);
449 }
450 
OnChecked(bool isChecked)451 void DOMNode::OnChecked(bool isChecked)
452 {
453     if (declaration_) {
454         declaration_->SetIsChecked(isChecked);
455     }
456     UpdatePseudoStyle(true);
457 }
458 
OnHover(bool isHover)459 void DOMNode::OnHover(bool isHover)
460 {
461     if (declaration_) {
462         declaration_->SetIsHover(isHover);
463     }
464     UpdatePseudoStyle(true);
465 }
466 
MarkNeedUpdate()467 void DOMNode::MarkNeedUpdate()
468 {
469     auto pipelineContext = pipelineContext_.Upgrade();
470     if (!pipelineContext) {
471         LOGE("pipelineContext_ is nullptr");
472         return;
473     }
474     rootComponent_->MarkNeedUpdate();
475     rootComponent_->SetUpdateType(UpdateType::ALL);
476     pipelineContext->ScheduleUpdate(rootComponent_);
477 }
478 
SetOnFocusClick(const EventMarker & eventMarker)479 void DOMNode::SetOnFocusClick(const EventMarker& eventMarker)
480 {
481     if (!focusableEventComponent_) {
482         return;
483     }
484     focusableEventComponent_->SetOnClickId(eventMarker);
485 }
486 
IsNodeDisabled() const487 bool DOMNode::IsNodeDisabled() const
488 {
489     return declaration_ ? declaration_->IsDisabled() : false;
490 }
491 
ResetDefaultStyles()492 void DOMNode::ResetDefaultStyles()
493 {
494     if (declaration_) {
495         declaration_->ResetDefaultStyles();
496     }
497 
498     displayComponent_.Reset();
499     if (transformComponent_) {
500         transformComponent_->ResetTransform();
501     }
502 }
503 
UpdatePseudoStyleByStatus(int32_t status,bool isBackendChange)504 void DOMNode::UpdatePseudoStyleByStatus(int32_t status, bool isBackendChange)
505 {
506     std::unordered_map<std::string, std::string> matchedStyleMap;
507     do {
508         if (pseudoClassStyleMap_.empty()) {
509             break;
510         }
511         // first:use status as the key, search the complete matched;
512         // second:if first do not matched any, calculate the max value of key & status, select the max value one.
513         auto matchedStyle = pseudoClassStyleMap_.find(status);
514         if (matchedStyle != pseudoClassStyleMap_.end()) {
515             matchedStyleMap = matchedStyle->second;
516         } else {
517             uint32_t maxAndResult = 0;
518             uint32_t maxValueKey = pseudoClassStyleMap_.begin()->first;
519             // status & map key, select the max result one
520             for (const auto& pseudoClass : pseudoClassStyleMap_) {
521                 uint32_t key = pseudoClass.first;
522                 uint32_t andResult = key & static_cast<uint32_t>(status);
523                 if (andResult > maxAndResult) {
524                     maxAndResult = andResult;
525                     maxValueKey = key;
526                 }
527             }
528             // if matched style except none pseudo style
529             auto iter = pseudoClassStyleMap_.find(maxValueKey);
530             if (maxAndResult > 0 && iter != pseudoClassStyleMap_.end()) {
531                 matchedStyleMap = iter->second;
532             }
533         }
534     } while (0);
535 
536     ResetDefaultStyles();
537     ResetInitializedStyle();
538 
539     // if not none pseudo style, need set none pseudo style first.
540     auto nonePseudoStylesIter = pseudoClassStyleMap_.find(STATE_NORMAL);
541     if (status != STATE_NORMAL && nonePseudoStylesIter != pseudoClassStyleMap_.end()) {
542         for (const auto& noneTypeStyle : nonePseudoStylesIter->second) {
543             if (!SetCurrentStyle(noneTypeStyle)) {
544                 declaration_->SetCurrentStyle(noneTypeStyle);
545             }
546         }
547     }
548     for (const auto& style : matchedStyleMap) {
549         if (!SetCurrentStyle(style)) {
550             declaration_->SetCurrentStyle(style);
551         }
552     }
553 
554     // do not move this for block into the up one
555     for (const auto& style : matchedStyleMap) {
556         if (style.first == DOM_TRANSITION_NAME) {
557             if (isTransitionNameUpdateFirst_) {
558                 isTransitionNameUpdateFirst_ = false;
559             } else {
560                 ParseTransitionNameStyle(style.second);
561                 propTransitionOption_ = TweenOption();
562                 TransitionOptionSetKeyframes(propTransitionOption_);
563                 transitionStyleUpdated_ = true;
564             }
565         }
566         if (style.first == DOM_TRANSITION_PROPERTY_DURATION) {
567             if (isTransitionDurationUpdateFirst_) {
568                 isTransitionDurationUpdateFirst_ = false;
569             } else {
570                 CreatePropertyAnimation(transitionPropertyName_);
571                 propTransitionOption_ = TweenOption();
572                 TransitionOptionSetKeyframes(propTransitionOption_);
573                 transitionStyleUpdated_ = true;
574             }
575         }
576     }
577     if (isBackendChange) {
578         auto pipelineContext = pipelineContext_.Upgrade();
579         if (!pipelineContext) {
580             LOGE("pipelineContext_ is nullptr");
581             return;
582         }
583         if (GetTag() != DOM_NODE_TAG_SPAN) {
584             UpdateUiComponents();
585         }
586         UpdateSpecializedComponentWithDeclaration();
587         PrepareSpecializedComponent();
588         CompositeComponents();
589         rootComponent_->MarkNeedUpdate();
590         rootComponent_->SetUpdateType(UpdateType::STYLE);
591         pipelineContext->ScheduleUpdate(rootComponent_);
592     }
593 }
594 
CalculatePseudoStatus() const595 uint32_t DOMNode::CalculatePseudoStatus() const
596 {
597     uint32_t status = STATE_NORMAL;
598     if (!declaration_) {
599         return STATE_NORMAL;
600     }
601     if (isActive_) {
602         status |= STATE_ACTIVE;
603     }
604     if (declaration_->IsDisabled()) {
605         status |= STATE_DISABLED;
606     }
607     if (isFocus_) {
608         status |= STATE_FOCUS;
609     }
610     if (declaration_->IsChecked()) {
611         status |= STATE_CHECKED;
612     }
613     if (declaration_->IsWaiting()) {
614         status |= STATE_WAITING;
615     }
616     if (declaration_->IsHover()) {
617         status |= STATE_HOVERED;
618     }
619     return status;
620 }
621 
UpdateStyleWithChildren()622 void DOMNode::UpdateStyleWithChildren()
623 {
624     auto status = CalculatePseudoStatus();
625     UpdatePseudoStyleByStatus(status, true);
626     SetAttrInternal(attributesCache_);
627 
628     for (const auto& child : children_) {
629         if (child) {
630             child->UpdateStyleWithChildren();
631         }
632     }
633 }
634 
UpdatePseudoStyle(bool isBackendChange)635 void DOMNode::UpdatePseudoStyle(bool isBackendChange)
636 {
637     if (!HasPseudo()) {
638         return;
639     }
640     auto status = CalculatePseudoStatus();
641     LOGD("UpdatePseudoStyle status is:%{public}d, isBackendChange:%{public}d", status, isBackendChange);
642     if (!isBackendChange) {
643         UpdatePseudoStyleByStatus(status, false);
644         return;
645     }
646     // Triggered by backend, elements may processing build or layout now. So post a new task to UI thread.
647     auto context = GetPipelineContext().Upgrade();
648     if (!context) {
649         LOGE("Context is null!");
650         return;
651     }
652     context->GetTaskExecutor()->PostTask(
653         [weak = AceType::WeakClaim(this), status = status]() {
654             auto node = weak.Upgrade();
655             if (!node) {
656                 return;
657             }
658             node->UpdatePseudoStyleByStatus(status, true);
659         },
660         TaskExecutor::TaskType::UI);
661 }
662 
CachePseudoClassStyle(const std::pair<std::string,std::string> & pseudoClassStyle)663 void DOMNode::CachePseudoClassStyle(const std::pair<std::string, std::string>& pseudoClassStyle)
664 {
665     uint32_t pseudoClassType = STATE_NORMAL;
666     const auto& styleKey = pseudoClassStyle.first;
667 
668     if (styleKey.find(DOM_ACTIVE_PSEUDO_CLASS) != std::string::npos) {
669         pseudoClassType |= STATE_ACTIVE;
670     }
671 
672     if (styleKey.find(DOM_DISABLED_PSEUDO_CLASS) != std::string::npos) {
673         pseudoClassType |= STATE_DISABLED;
674     }
675 
676     if (styleKey.find(DOM_FOCUS_PSEUDO_CLASS) != std::string::npos) {
677         pseudoClassType |= STATE_FOCUS;
678     }
679 
680     if (styleKey.find(DOM_CHECKED_PSEUDO_CLASS) != std::string::npos) {
681         pseudoClassType |= STATE_CHECKED;
682     }
683 
684     if (styleKey.find(DOM_WAITING_PSEUDO_CLASS) != std::string::npos) {
685         pseudoClassType |= STATE_WAITING;
686     }
687 
688     if (styleKey.find(DOM_HOVER_PSEUDO_CLASS) != std::string::npos) {
689         pseudoClassType |= STATE_HOVERED;
690     }
691 
692     cachedPseudoType_ |= pseudoClassType;
693 
694     auto pseudoSymbolLocation = styleKey.find(DOM_PSEUDO_CLASS_SYMBOL);
695     auto dealedStyleKey =
696         ((pseudoSymbolLocation != std::string::npos) ? styleKey.substr(0, pseudoSymbolLocation) : styleKey);
697 
698     auto styleMapIter = pseudoClassStyleMap_.find(pseudoClassType);
699 
700     if (styleMapIter != pseudoClassStyleMap_.end()) {
701         auto result = styleMapIter->second.try_emplace(dealedStyleKey, pseudoClassStyle.second);
702         if (!result.second) {
703             result.first->second = pseudoClassStyle.second;
704         }
705         return;
706     }
707     std::unordered_map<std::string, std::string> newPseudoMap;
708     newPseudoMap.emplace(dealedStyleKey, pseudoClassStyle.second);
709     pseudoClassStyleMap_.emplace(pseudoClassType, newPseudoMap);
710 }
711 
GenerateComponentNode()712 void DOMNode::GenerateComponentNode()
713 {
714     UpdatePseudoStyle(false);
715     if (GetTag() != DOM_NODE_TAG_SPAN) {
716         UpdateUiComponents();
717         UpdateTouchEventComponent();
718         UpdateGestureEventComponent();
719         UpdateMouseEventComponent();
720         UpdateFocusableEventComponents();
721         // Prepare for fixed position
722         UpdatePositionComponent();
723 #ifndef WEARABLE_PRODUCT
724         UpdateMultimodalComponent();
725         PrepareScrollComponent();
726 #endif
727     }
728     UpdateSpecializedComponentWithDeclaration();
729     PrepareSpecializedComponent();
730     CompositeComponents();
731     // Relative and absolute position needs to update the top component props.
732     UpdatePositionProps();
733     auto rootChild = AceType::DynamicCast<RenderComponent>(rootComponent_->GetChild());
734     if (isCustomComponent_) {
735         if (rootChild) {
736             rootChild->SetIsCustomComponent(isCustomComponent_);
737             rootChild->SetOnLayoutReadyMarker(EventMarker(GetNodeIdForEvent(), ""));
738         }
739     }
740     if (rootChild) {
741         int32_t zIndex = 0;
742         if (declaration_) {
743             auto& commonStyle = static_cast<CommonStyle&>(declaration_->GetStyle(StyleTag::COMMON_STYLE));
744             if (commonStyle.IsValid()) {
745                 zIndex = commonStyle.zIndex;
746             }
747         }
748         rootChild->SetZIndex(zIndex);
749     }
750     rootComponent_->MarkNeedUpdate();
751 }
752 
AddNode(const RefPtr<DOMNode> & node,int32_t slot)753 void DOMNode::AddNode(const RefPtr<DOMNode>& node, int32_t slot)
754 {
755     if (!node) {
756         return;
757     }
758     auto isExist = std::find_if(children_.begin(), children_.end(),
759         [node](const RefPtr<DOMNode>& child) { return child->GetNodeId() == node->GetNodeId(); });
760     if (isExist != children_.end()) {
761         LOGW("the node[%{public}d] has already in the children", node->GetNodeId());
762         return;
763     }
764     auto pos = children_.begin();
765     std::advance(pos, slot);
766     children_.insert(pos, node);
767     if (node->GetPosition() != PositionType::FIXED) {
768         if (!node->IsProxy() && GetDisplay() == DisplayType::NONE) {
769             node->GenerateComponentNode();
770         }
771         OnChildNodeAdded(node, slot);
772     }
773 }
774 
RemoveNode(const RefPtr<DOMNode> & node)775 void DOMNode::RemoveNode(const RefPtr<DOMNode>& node)
776 {
777     if (!node) {
778         return;
779     }
780     children_.remove_if([node](const RefPtr<DOMNode>& child) { return node->GetNodeId() == child->GetNodeId(); });
781     if (node->GetPosition() != PositionType::FIXED) {
782         OnChildNodeRemoved(node);
783     }
784 }
785 
SetDisplayStyle()786 void DOMNode::SetDisplayStyle()
787 {
788     switch (GetDisplay()) {
789         case DisplayType::NONE:
790             visible_ = VisibleType::GONE;
791             break;
792         case DisplayType::GRID:
793         case DisplayType::FLEX:
794         default:
795             VisibilityType visibility = VisibilityType::NO_SETTING;
796             if (declaration_) {
797                 auto& visibilityStyle =
798                     static_cast<CommonVisibilityStyle&>(declaration_->GetStyle(StyleTag::COMMON_VISIBILITY_STYLE));
799                 if (visibilityStyle.IsValid()) {
800                     visibility = visibilityStyle.visibility;
801                 }
802             }
803             visible_ = (visibility == VisibilityType::HIDDEN) ? VisibleType::INVISIBLE : VisibleType::VISIBLE;
804             break;
805     }
806 }
807 
BuildTransitionComponent()808 const RefPtr<PageTransitionComponent>& DOMNode::BuildTransitionComponent()
809 {
810     transitionComponent_ = AceType::MakeRefPtr<PageTransitionComponent>();
811     if (!declaration_) {
812         return transitionComponent_;
813     }
814 
815     transitionComponent_->SetTextDirection(declaration_->IsRightToLeft() ? TextDirection::RTL : TextDirection::LTR);
816     auto& pageTransitionStyle =
817         declaration_->MaybeResetStyle<CommonPageTransitionStyle>(StyleTag::COMMON_PAGE_TRANSITION_STYLE);
818     if (!pageTransitionStyle.IsValid()) {
819         return transitionComponent_;
820     }
821     if (pageTransitionStyle.transitionEnterOption.IsValid() || pageTransitionStyle.transitionExitOption.IsValid()) {
822         if (!pageTransitionStyle.transitionEnterOption.GetCurve()) {
823             // use FRICTION as transition default curve.
824             pageTransitionStyle.transitionEnterOption.SetCurve(Curves::FRICTION);
825             pageTransitionStyle.transitionExitOption.SetCurve(Curves::FRICTION);
826         }
827         transitionComponent_->SetContentTransitionOption(
828             pageTransitionStyle.transitionEnterOption, pageTransitionStyle.transitionExitOption);
829     }
830     return transitionComponent_;
831 }
832 
GetTransformType(const std::unique_ptr<JsonValue> & transformJson)833 std::string DOMNode::GetTransformType(const std::unique_ptr<JsonValue>& transformJson)
834 {
835     if (transformJson->IsNull()) {
836         LOGE("transformJson is null");
837         return "";
838     }
839     return transformJson->GetKey();
840 }
841 
GetTransformTypeValue(const std::unique_ptr<JsonValue> & transformJson)842 std::string DOMNode::GetTransformTypeValue(const std::unique_ptr<JsonValue>& transformJson)
843 {
844     if (transformJson->IsNull()) {
845         LOGE("transformJson is null");
846         return "";
847     }
848     std::string jsonValue = transformJson->GetString();
849     if (jsonValue.empty()) {
850         double jsonDouble = transformJson->GetDouble();
851         return std::to_string(jsonDouble);
852     }
853     return jsonValue;
854 }
855 
SetTransform(const std::string & value,DOMNode & node)856 void DOMNode::SetTransform(const std::string& value, DOMNode& node)
857 {
858     if (!node.transformComponent_) {
859         node.transformComponent_ = AceType::MakeRefPtr<TransformComponent>();
860     }
861     node.transformComponent_->ResetTransform(); // Avoid transfrom effect overlay.
862     auto jsonValue = node.GetTransformJsonValue(value);
863     std::unique_ptr<JsonValue> transformJson = JsonUtil::ParseJsonString(jsonValue);
864     for (int32_t index = 0; index < transformJson->GetArraySize(); ++index) {
865         std::string typeKey = node.GetTransformType(transformJson->GetArrayItem(index));
866         std::string typeValue = node.GetTransformTypeValue(transformJson->GetArrayItem(index));
867         if ((!typeKey.empty()) && (!typeValue.empty())) {
868             // Operator map for transform
869             static const std::unordered_map<std::string, void (*)(const std::string&, DOMNode&)> transformOperators = {
870                 { DOM_ROTATE,
871                     [](const std::string& typeValue, DOMNode& node) {
872                         node.transformComponent_->RotateZ(StringUtils::StringToDegree(typeValue));
873                     } },
874                 { DOM_ROTATE_3D,
875                     [](const std::string& typeValue, DOMNode& node) {
876                         std::vector<std::string> offsets;
877                         StringUtils::StringSpliter(typeValue, ' ', offsets);
878                         if (offsets.size() == FOUR_VALUES) {
879                             auto dx = StringToDouble(offsets[0]);
880                             auto dy = StringToDouble(offsets[1]);
881                             auto dz = StringToDouble(offsets[2]);
882                             auto degree = StringUtils::StringToDegree(offsets[3]);
883                             node.transformComponent_->Rotate(dx, dy, dz, degree);
884                         }
885                     } },
886                 { DOM_ROTATE_X,
887                     [](const std::string& typeValue, DOMNode& node) {
888                         node.transformComponent_->RotateX(StringUtils::StringToDegree(typeValue));
889                     } },
890                 { DOM_ROTATE_Y,
891                     [](const std::string& typeValue, DOMNode& node) {
892                         node.transformComponent_->RotateY(StringUtils::StringToDegree(typeValue));
893                     } },
894                 { DOM_ROTATE_Z,
895                     [](const std::string& typeValue, DOMNode& node) {
896                         node.transformComponent_->RotateZ(StringUtils::StringToDegree(typeValue));
897                     } },
898                 { SCALE,
899                     [](const std::string& typeValue, DOMNode& node) {
900                         if (typeValue.find(' ', 0) != std::string::npos) {
901                             Offset offset = ConvertStrToOffset(typeValue);
902                             node.transformComponent_->Scale(offset.GetX(), offset.GetY());
903                         } else {
904                             auto scaleValue = StringToDouble(typeValue);
905                             node.transformComponent_->Scale(scaleValue, scaleValue);
906                         }
907                     } },
908                 { DOM_SCALE_3D,
909                     [](const std::string& typeValue, DOMNode& node) {
910                         std::vector<std::string> offsets;
911                         StringUtils::StringSpliter(typeValue, ' ', offsets);
912                         if (offsets.size() == THREE_VALUES) {
913                             auto scaleX = StringToDouble(offsets[0]);
914                             auto scaleY = StringToDouble(offsets[1]);
915                             auto scaleZ = StringToDouble(offsets[2]);
916                             node.transformComponent_->Scale(scaleX, scaleY, scaleZ);
917                         }
918                     } },
919                 { DOM_SCALE_X, [](const std::string& typeValue,
920                                    DOMNode& node) { node.transformComponent_->ScaleX(StringToDouble(typeValue)); } },
921                 { DOM_SCALE_Y, [](const std::string& typeValue,
922                                    DOMNode& node) { node.transformComponent_->ScaleY(StringToDouble(typeValue)); } },
923                 { DOM_SCALE_Z, [](const std::string& typeValue,
924                                    DOMNode& node) { node.transformComponent_->ScaleZ(StringToDouble(typeValue)); } },
925                 { DOM_TRANSLATE,
926                     [](const std::string& typeValue, DOMNode& node) {
927                         std::vector<std::string> offsets;
928                         StringUtils::StringSpliter(typeValue, ' ', offsets);
929                         if (offsets.size() == TRANSFORM_DUAL) {
930                             node.transformComponent_->Translate(
931                                 node.ParseDimension(offsets[0]), node.ParseDimension(offsets[1]));
932                         } else if (offsets.size() == TRANSFORM_SINGLE) {
933                             node.transformComponent_->TranslateX(node.ParseDimension(offsets[0]));
934                         }
935                     } },
936                 { DOM_TRANSLATE_3D,
937                     [](const std::string& typeValue, DOMNode& node) {
938                         std::vector<std::string> offsets;
939                         StringUtils::StringSpliter(typeValue, ' ', offsets);
940                         if (offsets.size() == THREE_VALUES) {
941                             auto dx = node.ParseDimension(offsets[0]);
942                             auto dy = node.ParseDimension(offsets[1]);
943                             auto dz = node.ParseDimension(offsets[2]);
944                             node.transformComponent_->Translate(dx, dy, dz);
945                         }
946                     } },
947                 { DOM_TRANSLATE_X,
948                     [](const std::string& typeValue, DOMNode& node) {
949                         node.transformComponent_->TranslateX(node.ParseDimension(typeValue));
950                     } },
951                 { DOM_TRANSLATE_Y,
952                     [](const std::string& typeValue, DOMNode& node) {
953                         node.transformComponent_->TranslateY(node.ParseDimension(typeValue));
954                     } },
955                 { DOM_TRANSLATE_Z,
956                     [](const std::string& typeValue, DOMNode& node) {
957                         node.transformComponent_->TranslateZ(node.ParseDimension(typeValue));
958                     } },
959                 { DOM_SKEW,
960                     [](const std::string& typeValue, DOMNode& node) {
961                         std::vector<std::string> offsets;
962                         StringUtils::StringSpliter(typeValue, ' ', offsets);
963                         if (offsets.size() == TRANSFORM_DUAL) {
964                             auto degreeX = StringUtils::StringToDegree(offsets[0]);
965                             auto degreeY = StringUtils::StringToDegree(offsets[1]);
966                             node.transformComponent_->Skew(degreeX, degreeY);
967                         } else if (offsets.size() == TRANSFORM_SINGLE) {
968                             auto degree = StringUtils::StringToDegree(typeValue);
969                             node.transformComponent_->Skew(degree, 0.0f);
970                         }
971                     } },
972                 { DOM_SKEW_X,
973                     [](const std::string& typeValue, DOMNode& node) {
974                         node.transformComponent_->SkewX(StringUtils::StringToDegree(typeValue));
975                     } },
976                 { DOM_SKEW_Y,
977                     [](const std::string& typeValue, DOMNode& node) {
978                         node.transformComponent_->SkewY(StringUtils::StringToDegree(typeValue));
979                     } },
980                 { DOM_MATRIX,
981                     [](const std::string& typeValue, DOMNode& node) {
982                         std::vector<std::string> offsets;
983                         StringUtils::StringSpliter(typeValue, ' ', offsets);
984                         if (offsets.size() == TRANSFORM_SIX) {
985                             double scaleX = StringToDouble(offsets[0]);
986                             double skewY = StringToDouble(offsets[1]);
987                             double skewX = StringToDouble(offsets[2]);
988                             double scaleY = StringToDouble(offsets[3]);
989                             double translateX = StringToDouble(offsets[4]);
990                             double translateY = StringToDouble(offsets[5]);
991                             node.transformComponent_->Matrix(scaleX, skewY, skewX, scaleY, translateX, translateY);
992                         }
993                     } },
994                 { DOM_MATRIX_3D,
995                     [](const std::string& typeValue, DOMNode& node) {
996                         std::vector<std::string> offsets;
997                         StringUtils::StringSpliter(typeValue, ' ', offsets);
998                         if (offsets.size() == TRANSFORM_SIXTEEN) {
999                             std::vector<double> matrix;
1000                             for (const auto& offset : offsets) {
1001                                 matrix.push_back(StringToDouble(offset));
1002                             }
1003                             node.transformComponent_->Matrix3d(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4],
1004                                 matrix[5], matrix[6], matrix[7], matrix[8], matrix[9], matrix[10], matrix[11],
1005                                 matrix[12], matrix[13], matrix[14], matrix[15]);
1006                         }
1007                     } },
1008                 { DOM_PERSPECTIVE,
1009                     [](const std::string& typeValue, DOMNode& node) {
1010                         node.transformComponent_->Perspective(node.ParseDimension(typeValue));
1011                     } },
1012             };
1013 
1014             auto operatorIter = transformOperators.find(typeKey);
1015             if (operatorIter != transformOperators.end()) {
1016                 operatorIter->second(typeValue, node);
1017             }
1018         }
1019     }
1020 }
1021 
1022 // Convert transform style to json format, such as rotate(50deg) to {"ratate":"50deg"}
GetTransformJsonValue(const std::string & value)1023 std::string DOMNode::GetTransformJsonValue(const std::string& value)
1024 {
1025     auto rightIndex = value.find('(');
1026     auto leftIndex = value.find(')');
1027     std::string jsonValue = value;
1028 
1029     if (rightIndex != std::string::npos && leftIndex != std::string::npos && (leftIndex - 1 - rightIndex > 0)) {
1030         std::string transformType = value.substr(0, rightIndex);
1031         std::string transformValue = value.substr(rightIndex + 1, leftIndex - 1 - rightIndex);
1032         jsonValue = "{\"" + transformType + "\":\"" + transformValue + "\"}";
1033     }
1034 
1035     return jsonValue;
1036 }
1037 
AddKeyframe(double time,double typeValue,RefPtr<KeyframeAnimation<float>> & transformKeyframes)1038 void DOMNode::AddKeyframe(double time, double typeValue, RefPtr<KeyframeAnimation<float>>& transformKeyframes)
1039 {
1040     auto keyframe = AceType::MakeRefPtr<Keyframe<float>>(time, typeValue);
1041     transformKeyframes->AddKeyframe(keyframe);
1042 }
1043 
AddKeyframe(double time,const std::string & typeValue,RefPtr<KeyframeAnimation<float>> & transformKeyframes)1044 void DOMNode::AddKeyframe(
1045     double time, const std::string& typeValue, RefPtr<KeyframeAnimation<float>>& transformKeyframes)
1046 {
1047     DOMNode::AddKeyframe(time, StringToDouble(typeValue), transformKeyframes);
1048 }
1049 
SetSharedTransitionStyle(const std::vector<std::unordered_map<std::string,std::string>> & animationKeyframes)1050 void DOMNode::SetSharedTransitionStyle(
1051     const std::vector<std::unordered_map<std::string, std::string>>& animationKeyframes)
1052 {
1053     if (!declaration_) {
1054         return;
1055     }
1056     auto& shareTransitionStyle =
1057         declaration_->MaybeResetStyle<CommonShareTransitionStyle>(StyleTag::COMMON_SHARE_TRANSITION_STYLE);
1058     if (!shareTransitionStyle.IsValid()) {
1059         return;
1060     }
1061     if (!ParseAnimationStyle(animationKeyframes)) {
1062         return;
1063     }
1064     shareTransitionStyle.sharedTransitionOption = TweenOption();
1065     TweenOptionSetKeyframes(shareTransitionStyle.sharedTransitionOption);
1066 }
1067 
ParseAnimationStyle(const std::vector<std::unordered_map<std::string,std::string>> & animationKeyframes)1068 bool DOMNode::ParseAnimationStyle(const std::vector<std::unordered_map<std::string, std::string>>& animationKeyframes)
1069 {
1070     if (animationKeyframes.empty()) {
1071         return false;
1072     }
1073     animationUtil_.ParseAnimationStyle(animationKeyframes, declaration_, GetThemeConstants());
1074     propAnimations_ = animationUtil_.GetPropAnimationMap();
1075     animationName_ = animationUtil_.GetAnimationName();
1076 
1077     if (propAnimations_.find(AnimatableType::PROPERTY_OPACITY) != propAnimations_.end()) {
1078         if (declaration_) {
1079             declaration_->SetHasDisplayStyle(true);
1080         }
1081     }
1082     return true;
1083 }
1084 
SetAnimationStyle(const std::vector<std::unordered_map<std::string,std::string>> & animationKeyframes)1085 void DOMNode::SetAnimationStyle(const std::vector<std::unordered_map<std::string, std::string>>& animationKeyframes)
1086 {
1087     if (!declaration_ || !ParseAnimationStyle(animationKeyframes)) {
1088         return;
1089     }
1090     if (isTransition_) {
1091         auto& pageTransitionStyle =
1092             declaration_->MaybeResetStyle<CommonPageTransitionStyle>(StyleTag::COMMON_PAGE_TRANSITION_STYLE);
1093         if (pageTransitionStyle.IsValid()) {
1094             if (isEnter_) {
1095                 TweenOptionSetKeyframes(pageTransitionStyle.transitionEnterOption);
1096             } else {
1097                 TweenOptionSetKeyframes(pageTransitionStyle.transitionExitOption);
1098             }
1099         }
1100     } else {
1101         auto& animationStyle = declaration_->MaybeResetStyle<CommonAnimationStyle>(StyleTag::COMMON_ANIMATION_STYLE);
1102         if (animationStyle.IsValid()) {
1103             animationStyle.tweenOption = TweenOption();
1104             TweenOptionSetKeyframes(animationStyle.tweenOption);
1105             animationStyleUpdated_ = true;
1106         }
1107     }
1108 }
1109 
UpdatePropAnimations(const PropAnimationMap & animations)1110 void DOMNode::UpdatePropAnimations(const PropAnimationMap& animations)
1111 {
1112     if (boxComponent_ != nullptr) {
1113         boxComponent_->ClearAnimatables();
1114     }
1115     if (displayComponent_ != nullptr) {
1116         displayComponent_->ClearAnimatables();
1117     }
1118     for (const auto& [type, animation] : animations) {
1119         switch (type) {
1120             case AnimatableType::PROPERTY_WIDTH:
1121             case AnimatableType::PROPERTY_HEIGHT:
1122             case AnimatableType::PROPERTY_BG_COLOR:
1123             case AnimatableType::PROPERTY_MARGIN_LEFT:
1124             case AnimatableType::PROPERTY_MARGIN_TOP:
1125             case AnimatableType::PROPERTY_MARGIN_RIGHT:
1126             case AnimatableType::PROPERTY_MARGIN_BOTTOM:
1127             case AnimatableType::PROPERTY_PADDING_LEFT:
1128             case AnimatableType::PROPERTY_PADDING_TOP:
1129             case AnimatableType::PROPERTY_PADDING_RIGHT:
1130             case AnimatableType::PROPERTY_PADDING_BOTTOM:
1131             case AnimatableType::PROPERTY_BACKGROUND_POSITION:
1132             case AnimatableType::PROPERTY_BACKGROUND_SIZE:
1133             case AnimatableType::PROPERTY_BORDER_LEFT_WIDTH:
1134             case AnimatableType::PROPERTY_BORDER_TOP_WIDTH:
1135             case AnimatableType::PROPERTY_BORDER_RIGHT_WIDTH:
1136             case AnimatableType::PROPERTY_BORDER_BOTTOM_WIDTH:
1137             case AnimatableType::PROPERTY_BORDER_LEFT_COLOR:
1138             case AnimatableType::PROPERTY_BORDER_TOP_COLOR:
1139             case AnimatableType::PROPERTY_BORDER_RIGHT_COLOR:
1140             case AnimatableType::PROPERTY_BORDER_BOTTOM_COLOR:
1141             case AnimatableType::PROPERTY_BORDER_TOP_LEFT_RADIUS:
1142             case AnimatableType::PROPERTY_BORDER_TOP_RIGHT_RADIUS:
1143             case AnimatableType::PROPERTY_BORDER_BOTTOM_LEFT_RADIUS:
1144             case AnimatableType::PROPERTY_BORDER_BOTTOM_RIGHT_RADIUS:
1145             case AnimatableType::PROPERTY_BORDER_LEFT_STYLE:
1146             case AnimatableType::PROPERTY_BORDER_RIGHT_STYLE:
1147             case AnimatableType::PROPERTY_BORDER_TOP_STYLE:
1148             case AnimatableType::PROPERTY_BORDER_BOTTOM_STYLE:
1149             case AnimatableType::PROPERTY_FILTER_BLUR:
1150             case AnimatableType::PROPERTY_BACKDROP_FILTER_BLUR:
1151             case AnimatableType::PROPERTY_WINDOW_FILTER_BLUR:
1152             case AnimatableType::PROPERTY_BOX_SHADOW: {
1153                 if (boxComponent_ != nullptr) {
1154                     boxComponent_->AddAnimatable(type, animation);
1155                 }
1156                 break;
1157             }
1158             case AnimatableType::PROPERTY_OPACITY: {
1159                 if (displayComponent_ != nullptr) {
1160                     displayComponent_->AddAnimatable(type, animation);
1161                 }
1162                 break;
1163             }
1164             default:
1165                 break;
1166         }
1167     }
1168 }
1169 
UpdatePositionAnimations(const RefPtr<Component> componet)1170 void DOMNode::UpdatePositionAnimations(const RefPtr<Component> componet)
1171 {
1172     if (componet != nullptr) {
1173         static const AnimatableType positionAnimatableType[] = {
1174             AnimatableType::PROPERTY_POSITION_LEFT,
1175             AnimatableType::PROPERTY_POSITION_TOP,
1176             AnimatableType::PROPERTY_POSITION_RIGHT,
1177             AnimatableType::PROPERTY_POSITION_BOTTOM,
1178         };
1179 
1180         for (const auto& type : positionAnimatableType) {
1181             const auto& animation = propAnimations_[type];
1182             if (animation) {
1183                 componet->AddAnimatable(type, animation);
1184             }
1185         }
1186     }
1187 }
1188 
TweenOptionSetKeyframes(TweenOption & tweenOption)1189 void DOMNode::TweenOptionSetKeyframes(TweenOption& tweenOption)
1190 {
1191     auto pos = propAnimations_.find(AnimatableType::PROPERTY_OPACITY);
1192     if (pos != propAnimations_.end()) {
1193         auto opacityAnimation = AceType::MakeRefPtr<KeyframeAnimation<float>>();
1194         for (auto& item : pos->second->GetAnimatable()) {
1195             auto opacityAnimatable = AceType::DynamicCast<AnimatableData<float>>(item);
1196             if (opacityAnimatable) {
1197                 opacityAnimation->AddKeyframe(
1198                     AceType::MakeRefPtr<Keyframe<float>>(item->GetTimePoint(), opacityAnimatable->GetValue()));
1199             }
1200         }
1201         tweenOption.SetOpacityAnimation(opacityAnimation);
1202         propAnimations_.erase(pos);
1203     }
1204     if (!propAnimations_.empty()) {
1205         tweenOption.SetAnimatables(propAnimations_);
1206     }
1207     animationUtil_.GetTransformConvertor().AddAnimationToTweenOption(tweenOption);
1208 }
1209 
SetCustomAnimationStyleUpdate(bool enable)1210 void DOMNode::SetCustomAnimationStyleUpdate(bool enable)
1211 {
1212     customAnimationStyleUpdated_ = enable;
1213 }
1214 
CompositeComponents()1215 void DOMNode::CompositeComponents()
1216 {
1217     std::vector<RefPtr<SingleChild>> components;
1218     if (flexItemComponent_) {
1219         // Update flex item after PrepareSpecializedComponent to make sure sub class has finished prepare.
1220         UpdateFlexItemComponent();
1221         components.emplace_back(flexItemComponent_);
1222     }
1223     if (tweenComponent_) {
1224         tweenComponent_->SetLeafNode(IsLeafNode());
1225         components.emplace_back(tweenComponent_);
1226     }
1227     if (displayComponent_) {
1228         displayComponent_->DisableLayer(IsLeafNode());
1229         components.emplace_back(displayComponent_);
1230         if (focusableEventComponent_) {
1231             focusableEventComponent_->SetShow(GetDisplay() != DisplayType::NONE);
1232         }
1233     }
1234     if (transformComponent_) {
1235         components.emplace_back(transformComponent_);
1236     }
1237     if (focusableEventComponent_) {
1238         components.emplace_back(focusableEventComponent_);
1239     }
1240     if (touchEventComponent_) {
1241         touchEventComponent_->SetIsVisible(visible_ == VisibleType::VISIBLE);
1242         components.emplace_back(touchEventComponent_);
1243     }
1244     if (gestureEventComponent_) {
1245         gestureEventComponent_->SetIsVisible(visible_ == VisibleType::VISIBLE);
1246         components.emplace_back(gestureEventComponent_);
1247     }
1248 #ifndef WEARABLE_PRODUCT
1249     if (multimodalComponent_) {
1250         components.emplace_back(multimodalComponent_);
1251     }
1252 #endif
1253     if (mouseEventComponent_) {
1254         components.emplace_back(mouseEventComponent_);
1255     }
1256     if (propTransitionComponent_) {
1257         components.emplace_back(propTransitionComponent_);
1258     }
1259     if (boxComponent_) {
1260         components.emplace_back(boxComponent_);
1261     }
1262     if (scrollComponent_) {
1263         components.emplace_back(scrollComponent_);
1264     }
1265     if (sharedTransitionComponent_) {
1266         components.emplace_back(sharedTransitionComponent_);
1267     }
1268 
1269     auto mainComponent = GetSpecializedComponent();
1270     if (!components.empty() &&
1271         (AceType::InstanceOf<TextureComponent>(mainComponent) ||
1272         AceType::InstanceOf<ListComponent>(mainComponent) ||
1273         AceType::InstanceOf<ListItemComponent>(mainComponent) ||
1274         AceType::InstanceOf<WebComponent>(mainComponent) ||
1275         AceType::InstanceOf<XComponentComponent>(mainComponent))) {
1276         Component::MergeRSNode(components);
1277         Component::MergeRSNode(mainComponent);
1278     } else {
1279         Component::MergeRSNode(components, mainComponent);
1280     }
1281     // Only fixed position has position component
1282     if (positionComponent_ && GetPosition() == PositionType::FIXED) {
1283         components.emplace(components.begin(), positionComponent_);
1284         Component::MergeRSNode(positionComponent_);
1285     }
1286 
1287     // First, composite all common components.
1288     for (int32_t idx = static_cast<int32_t>(components.size()) - 1; idx - 1 >= 0; --idx) {
1289         components[idx - 1]->SetChild(DynamicCast<Component>(components[idx]));
1290     }
1291     // Then composite specialized components.
1292     auto compositeComponent = CompositeSpecializedComponent(components);
1293     // At last add to composite component.
1294     rootComponent_->SetChild(compositeComponent);
1295     // final set disabled status.
1296     if (declaration_ && declaration_->IsDisabled() != rootComponent_->IsDisabledStatus()) {
1297         rootComponent_->SetDisabledStatus(declaration_->IsDisabled());
1298     }
1299 }
1300 
UpdateFlexItemComponent()1301 void DOMNode::UpdateFlexItemComponent()
1302 {
1303     if (!declaration_ || !flexItemComponent_) {
1304         return;
1305     }
1306 
1307     auto& flexStyle = static_cast<CommonFlexStyle&>(declaration_->GetStyle(StyleTag::COMMON_FLEX_STYLE));
1308     if (flexStyle.IsValid()) {
1309         flexItemComponent_->SetFlexGrow(flexStyle.flexGrow);
1310         flexItemComponent_->SetFlexShrink(flexStyle.flexShrink);
1311         flexItemComponent_->SetFlexBasis(flexStyle.flexBasis);
1312         flexItemComponent_->SetFlexWeight(flexStyle.flexWeight);
1313         flexItemComponent_->SetDisplayIndex(flexStyle.displayIndex);
1314     }
1315     const LinearMapNode<FlexAlign> ALIGN_SELF_TABLE[] = {
1316         { DOM_ALIGN_ITEMS_BASELINE, FlexAlign::BASELINE },
1317         { DOM_ALIGN_ITEMS_CENTER, FlexAlign::CENTER },
1318         { DOM_ALIGN_ITEMS_END, FlexAlign::FLEX_END },
1319         { DOM_ALIGN_ITEMS_START, FlexAlign::FLEX_START },
1320         { DOM_ALIGN_ITEMS_STRETCH, FlexAlign::STRETCH },
1321     };
1322     auto& commonStyle = static_cast<CommonStyle&>(declaration_->GetStyle(StyleTag::COMMON_STYLE));
1323     int64_t index = -1;
1324     if (commonStyle.IsValid()) {
1325         index = BinarySearchFindIndex(ALIGN_SELF_TABLE, ArraySize(ALIGN_SELF_TABLE), commonStyle.alignSelf.c_str());
1326     }
1327     if (index != -1) {
1328         flexItemComponent_->SetAlignSelf(ALIGN_SELF_TABLE[index].value);
1329     } else {
1330         flexItemComponent_->SetAlignSelf(FlexAlign::AUTO);
1331     }
1332     auto parentNode = parentNode_.Upgrade();
1333     if ((parentNode) &&
1334         (parentNode->GetTag() == DOM_NODE_TAG_DIV || parentNode->GetTag() == DOM_NODE_TAG_GRID_COLUMN)) {
1335         auto parent = AceType::DynamicCast<DOMDiv>(parentNode);
1336         // Stretch flag means that if the child's main size is determined, it can not be stretched.
1337         if ((parent->GetFlexDirection() == FlexDirection::ROW && (GreatOrEqual(GetHeight().Value(), 0.0) ||
1338             GetHeight().Unit() == DimensionUnit::CALC)) ||
1339             (parent->GetFlexDirection() == FlexDirection::COLUMN && (GreatOrEqual(GetWidth().Value(), 0.0) ||
1340             GetWidth().Unit() == DimensionUnit::CALC))) {
1341             flexItemComponent_->SetStretchFlag(false);
1342         } else {
1343             flexItemComponent_->SetStretchFlag(true);
1344         }
1345     }
1346     auto& sizeStyle = static_cast<CommonSizeStyle&>(declaration_->GetStyle(StyleTag::COMMON_SIZE_STYLE));
1347     if (sizeStyle.IsValid()) {
1348         // Make sure input layout constraint is valid
1349         flexItemComponent_->SetMaxHeight(sizeStyle.maxHeight);
1350         flexItemComponent_->SetMaxWidth(sizeStyle.maxWidth);
1351         flexItemComponent_->SetMinHeight(sizeStyle.minHeight);
1352         flexItemComponent_->SetMinWidth(sizeStyle.minWidth);
1353         // If set aspect Ratio, it cannot be stretch
1354         if (GreatNotEqual(sizeStyle.aspectRatio, 0.0)) {
1355             flexItemComponent_->SetStretchFlag(false);
1356         }
1357     }
1358     // If set display, this flexItem is ignored.
1359     flexItemComponent_->SetIsHidden(GetDisplay() == DisplayType::NONE);
1360 }
1361 
UpdateUiComponents()1362 void DOMNode::UpdateUiComponents()
1363 {
1364     UpdateBoxComponent();
1365     UpdateDisplayComponent();
1366     UpdateTweenComponent();
1367 }
1368 
UpdateBoxSize(const CalcDimension & width,const CalcDimension & height)1369 void DOMNode::UpdateBoxSize(const CalcDimension& width, const CalcDimension& height)
1370 {
1371     if (height.Unit() == DimensionUnit::CALC) {
1372         boxComponent_->SetHeight(height.CalcValue(), height.Unit());
1373     } else {
1374         boxComponent_->SetHeight(height.Value(), height.Unit());
1375     }
1376     if (width.Unit() == DimensionUnit::CALC) {
1377         boxComponent_->SetWidth(width.CalcValue(), width.Unit());
1378     } else {
1379         boxComponent_->SetWidth(width.Value(), width.Unit());
1380     }
1381 }
1382 
UpdateBoxPadding(const Edge & padding)1383 void DOMNode::UpdateBoxPadding(const Edge& padding)
1384 {
1385     boxComponent_->SetPadding(padding);
1386 }
1387 
UpdateBoxBorder(const Border & border)1388 void DOMNode::UpdateBoxBorder(const Border& border)
1389 {
1390     if (declaration_ && declaration_->GetBackDecoration()) {
1391         declaration_->GetBackDecoration()->SetBorder(border);
1392     }
1393 }
1394 
UpdateBoxComponent()1395 void DOMNode::UpdateBoxComponent()
1396 {
1397     if (!declaration_) {
1398         return;
1399     }
1400 
1401     if (declaration_->HasBoxStyle()) {
1402         if (GetWidth().Unit() != DimensionUnit::CALC && GetHeight().Unit() != DimensionUnit::CALC) {
1403             UpdateBoxSize(GetWidth(), GetHeight());
1404         } else if (GetWidth().Unit() == DimensionUnit::CALC && GetHeight().Unit() != DimensionUnit::CALC) {
1405             UpdateBoxSize(GetCalcWidth(), GetHeight());
1406         } else if (GetWidth().Unit() != DimensionUnit::CALC && GetHeight().Unit() == DimensionUnit::CALC) {
1407             UpdateBoxSize(GetWidth(), GetCalcHeight());
1408         } else {
1409             UpdateBoxSize(GetCalcWidth(), GetCalcHeight());
1410         }
1411         auto& paddingStyle = static_cast<CommonPaddingStyle&>(declaration_->GetStyle(StyleTag::COMMON_PADDING_STYLE));
1412         if (paddingStyle.IsValid()) {
1413             UpdateBoxPadding(paddingStyle.padding);
1414         }
1415         auto& marginStyle = static_cast<CommonMarginStyle&>(declaration_->GetStyle(StyleTag::COMMON_MARGIN_STYLE));
1416         if (marginStyle.IsValid()) {
1417             boxComponent_->SetMargin(marginStyle.margin);
1418         }
1419         auto& commonStyle = static_cast<CommonStyle&>(declaration_->GetStyle(StyleTag::COMMON_STYLE));
1420         if (commonStyle.IsValid()) {
1421             boxComponent_->SetLayoutInBoxFlag(commonStyle.layoutInBox);
1422         }
1423     }
1424 
1425     if (flexItemComponent_) {
1426         boxComponent_->SetDeliverMinToChild(false);
1427         auto& sizeStyle = static_cast<CommonSizeStyle&>(declaration_->GetStyle(StyleTag::COMMON_SIZE_STYLE));
1428         if (sizeStyle.IsValid()) {
1429             boxComponent_->SetAspectRatio(sizeStyle.aspectRatio);
1430             boxComponent_->SetMinWidth(sizeStyle.minWidth);
1431             boxComponent_->SetMinHeight(sizeStyle.minHeight);
1432             boxComponent_->SetMaxWidth(sizeStyle.maxWidth);
1433             boxComponent_->SetMaxHeight(sizeStyle.maxHeight);
1434             boxComponent_->SetBoxSizing(sizeStyle.boxSizing);
1435         }
1436     }
1437 
1438     if (declaration_->HasDecorationStyle()) {
1439         auto& borderStyle = declaration_->MaybeResetStyle<CommonBorderStyle>(StyleTag::COMMON_BORDER_STYLE);
1440         if (borderStyle.IsValid()) {
1441             UpdateBoxBorder(borderStyle.border);
1442         }
1443         auto& backDecoration = declaration_->GetBackDecoration();
1444         if (!declaration_->HasBackGroundColor() && boxComponent_->GetBackDecoration() &&
1445             boxComponent_->HasBackgroundColor()) {
1446             backDecoration->SetBackgroundColor(boxComponent_->GetBackDecoration()->GetBackgroundColor());
1447         }
1448         auto& backgroundStyle =
1449             static_cast<CommonBackgroundStyle&>(declaration_->GetStyle(StyleTag::COMMON_BACKGROUND_STYLE));
1450         if (backgroundStyle.IsValid() && backgroundStyle.gradient.IsValid()) {
1451             backDecoration->SetGradient(backgroundStyle.gradient);
1452         }
1453         if (backgroundStyle.IsValid() && backgroundStyle.gradientBorderImage.IsValid()) {
1454             backDecoration->SetGradientBorderImage(backgroundStyle.gradientBorderImage);
1455         }
1456 
1457         if (declaration_->HasShadowStyle()) {
1458             auto& shadowStyle = static_cast<CommonShadowStyle&>(declaration_->GetStyle(StyleTag::COMMON_SHADOW_STYLE));
1459             if (shadowStyle.IsValid()) {
1460                 backDecoration->ClearAllShadow();
1461                 backDecoration->AddShadow(shadowStyle.shadow);
1462             }
1463         }
1464         boxComponent_->SetBackDecoration(backDecoration);
1465     }
1466 
1467     if (declaration_->HasFrontDecorationStyle()) {
1468         boxComponent_->SetFrontDecoration(declaration_->GetFrontDecoration());
1469     }
1470     auto& overflowStyle = static_cast<CommonOverflowStyle&>(declaration_->GetStyle(StyleTag::COMMON_OVERFLOW_STYLE));
1471     if (overflowStyle.IsValid()) {
1472         boxComponent_->SetOverflow(overflowStyle.overflow);
1473     }
1474 
1475     boxComponent_->SetOnDomDragEnter(GetDragEnterId());
1476     boxComponent_->SetOnDomDragOver(GetDragOverId());
1477     boxComponent_->SetOnDomDragLeave(GetDragLeaveId());
1478     boxComponent_->SetOnDomDragDrop(GetDragDropId());
1479 
1480     auto& clipPathStyle = static_cast<CommonClipPathStyle&>(declaration_->GetStyle(StyleTag::COMMON_CLIP_PATH_STYLE));
1481     if (clipPathStyle.IsValid() && clipPathStyle.clipPath != nullptr) {
1482         boxComponent_->SetClipPath(clipPathStyle.clipPath);
1483     }
1484 
1485     auto& maskStyle = static_cast<CommonMaskStyle&>(declaration_->GetStyle(StyleTag::COMMON_MASK_STYLE));
1486     if (maskStyle.IsValid() && !maskStyle.maskImage.empty()) {
1487         BackgroundImagePosition position;
1488         if (!maskStyle.maskPosition.empty()) {
1489             ParseBackgroundImagePosition(maskStyle.maskPosition, position);
1490         }
1491 
1492         BackgroundImageSize size;
1493         if (!maskStyle.maskSize.empty()) {
1494             ParseBackgroundImageSize(maskStyle.maskSize, size);
1495         }
1496         boxComponent_->SetMask(maskStyle.maskImage, size, position);
1497     }
1498 }
1499 
PrepareScrollComponent()1500 void DOMNode::PrepareScrollComponent()
1501 {
1502     if (!declaration_) {
1503         return;
1504     }
1505 
1506     // div is specially handled.
1507     if (GetTag() == DOM_NODE_TAG_DIV) {
1508         return;
1509     }
1510     auto& overflowStyle = static_cast<CommonOverflowStyle&>(declaration_->GetStyle(StyleTag::COMMON_OVERFLOW_STYLE));
1511     if (!declaration_->HasOverflowStyle() || !overflowStyle.IsValid() || overflowStyle.overflow != Overflow::SCROLL) {
1512         return;
1513     }
1514     if (boxComponent_->GetWidthDimension().IsValid() && boxComponent_->GetHeightDimension().IsValid()) {
1515         if (!scrollComponent_) {
1516             scrollComponent_ = AceType::MakeRefPtr<ScrollComponent>(nullptr);
1517         }
1518         scrollComponent_->InitScrollBar(GetTheme<ScrollBarTheme>(), overflowStyle.scrollBarColor,
1519             overflowStyle.scrollBarWidth, overflowStyle.edgeEffect);
1520         declaration_->SetPositionController(scrollComponent_->GetScrollPositionController());
1521     }
1522 }
1523 
UpdateDisplayComponent()1524 void DOMNode::UpdateDisplayComponent()
1525 {
1526     if (!declaration_ || !declaration_->HasDisplayStyle()) {
1527         return;
1528     }
1529 
1530     if (!displayComponent_) {
1531         displayComponent_ = AceType::MakeRefPtr<DisplayComponent>(rootComponent_->GetChild());
1532     }
1533     auto& opacityStyle = static_cast<CommonOpacityStyle&>(declaration_->GetStyle(StyleTag::COMMON_OPACITY_STYLE));
1534     if (opacityStyle.IsValid()) {
1535         displayComponent_->SetOpacity(opacityStyle.opacity);
1536         displayComponent_->SetAppearingDuration(opacityStyle.appearingDuration);
1537     }
1538     auto context = pipelineContext_.Upgrade();
1539     if (!context) {
1540         return;
1541     }
1542     SetDisplayStyle();
1543     displayComponent_->SetVisible(visible_);
1544     bool show = (GetDisplay() != DisplayType::NONE);
1545     if (!focusableEventComponent_ && !show && !context->IsJsCard()) {
1546         focusableEventComponent_ = AceType::MakeRefPtr<FocusableComponent>();
1547         focusableEventComponent_->SetFocusable(true);
1548         declaration_->SetFocusableController(focusableEventComponent_->GetFocusableController());
1549     }
1550     if (focusableEventComponent_) {
1551         focusableEventComponent_->SetShow(show);
1552     }
1553     if (declaration_->HasShadowStyle()) {
1554         auto& shadowStyle = static_cast<CommonShadowStyle&>(declaration_->GetStyle(StyleTag::COMMON_SHADOW_STYLE));
1555         if (shadowStyle.IsValid()) {
1556             displayComponent_->SetShadow(shadowStyle.shadow);
1557         }
1558     }
1559 }
1560 
UpdateTweenComponent()1561 void DOMNode::UpdateTweenComponent()
1562 {
1563     if (transitionStyleUpdated_) {
1564         if (!propTransitionComponent_) {
1565             propTransitionComponent_ = AceType::MakeRefPtr<TransitionComponent>(TRANSITION_COMPONENT_PREFIX
1566                 + std::to_string(nodeId_), tag_);
1567         }
1568         propTransitionComponent_->SetTransitionOption(propTransitionOption_);
1569         transitionStyleUpdated_ = false;
1570     }
1571     if (!declaration_) {
1572         return;
1573     }
1574     if (declaration_->HasTransformStyle() && !transformComponent_) {
1575         transformComponent_ = AceType::MakeRefPtr<TransformComponent>();
1576     }
1577     auto& animationStyle = static_cast<CommonAnimationStyle&>(declaration_->GetStyle(StyleTag::COMMON_ANIMATION_STYLE));
1578     auto& shadowStyle = static_cast<CommonShadowStyle&>(declaration_->GetStyle(StyleTag::COMMON_SHADOW_STYLE));
1579     auto& clickEffectAttr =
1580         static_cast<CommonClickEffectAttribute&>(declaration_->GetAttribute(AttributeTag::COMMON_CLICK_EFFECT_ATTR));
1581     if (transformComponent_) {
1582         if (clickEffectAttr.IsValid()) {
1583             transformComponent_->SetClickSpringEffectType(clickEffectAttr.clickEffect);
1584         }
1585         if (animationStyle.IsValid()) {
1586             // Set transform style.
1587             if (declaration_->HasTransformOriginStyle()) {
1588                 transformComponent_->SetOriginDimension(
1589                     DimensionOffset(animationStyle.transformOriginX, animationStyle.transformOriginY));
1590             }
1591         }
1592 
1593         if (declaration_->HasShadowStyle() && shadowStyle.IsValid()) {
1594             transformComponent_->SetShadow(shadowStyle.shadow);
1595         }
1596 
1597         auto& cardTransitionStyle =
1598             static_cast<CommonCardTransitionStyle&>(declaration_->GetStyle(StyleTag::COMMON_CARD_TRANSITION_STYLE));
1599         if (cardTransitionStyle.IsValid()) {
1600             transformComponent_->SetTransitionEffect(cardTransitionStyle.transitionEffect);
1601         }
1602     }
1603 
1604     // Only check animation style here.
1605     if (animationStyle.IsValid() && animationStyle.tweenOption.IsValid() && animationStyleUpdated_) {
1606         if (!tweenComponent_) {
1607             tweenComponent_ = AceType::MakeRefPtr<TweenComponent>(COMPONENT_PREFIX + std::to_string(nodeId_), tag_);
1608         }
1609         tweenComponent_->SetTweenOption(animationStyle.tweenOption);
1610         tweenComponent_->UpdateAnimationName(animationName_);
1611         tweenComponent_->SetAnimationOperation(animationStyle.animationOperation);
1612         if (declaration_->HasShadowStyle() && shadowStyle.IsValid()) {
1613             tweenComponent_->SetShadow(shadowStyle.shadow);
1614         }
1615         UpdatePropAnimations(propAnimations_);
1616         animationStyleUpdated_ = false;
1617     }
1618     // for custom animation
1619     if (customAnimationStyleUpdated_) {
1620         UpdatePropAnimations(propAnimations_);
1621         customAnimationStyleUpdated_ = false;
1622     }
1623     if (!shareId_.empty()) {
1624         if (!sharedTransitionComponent_) {
1625             sharedTransitionComponent_ = AceType::MakeRefPtr<SharedTransitionComponent>(
1626                 "FrontendShared" + std::to_string(nodeId_), tag_, shareId_);
1627             auto& sharedTransitionStyle = static_cast<CommonShareTransitionStyle&>(
1628                 declaration_->GetStyle(StyleTag::COMMON_SHARE_TRANSITION_STYLE));
1629             if (sharedTransitionStyle.IsValid()) {
1630                 sharedTransitionComponent_->SetOption(sharedTransitionStyle.sharedTransitionOption);
1631                 sharedTransitionComponent_->SetEffect(sharedTransitionStyle.sharedEffect);
1632             }
1633         } else {
1634             sharedTransitionComponent_->SetShareId(shareId_);
1635         }
1636     }
1637 }
1638 
IsTabbarSubNode() const1639 bool DOMNode::IsTabbarSubNode() const
1640 {
1641     if (isRootNode_) {
1642         return GetTag() == DOM_NODE_TAG_TAB_BAR;
1643     }
1644     RefPtr<DOMNode> parent = parentNode_.Upgrade();
1645     if (!parent) {
1646         return false;
1647     }
1648 
1649     if (parent->GetTag() == DOM_NODE_TAG_TAB_BAR) {
1650         return true;
1651     }
1652 
1653     while (!parent->IsRootNode()) {
1654         if (parent->GetTag() == DOM_NODE_TAG_TAB_BAR) {
1655             return true;
1656         }
1657         parent = parent->GetParentNode();
1658         if (!parent) {
1659             return false;
1660         }
1661     }
1662     return false;
1663 }
1664 
PrepareTouchEvent(EventMarker & eventMarker,uint32_t type)1665 void DOMNode::PrepareTouchEvent(EventMarker& eventMarker, uint32_t type)
1666 {
1667     bool isTababrSubNode = IsTabbarSubNode();
1668     if (isTababrSubNode) {
1669         return;
1670     }
1671 
1672     auto weak = AceType::WeakClaim(this);
1673     if (eventMarker.IsEmpty()) {
1674         eventMarker = BackEndEventManager<void(const TouchEventInfo&)>::GetInstance().GetAvailableMarker();
1675         BackEndEventManager<void(const TouchEventInfo&)>::GetInstance().BindBackendEvent(
1676             eventMarker, [](const TouchEventInfo&) {});
1677     }
1678     eventMarker.SetPreFunction([weak, type]() {
1679         auto domNode = weak.Upgrade();
1680         if (!domNode) {
1681             LOGE("get dom node failed!");
1682             return;
1683         }
1684         domNode->OnActive(type != EventType::TOUCH_UP && type != EventType::TOUCH_CANCEL);
1685     });
1686 }
1687 
PrepareMouseHoverEvent()1688 void DOMNode::PrepareMouseHoverEvent()
1689 {
1690     if (!declaration_) {
1691         return;
1692     }
1693     auto& mouseEvent = declaration_->MaybeResetEvent<CommonMouseEvent>(EventTag::COMMON_MOUSE_EVENT);
1694     if (!mouseEvent.IsValid()) {
1695         return;
1696     }
1697     auto weak = AceType::WeakClaim(this);
1698     if (mouseEvent.mouseHover.eventMarker.IsEmpty()) {
1699         mouseEvent.mouseHover.eventMarker = BackEndEventManager<void()>::GetInstance().GetAvailableMarker();
1700         mouseEvent.mouseHover.isRefreshed = true;
1701         BackEndEventManager<void()>::GetInstance().BindBackendEvent(mouseEvent.mouseHover.eventMarker, []() {});
1702     }
1703     mouseEvent.mouseHover.eventMarker.SetPreFunction([weak]() {
1704         auto domNode = weak.Upgrade();
1705         if (!domNode) {
1706             LOGE("get dom node failed!");
1707             return;
1708         }
1709         domNode->OnHover(true);
1710     });
1711 
1712     if (mouseEvent.mouseHoverExit.eventMarker.IsEmpty()) {
1713         mouseEvent.mouseHoverExit.eventMarker = BackEndEventManager<void()>::GetInstance().GetAvailableMarker();
1714         mouseEvent.mouseHoverExit.isRefreshed = true;
1715         BackEndEventManager<void()>::GetInstance().BindBackendEvent(mouseEvent.mouseHoverExit.eventMarker, []() {});
1716     }
1717     mouseEvent.mouseHoverExit.eventMarker.SetPreFunction([weak]() {
1718         auto domNode = weak.Upgrade();
1719         if (!domNode) {
1720             LOGE("get dom node failed!");
1721             return;
1722         }
1723         domNode->OnHover(false);
1724     });
1725 }
1726 
PrepareFocusableEventId()1727 void DOMNode::PrepareFocusableEventId()
1728 {
1729     if (!declaration_) {
1730         return;
1731     }
1732     auto& focusEvent = declaration_->MaybeResetEvent<CommonFocusEvent>(EventTag::COMMON_FOCUS_EVENT);
1733     if (!focusEvent.IsValid()) {
1734         return;
1735     }
1736 
1737     auto weak = AceType::WeakClaim(this);
1738     if (focusEvent.focus.eventMarker.IsEmpty()) {
1739         focusEvent.focus.eventMarker = BackEndEventManager<void()>::GetInstance().GetAvailableMarker();
1740         focusEvent.focus.isRefreshed = true;
1741         BackEndEventManager<void()>::GetInstance().BindBackendEvent(focusEvent.focus.eventMarker, []() {});
1742     }
1743 
1744     focusEvent.focus.eventMarker.SetPreFunction([weak]() {
1745         auto domNode = weak.Upgrade();
1746         if (!domNode) {
1747             LOGE("get dom node failed!");
1748             return;
1749         }
1750         domNode->OnFocus(true);
1751     });
1752 
1753     if (focusEvent.blur.eventMarker.IsEmpty()) {
1754         focusEvent.blur.eventMarker = BackEndEventManager<void()>::GetInstance().GetAvailableMarker();
1755         focusEvent.blur.isRefreshed = true;
1756         BackEndEventManager<void()>::GetInstance().BindBackendEvent(focusEvent.blur.eventMarker, []() {});
1757     }
1758 
1759     focusEvent.blur.eventMarker.SetPreFunction([weak]() {
1760         auto domNode = weak.Upgrade();
1761         if (!domNode) {
1762             LOGE("get dom node failed!");
1763             return;
1764         }
1765         domNode->OnFocus(false);
1766     });
1767 }
1768 
UpdateTouchEventComponent()1769 void DOMNode::UpdateTouchEventComponent()
1770 {
1771     if (!declaration_) {
1772         return;
1773     }
1774 
1775     auto& swipeEvent = static_cast<CommonSwipeEvent&>(declaration_->GetEvent(EventTag::COMMON_SWIPE_EVENT));
1776     if (swipeEvent.IsValid() && !swipeEvent.swipe.eventMarker.IsEmpty()) {
1777         if (!touchEventComponent_) {
1778             touchEventComponent_ = AceType::MakeRefPtr<TouchListenerComponent>();
1779         }
1780         touchEventComponent_->SetOnSwipeId(swipeEvent.swipe.eventMarker);
1781     }
1782 
1783     auto& touchableAttr =
1784         static_cast<CommonTouchableAttribute&>(declaration_->GetAttribute(AttributeTag::COMMON_TOUCHABLE_ATTR));
1785     if (touchableAttr.IsValid() && !touchableAttr.touchable) {
1786         if (!touchEventComponent_) {
1787             touchEventComponent_ = AceType::MakeRefPtr<TouchListenerComponent>();
1788         }
1789         touchEventComponent_->SetTouchable(touchableAttr.touchable);
1790     }
1791 
1792     auto& rawEvent = static_cast<CommonRawEvent&>(declaration_->GetEvent(EventTag::COMMON_RAW_EVENT));
1793     if (!rawEvent.IsValid()) {
1794         return;
1795     }
1796     for (uint32_t eventAction = 0; eventAction < EventAction::SIZE; eventAction++) {
1797         for (uint32_t eventStage = 0; eventStage < EventStage::SIZE; eventStage++) {
1798             for (uint32_t touchEventType = 0; touchEventType < EventType::SIZE; touchEventType++) {
1799                 EventMarker& eventMarker = GetTouchId(eventAction, eventStage, touchEventType);
1800                 if (!eventMarker.IsEmpty() || HasActivePseudo()) {
1801                     if (!touchEventComponent_) {
1802                         touchEventComponent_ = AceType::MakeRefPtr<TouchListenerComponent>();
1803                     }
1804                     if (HasActivePseudo() && touchEventType != EventType::TOUCH_MOVE &&
1805                         eventAction == EventAction::ON && eventStage == EventStage::BUBBLE) {
1806                         PrepareTouchEvent(eventMarker, touchEventType);
1807                     }
1808                     touchEventComponent_->SetEvent(eventMarker, eventAction, eventStage, touchEventType);
1809                 }
1810             }
1811         }
1812     }
1813 }
1814 
UpdateMouseEventComponent()1815 void DOMNode::UpdateMouseEventComponent()
1816 {
1817     if (!declaration_) {
1818         return;
1819     }
1820     auto& mouseEvent = declaration_->MaybeResetEvent<CommonMouseEvent>(EventTag::COMMON_MOUSE_EVENT);
1821     if (!mouseEvent.IsValid()) {
1822         return;
1823     }
1824     if (!mouseEvent.mouse.eventMarker.IsEmpty()) {
1825         if (!mouseEventComponent_) {
1826             mouseEventComponent_ = AceType::MakeRefPtr<MouseListenerComponent>();
1827         }
1828         mouseEventComponent_->SetOnMouseId(mouseEvent.mouse.eventMarker);
1829     }
1830 
1831     PrepareMouseHoverEvent();
1832     if (!mouseEvent.mouseHover.eventMarker.IsEmpty()) {
1833         if (!mouseEventComponent_) {
1834             mouseEventComponent_ = AceType::MakeRefPtr<MouseListenerComponent>();
1835         }
1836         mouseEventComponent_->SetOnMouseHoverId(mouseEvent.mouseHover.eventMarker);
1837     }
1838     if (!mouseEvent.mouseHoverExit.eventMarker.IsEmpty()) {
1839         if (!mouseEventComponent_) {
1840             mouseEventComponent_ = AceType::MakeRefPtr<MouseListenerComponent>();
1841         }
1842         mouseEventComponent_->SetOnMouseHoverExitId(mouseEvent.mouseHoverExit.eventMarker);
1843     }
1844 }
1845 
UpdateGestureEventComponent()1846 void DOMNode::UpdateGestureEventComponent()
1847 {
1848     if (!declaration_) {
1849         return;
1850     }
1851 
1852     if (!GetClickId().IsEmpty() || !GetDoubleClickId().IsEmpty() || !GetLongPressId().IsEmpty() ||
1853         !GetPinchStartId().IsEmpty() || !GetPinchUpdateId().IsEmpty() || !GetPinchEndId().IsEmpty() ||
1854         !GetPinchCancelId().IsEmpty() || declaration_->HasIdAttr() || !GetDragStartId().IsEmpty() ||
1855         !GetDragId().IsEmpty() || !GetDragEndId().IsEmpty()) {
1856         if (!gestureEventComponent_) {
1857             gestureEventComponent_ = AceType::MakeRefPtr<GestureListenerComponent>();
1858         }
1859         gestureEventComponent_->SetOnClickId(GetClickId());
1860         gestureEventComponent_->SetOnDoubleClickId(GetDoubleClickId());
1861         gestureEventComponent_->SetOnLongPressId(GetLongPressId());
1862         gestureEventComponent_->SetOnPinchStartId(GetPinchStartId());
1863         gestureEventComponent_->SetOnPinchUpdateId(GetPinchUpdateId());
1864         gestureEventComponent_->SetOnPinchEndId(GetPinchEndId());
1865         gestureEventComponent_->SetOnPinchCancelId(GetPinchCancelId());
1866         gestureEventComponent_->SetOnFreeDragStartId(GetDragStartId());
1867         gestureEventComponent_->SetOnFreeDragUpdateId(GetDragId());
1868         gestureEventComponent_->SetOnFreeDragEndId(GetDragEndId());
1869     }
1870 }
1871 
UpdateFocusableEventComponents()1872 void DOMNode::UpdateFocusableEventComponents()
1873 {
1874     if (!declaration_ || (UNFOCUSABLED_NODE.find(tag_) != UNFOCUSABLED_NODE.end())) {
1875         return;
1876     }
1877 
1878     auto& focusableAttr =
1879         static_cast<CommonFocusableAttribute&>(declaration_->GetAttribute(AttributeTag::COMMON_FOCUSABLE_ATTR));
1880     auto& focusEvent = declaration_->MaybeResetEvent<CommonFocusEvent>(EventTag::COMMON_FOCUS_EVENT);
1881     auto& keyEvent = static_cast<CommonKeyEvent&>(declaration_->GetEvent(EventTag::COMMON_KEY_EVENT));
1882     bool focusable = focusableAttr.IsValid() && focusableAttr.focusable.second;
1883     bool supportFocus = focusEvent.IsValid() && !focusEvent.focus.eventMarker.IsEmpty();
1884     bool supportBlur = focusEvent.IsValid() && !focusEvent.blur.eventMarker.IsEmpty();
1885     bool supportKey = keyEvent.IsValid() && !keyEvent.key.eventMarker.IsEmpty();
1886 
1887     if (!focusable && GetClickId().IsEmpty() && !supportFocus && !supportBlur && !supportKey && !HasFocusPseudo()) {
1888         return;
1889     }
1890     if (!focusableEventComponent_) {
1891         focusableEventComponent_ = AceType::MakeRefPtr<FocusableComponent>();
1892         declaration_->SetFocusableController(focusableEventComponent_->GetFocusableController());
1893     }
1894     if (focusableAttr.IsValid() && focusableAttr.focusable.second) {
1895         focusableEventComponent_->SetFocusable(focusableAttr.focusable.first);
1896     } else {
1897         focusableEventComponent_->SetFocusable(true);
1898     }
1899 
1900     focusableEventComponent_->SetOnClickId(GetClickId());
1901 
1902     PrepareFocusableEventId();
1903 
1904     if (focusEvent.IsValid()) {
1905         focusableEventComponent_->SetOnBlurId(focusEvent.blur.eventMarker);
1906         focusableEventComponent_->SetOnFocusId(focusEvent.focus.eventMarker);
1907     }
1908     if (keyEvent.IsValid()) {
1909         focusableEventComponent_->SetOnKeyId(keyEvent.key.eventMarker);
1910     }
1911     if (g_focusableNode.empty()) {
1912         g_focusableNode = std::unordered_set<std::string>({
1913             DOM_NODE_TAG_BUTTON,
1914             DOM_NODE_TAG_DIV,
1915             DOM_NODE_TAG_FORM,
1916             DOM_NODE_TAG_LIST,
1917             DOM_NODE_TAG_LIST_ITEM,
1918             DOM_NODE_TAG_REFRESH,
1919             DOM_NODE_TAG_INPUT,
1920             DOM_NODE_TAG_OPTION,
1921             DOM_NODE_TAG_PROGRESS,
1922             DOM_NODE_TAG_POPUP,
1923             DOM_NODE_TAG_RATING,
1924             DOM_NODE_TAG_SELECT,
1925             DOM_NODE_TAG_SLIDER,
1926             DOM_NODE_TAG_STACK,
1927             DOM_NODE_TAG_STEPPER,
1928             DOM_NODE_TAG_STEPPER_ITEM,
1929             DOM_NODE_TAG_SWIPER,
1930             DOM_NODE_TAG_SWITCH,
1931             DOM_NODE_TAG_TABS,
1932             DOM_NODE_TAG_TAB_BAR,
1933             DOM_NODE_TAG_TAB_CONTENT,
1934             DOM_NODE_TAG_TEXTAREA,
1935             DOM_NODE_TAG_TOGGLE,
1936             DOM_NODE_TAG_SEARCH,
1937             DOM_NODE_TAG_VIDEO,
1938             DOM_NODE_TAG_CALENDAR,
1939             DOM_NODE_TAG_PICKER_DIALOG,
1940             DOM_NODE_TAG_PIECE,
1941         });
1942     }
1943     if (g_focusableNode.find(tag_) != g_focusableNode.end()) {
1944         focusableEventComponent_->SetFocusNode(false);
1945     } else {
1946         focusableEventComponent_->SetFocusNode(true);
1947     }
1948 }
1949 
UpdatePositionProps()1950 void DOMNode::UpdatePositionProps()
1951 {
1952     if (!declaration_ || !declaration_->HasPositionStyle() || GetPosition() == PositionType::FIXED) {
1953         return;
1954     }
1955 
1956     declaration_->SetHasPositionStyle(false);
1957     auto tweenComponent = AceType::DynamicCast<TweenComponent>(rootComponent_->GetChild());
1958     if (tweenComponent) {
1959         UpdateTweenPosition(tweenComponent);
1960         UpdatePositionAnimations(tweenComponent);
1961     } else {
1962         // Set position props to first RenderComponent of node
1963         auto compositeComponent = AceType::DynamicCast<RenderComponent>(rootComponent_->GetChild());
1964         if (!compositeComponent) {
1965             return;
1966         }
1967         compositeComponent->SetHasLeft(declaration_->HasLeft());
1968         compositeComponent->SetHasTop(declaration_->HasTop());
1969         compositeComponent->SetHasBottom(declaration_->HasBottom());
1970         compositeComponent->SetHasRight(declaration_->HasRight());
1971         auto& positionStyle =
1972             static_cast<CommonPositionStyle&>(declaration_->GetStyle(StyleTag::COMMON_POSITION_STYLE));
1973         if (positionStyle.IsValid()) {
1974             if (declaration_->HasLeft()) {
1975                 compositeComponent->SetLeft(positionStyle.left);
1976                 // reset value
1977                 declaration_->SetHasLeft(false);
1978             }
1979             if (declaration_->HasRight()) {
1980                 compositeComponent->SetRight(positionStyle.right);
1981                 declaration_->SetHasRight(false);
1982             }
1983             if (declaration_->HasTop()) {
1984                 compositeComponent->SetTop(positionStyle.top);
1985                 declaration_->SetHasTop(false);
1986             }
1987             if (declaration_->HasBottom()) {
1988                 compositeComponent->SetBottom(positionStyle.bottom);
1989                 declaration_->SetHasBottom(false);
1990             }
1991             compositeComponent->SetPositionType(positionStyle.position);
1992         }
1993         UpdatePositionAnimations(compositeComponent);
1994     }
1995 }
1996 
UpdateTweenPosition(const RefPtr<TweenComponent> tweenComponent)1997 void DOMNode::UpdateTweenPosition(const RefPtr<TweenComponent> tweenComponent)
1998 {
1999     if (!declaration_ || !tweenComponent) {
2000         return;
2001     }
2002     tweenComponent->SetHasLeft(declaration_->HasLeft());
2003     tweenComponent->SetHasTop(declaration_->HasTop());
2004     tweenComponent->SetHasBottom(declaration_->HasBottom());
2005     tweenComponent->SetHasRight(declaration_->HasRight());
2006 
2007     auto& positionStyle = static_cast<CommonPositionStyle&>(declaration_->GetStyle(StyleTag::COMMON_POSITION_STYLE));
2008     if (!positionStyle.IsValid()) {
2009         return;
2010     }
2011     if (declaration_->HasLeft()) {
2012         tweenComponent->SetLeft(positionStyle.left);
2013         // reset value
2014         declaration_->SetHasLeft(false);
2015     }
2016     if (declaration_->HasRight()) {
2017         tweenComponent->SetRight(positionStyle.right);
2018         declaration_->SetHasRight(false);
2019     }
2020     if (declaration_->HasTop()) {
2021         tweenComponent->SetTop(positionStyle.top);
2022         declaration_->SetHasTop(false);
2023     }
2024     if (declaration_->HasBottom()) {
2025         tweenComponent->SetBottom(positionStyle.bottom);
2026         declaration_->SetHasBottom(false);
2027     }
2028     tweenComponent->SetPositionType(positionStyle.position);
2029 }
2030 
UpdatePositionComponent()2031 void DOMNode::UpdatePositionComponent()
2032 {
2033     if (!declaration_ || !declaration_->HasPositionStyle() || GetPosition() != PositionType::FIXED) {
2034         return;
2035     }
2036     if (!positionComponent_) {
2037         positionComponent_ = AceType::MakeRefPtr<PositionedComponent>();
2038     }
2039     auto& positionStyle = static_cast<CommonPositionStyle&>(declaration_->GetStyle(StyleTag::COMMON_POSITION_STYLE));
2040     if (positionStyle.IsValid()) {
2041         positionComponent_->SetTop(positionStyle.top);
2042         positionComponent_->SetRight(positionStyle.right);
2043         positionComponent_->SetBottom(positionStyle.bottom);
2044         positionComponent_->SetLeft(positionStyle.left);
2045         positionComponent_->SetHasLeft(declaration_->HasLeft());
2046         positionComponent_->SetHasRight(declaration_->HasRight());
2047         positionComponent_->SetHasBottom(declaration_->HasBottom());
2048         positionComponent_->SetHasTop(declaration_->HasTop());
2049     }
2050     UpdatePositionAnimations(positionComponent_);
2051 }
2052 
CompositeSpecializedComponent(const std::vector<RefPtr<SingleChild>> & components)2053 RefPtr<Component> DOMNode::CompositeSpecializedComponent(const std::vector<RefPtr<SingleChild>>& components)
2054 {
2055     const auto& specializedComponent = GetSpecializedComponent();
2056     if (specializedComponent) {
2057         bool touchable = true;
2058         if (declaration_) {
2059             auto& touchableAttr =
2060                 static_cast<CommonTouchableAttribute&>(declaration_->GetAttribute(AttributeTag::COMMON_TOUCHABLE_ATTR));
2061             if (touchableAttr.IsValid()) {
2062                 touchable = touchableAttr.touchable;
2063             }
2064         }
2065         specializedComponent->SetTouchable(touchable);
2066     }
2067     if (components.empty()) {
2068         return specializedComponent;
2069     } else {
2070         const auto& parent = components.back();
2071         if (parent) {
2072             parent->SetChild(specializedComponent);
2073         }
2074         return AceType::DynamicCast<Component>(components.front());
2075     }
2076 }
2077 
2078 #ifndef WEARABLE_PRODUCT
UpdateMultimodalComponent()2079 void DOMNode::UpdateMultimodalComponent()
2080 {
2081     if (!declaration_ || GetClickId().IsEmpty()) {
2082         return;
2083     }
2084     auto& multimodalAttr =
2085         static_cast<CommonMultimodalAttribute&>(declaration_->GetAttribute(AttributeTag::COMMON_MULTIMODAL_ATTR));
2086     if (!multimodalAttr.IsValid() || multimodalAttr.IsUnavailable() || multimodalAttr.scene == SceneLabel::SWITCH) {
2087         return;
2088     }
2089     if (!multimodalComponent_) {
2090         multimodalComponent_ = AceType::MakeRefPtr<MultimodalComponent>(pageId_);
2091     }
2092     multimodalComponent_->SetMultimodalProperties(multimodalAttr);
2093     multimodalComponent_->SetOnClickId(GetClickId());
2094 }
2095 #endif
2096 
GetThemeConstants() const2097 RefPtr<ThemeConstants> DOMNode::GetThemeConstants() const
2098 {
2099     auto themeManager = GetThemeManager();
2100     if (!themeManager) {
2101         return nullptr;
2102     }
2103     return themeManager->GetThemeConstants();
2104 }
2105 
ParseColor(const std::string & value,uint32_t maskAlpha) const2106 Color DOMNode::ParseColor(const std::string& value, uint32_t maskAlpha) const
2107 {
2108     auto themeConstants = GetThemeConstants();
2109     if (!themeConstants) {
2110         LOGW("themeConstants is null, return Transparent color.");
2111         return Color::TRANSPARENT;
2112     }
2113     auto&& noRefFunc = [&value, maskAlpha = maskAlpha]() { return Color::FromString(value, maskAlpha); };
2114     auto&& idRefFunc = [constants = themeConstants](uint32_t refId) { return constants->GetColor(refId); };
2115     return ParseThemeReference<Color>(value, noRefFunc, idRefFunc, Color::TRANSPARENT);
2116 }
2117 
ParseDouble(const std::string & value) const2118 double DOMNode::ParseDouble(const std::string& value) const
2119 {
2120     auto themeConstants = GetThemeConstants();
2121     if (!themeConstants) {
2122         LOGW("themeConstants is null, return 0.");
2123         return 0.0;
2124     }
2125     auto&& noRefFunc = [&value]() { return StringUtils::StringToDouble(value); };
2126     auto&& idRefFunc = [constants = themeConstants](uint32_t refId) { return constants->GetDouble(refId); };
2127     return ParseThemeReference<double>(value, noRefFunc, idRefFunc, 0.0);
2128 }
2129 
ParseDimension(const std::string & value) const2130 CalcDimension DOMNode::ParseDimension(const std::string& value) const
2131 {
2132     auto themeConstants = GetThemeConstants();
2133     if (!themeConstants) {
2134         LOGW("themeConstants is null, return 0 dimension.");
2135         return Dimension();
2136     }
2137     auto&& noRefFunc = [&value]() { return StringUtils::StringToDimension(value); };
2138     auto&& idRefFunc = [constants = themeConstants](uint32_t refId) { return constants->GetDimension(refId); };
2139     if (value.find("calc") != std::string::npos) {
2140         return CalcDimension(value, DimensionUnit::CALC);
2141     } else {
2142         return ParseThemeReference<Dimension>(value, noRefFunc, idRefFunc, Dimension());
2143     }
2144 }
2145 
ParseLineHeight(const std::string & value) const2146 Dimension DOMNode::ParseLineHeight(const std::string& value) const
2147 {
2148     auto themeConstants = GetThemeConstants();
2149     if (!themeConstants) {
2150         LOGW("themeConstants is null, return 0 line height.");
2151         return Dimension();
2152     }
2153     const auto& parseResult = ThemeUtils::ParseThemeIdReference(value, GetThemeConstants());
2154     if (!parseResult.parseSuccess) {
2155         return StringUtils::StringToDimension(value);
2156     }
2157     auto&& noRefFunc = [&value]() { return StringUtils::StringToDouble(value); };
2158     auto&& idRefFunc = [constants = themeConstants](uint32_t refId) { return constants->GetDouble(refId); };
2159     auto lineHeightScale = ParseThemeReference<double>(value, noRefFunc, idRefFunc, 1.0);
2160     // If got 0.0 from ThemeConstants, use default 1.0
2161     lineHeightScale = NearZero(lineHeightScale) ? 1.0 : lineHeightScale;
2162     return Dimension(lineHeightScale, DimensionUnit::PERCENT);
2163 }
2164 
ParseFontFamilies(const std::string & value) const2165 std::vector<std::string> DOMNode::ParseFontFamilies(const std::string& value) const
2166 {
2167     std::vector<std::string> fontFamilies;
2168     std::stringstream stream(value);
2169     std::string fontFamily;
2170 
2171     auto themeConstants = GetThemeConstants();
2172     if (!themeConstants) {
2173         LOGW("themeConstants is null, return empty font families.");
2174         return fontFamilies;
2175     }
2176     auto&& idRefFunc = [constants = themeConstants](uint32_t refId) { return constants->GetString(refId); };
2177 
2178     while (getline(stream, fontFamily, ',')) {
2179         auto&& noRefFunc = [&fontFamily]() { return fontFamily; };
2180         fontFamilies.emplace_back(ParseThemeReference<std::string>(fontFamily, noRefFunc, idRefFunc, fontFamily));
2181     }
2182     return fontFamilies;
2183 }
2184 
ParsePreferFontSizes(const std::string & value) const2185 std::vector<Dimension> DOMNode::ParsePreferFontSizes(const std::string& value) const
2186 {
2187     std::vector<Dimension> prefers;
2188     std::stringstream stream(value);
2189     std::string fontSize;
2190     while (getline(stream, fontSize, ',')) {
2191         prefers.emplace_back(ParseDimension(fontSize));
2192     }
2193     std::sort(prefers.begin(), prefers.end(),
2194         [](const Dimension& left, const Dimension& right) { return left.Value() > right.Value(); });
2195     return prefers;
2196 }
2197 
ParseImageSrc(const std::string & imgSrc) const2198 std::string DOMNode::ParseImageSrc(const std::string& imgSrc) const
2199 {
2200     return ThemeUtils::ProcessImageSource(imgSrc, GetThemeConstants());
2201 }
2202 
AdjustParamInLiteMode()2203 void DOMNode::AdjustParamInLiteMode()
2204 {
2205     if (!declaration_) {
2206         return;
2207     }
2208 
2209     declaration_->SetUseLiteStyle(true);
2210     // Change default value
2211     if (boxComponent_) {
2212         boxComponent_->SetUseLiteStyle(true);
2213         boxComponent_->SetAlignment(Alignment::TOP_CENTER);
2214     }
2215     auto& flexStyle = declaration_->MaybeResetStyle<CommonFlexStyle>(StyleTag::COMMON_FLEX_STYLE);
2216     if (flexStyle.IsValid()) {
2217         flexStyle.flexShrink = 0.0;
2218     }
2219     AdjustSpecialParamInLiteMode();
2220 }
2221 
CreateDeclaration(const std::string & tag)2222 void DOMNode::CreateDeclaration(const std::string& tag)
2223 {
2224     declaration_ = DeclarationCreatorManager::GetInstance().CreateDeclaration(tag);
2225     if (!declaration_) {
2226         LOGE("node %{public}s doesn't support", tag.c_str());
2227         return;
2228     }
2229     declaration_->SetCachePseudoClassStyle(
2230         [weak = WeakClaim(this)](const std::pair<std::string, std::string>& pseudoClassStyle) {
2231             auto node = weak.Upgrade();
2232             if (node) {
2233                 node->CachePseudoClassStyle(pseudoClassStyle);
2234             }
2235         });
2236     declaration_->SetOnSetStyleFinished([weak = WeakClaim(this)]() {
2237         auto node = weak.Upgrade();
2238         if (node) {
2239             node->OnSetStyleFinished();
2240         }
2241     });
2242     declaration_->SetOnSetAttribute([weakComponent = WeakPtr<ComposedComponent>(rootComponent_)]() {
2243         auto rootComponent = weakComponent.Upgrade();
2244         if (rootComponent) {
2245             rootComponent->SetUpdateType(UpdateType::ALL);
2246         }
2247     });
2248 }
2249 
2250 } // namespace OHOS::Ace::Framework
2251