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