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 #ifndef FOUNDATION_ACE_FRAMEWORKS_BRIDGE_COMMON_DOM_DOM_DOCUMENT_H
17 #define FOUNDATION_ACE_FRAMEWORKS_BRIDGE_COMMON_DOM_DOM_DOCUMENT_H
18 
19 #include <string>
20 #include <unordered_map>
21 
22 #include "base/memory/ace_type.h"
23 #include "base/utils/macros.h"
24 #include "core/components/stack/stack_component.h"
25 #include "frameworks/bridge/common/dom/dom_node.h"
26 #include "frameworks/bridge/common/dom/dom_proxy.h"
27 
28 namespace OHOS::Ace::Framework {
29 
30 // DOMDocument is owned by JsAcePage, to maintain the component structures.
31 // As the [Component] can't completely one-one correspondence with Ace [Component],
32 // so the basic idea is:
33 // Each AcePage corresponding to only one DOMDocument, each DomDocument contains some [Node]s,
34 // each [Node] maybe corresponding only one Ace [Component], like Text/Image/..., or a
35 // [ComposedComponent] with some other components.
36 class ACE_FORCE_EXPORT DOMDocument final : public virtual AceType {
37     DECLARE_ACE_TYPE(DOMDocument, AceType);
38 
39 public:
DOMDocument(int32_t pageId)40     explicit DOMDocument(int32_t pageId) : rootNodeId_(DOM_ROOT_NODE_ID_BASE + pageId) {}
41     ~DOMDocument() override;
42 
43     RefPtr<DOMNode> CreateNodeWithId(const std::string& tag, NodeId nodeId, int32_t itemIndex = -1);
44 
45     RefPtr<DOMProxy> CreateProxyNodeWithId(const std::string& tag, NodeId nodeId);
46 
47     RefPtr<DOMNode> GetDOMNodeById(NodeId nodeId) const;
48 
49     void RemoveNodes(const RefPtr<DOMNode>& node, bool scheduleUpdate);
50 
51     void SetUpRootComponent(const RefPtr<DOMNode>& node);
52 
GetComponentById(NodeId nodeId)53     RefPtr<Component> GetComponentById(NodeId nodeId) const
54     {
55         auto domNode = GetDOMNodeById(nodeId);
56         return (domNode == nullptr) ? nullptr : domNode->GetRootComponent();
57     }
58 
GetComponentsCount()59     size_t GetComponentsCount() const
60     {
61         return domNodes_.size();
62     }
63 
GetRootStackComponent()64     const RefPtr<StackComponent>& GetRootStackComponent() const
65     {
66         return rootStackComponent_;
67     }
68 
GetRootComposedStack()69     const RefPtr<ComposedComponent>& GetRootComposedStack() const
70     {
71         return rootComposedStack_;
72     }
73 
74     void AddNodeWithId(const std::string& key, const RefPtr<DOMNode>& domNode);
75     void AddNodeWithTarget(const std::string& key, const RefPtr<DOMNode>& domNode);
76     void HandleComponentPostBinding();
77     void HandlePageLoadFinish();
78 
GetRootNodeId()79     int32_t GetRootNodeId() const
80     {
81         return rootNodeId_;
82     }
83 
SetPipelineContext(const WeakPtr<PipelineContext> & pipelineContext)84     void SetPipelineContext(const WeakPtr<PipelineContext>& pipelineContext)
85     {
86         pipelineContext_ = pipelineContext;
87     }
88 
GetProxyRelatedNodes()89     const std::unordered_set<NodeId>& GetProxyRelatedNodes() const
90     {
91         return proxyRelatedNode_;
92     }
93 
94     static RefPtr<PixelMap> pixelMap_;
95     static int32_t pixelMapOffsetX_;
96     static int32_t pixelMapOffsetY_;
97 
98 private:
99     NodeId rootNodeId_ = DOM_ROOT_NODE_ID_BASE;
100 
101     RefPtr<StackComponent> rootStackComponent_;
102     RefPtr<ComposedComponent> rootComposedStack_;
103     std::unordered_map<NodeId, RefPtr<DOMNode>> domNodes_;
104     WeakPtr<PipelineContext> pipelineContext_;
105     std::unordered_set<NodeId>  proxyRelatedNode_;
106 
107     // Below id and target vector are for special cases: popup and label node in Js.
108     // Both of them must be assigned a 'target' attribute, which is corresponding to a DOMNode
109     // that must be assigned 'id' attribute.
110     // And the popup/label component in backend must be as the parent of the component that is
111     // included in 'id' DOMNode.
112     // However, the sequence(position in JS bundle) of the 'target' and 'id' DOMNode is uncertain,
113     // and even not 1 to 1, we need save them and binding the relation after whole page loading done.
114     std::vector<std::pair<std::string, WeakPtr<DOMNode>>> nodeWithIdVec_;
115     std::vector<std::pair<std::string, WeakPtr<DOMNode>>> nodeWithTargetVec_;
116 };
117 
118 } // namespace OHOS::Ace::Framework
119 
120 #endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_COMMON_DOM_DOM_DOCUMENT_H
121