| /* |
| * Copyright (C) 2008, 2010 Apple Inc. All rights reserved. |
| * Copyright (C) 2008 David Smith <catfish.man@gmail.com> |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Library General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public License |
| * along with this library; see the file COPYING.LIB. If not, write to |
| * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| * Boston, MA 02110-1301, USA. |
| * |
| */ |
| |
| #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_NODE_RARE_DATA_H_ |
| #define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_NODE_RARE_DATA_H_ |
| |
| #include "base/macros.h" |
| #include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h" |
| #include "third_party/blink/renderer/platform/heap/handle.h" |
| #include "third_party/blink/renderer/platform/wtf/hash_set.h" |
| |
| namespace blink { |
| |
| class ComputedStyle; |
| enum class DynamicRestyleFlags; |
| enum class ElementFlags; |
| class LayoutObject; |
| class MutationObserverRegistration; |
| class NodeListsNodeData; |
| |
| class NodeMutationObserverData final |
| : public GarbageCollected<NodeMutationObserverData> { |
| public: |
| static NodeMutationObserverData* Create() { |
| return new NodeMutationObserverData; |
| } |
| |
| const HeapVector<TraceWrapperMember<MutationObserverRegistration>>& |
| Registry() { |
| return registry_; |
| } |
| |
| const HeapHashSet<TraceWrapperMember<MutationObserverRegistration>>& |
| TransientRegistry() { |
| return transient_registry_; |
| } |
| |
| void AddTransientRegistration(MutationObserverRegistration* registration); |
| void RemoveTransientRegistration(MutationObserverRegistration* registration); |
| void AddRegistration(MutationObserverRegistration* registration); |
| void RemoveRegistration(MutationObserverRegistration* registration); |
| |
| void Trace(blink::Visitor* visitor); |
| |
| private: |
| NodeMutationObserverData() = default; |
| |
| HeapVector<TraceWrapperMember<MutationObserverRegistration>> registry_; |
| HeapHashSet<TraceWrapperMember<MutationObserverRegistration>> |
| transient_registry_; |
| DISALLOW_COPY_AND_ASSIGN(NodeMutationObserverData); |
| }; |
| |
| class NodeRenderingData { |
| public: |
| explicit NodeRenderingData(LayoutObject*, |
| scoped_refptr<ComputedStyle> non_attached_style); |
| ~NodeRenderingData(); |
| |
| LayoutObject* GetLayoutObject() const { return layout_object_; } |
| void SetLayoutObject(LayoutObject* layout_object) { |
| DCHECK_NE(&SharedEmptyData(), this); |
| layout_object_ = layout_object; |
| } |
| |
| ComputedStyle* GetNonAttachedStyle() const { |
| return non_attached_style_.get(); |
| } |
| void SetNonAttachedStyle(scoped_refptr<ComputedStyle> non_attached_style); |
| |
| static NodeRenderingData& SharedEmptyData(); |
| bool IsSharedEmptyData() { return this == &SharedEmptyData(); } |
| |
| private: |
| LayoutObject* layout_object_; |
| scoped_refptr<ComputedStyle> non_attached_style_; |
| DISALLOW_COPY_AND_ASSIGN(NodeRenderingData); |
| }; |
| |
| class NodeRareDataBase { |
| public: |
| NodeRenderingData* GetNodeRenderingData() const { return node_layout_data_; } |
| void SetNodeRenderingData(NodeRenderingData* node_layout_data) { |
| DCHECK(node_layout_data); |
| node_layout_data_ = node_layout_data; |
| } |
| |
| protected: |
| explicit NodeRareDataBase(NodeRenderingData* node_layout_data) |
| : node_layout_data_(node_layout_data) {} |
| ~NodeRareDataBase() { |
| if (node_layout_data_ && !node_layout_data_->IsSharedEmptyData()) |
| delete node_layout_data_; |
| } |
| |
| protected: |
| NodeRenderingData* node_layout_data_; |
| }; |
| |
| class NodeRareData : public GarbageCollectedFinalized<NodeRareData>, |
| public NodeRareDataBase { |
| public: |
| static NodeRareData* Create(NodeRenderingData* node_layout_data) { |
| return new NodeRareData(node_layout_data); |
| } |
| |
| void ClearNodeLists() { node_lists_.Clear(); } |
| NodeListsNodeData* NodeLists() const { return node_lists_.Get(); } |
| // ensureNodeLists() and a following NodeListsNodeData functions must be |
| // wrapped with a ThreadState::GCForbiddenScope in order to avoid an |
| // initialized m_nodeLists is cleared by NodeRareData::traceAfterDispatch(). |
| NodeListsNodeData& EnsureNodeLists() { |
| DCHECK(ThreadState::Current()->IsGCForbidden()); |
| if (!node_lists_) |
| return CreateNodeLists(); |
| return *node_lists_; |
| } |
| |
| NodeMutationObserverData* MutationObserverData() { |
| return mutation_observer_data_.Get(); |
| } |
| NodeMutationObserverData& EnsureMutationObserverData() { |
| if (!mutation_observer_data_) { |
| mutation_observer_data_ = NodeMutationObserverData::Create(); |
| } |
| return *mutation_observer_data_; |
| } |
| |
| unsigned ConnectedSubframeCount() const { return connected_frame_count_; } |
| void IncrementConnectedSubframeCount(); |
| void DecrementConnectedSubframeCount() { |
| DCHECK(connected_frame_count_); |
| --connected_frame_count_; |
| } |
| |
| bool HasElementFlag(ElementFlags mask) const { |
| return element_flags_ & static_cast<unsigned>(mask); |
| } |
| void SetElementFlag(ElementFlags mask, bool value) { |
| element_flags_ = (element_flags_ & ~static_cast<unsigned>(mask)) | |
| (-(int32_t)value & static_cast<unsigned>(mask)); |
| } |
| void ClearElementFlag(ElementFlags mask) { |
| element_flags_ &= ~static_cast<unsigned>(mask); |
| } |
| |
| bool HasRestyleFlag(DynamicRestyleFlags mask) const { |
| return restyle_flags_ & static_cast<unsigned>(mask); |
| } |
| void SetRestyleFlag(DynamicRestyleFlags mask) { |
| restyle_flags_ |= static_cast<unsigned>(mask); |
| CHECK(restyle_flags_); |
| } |
| bool HasRestyleFlags() const { return restyle_flags_; } |
| void ClearRestyleFlags() { restyle_flags_ = 0; } |
| |
| enum { |
| kConnectedFrameCountBits = 10, // Must fit Page::maxNumberOfFrames. |
| kNumberOfElementFlags = 6, |
| kNumberOfDynamicRestyleFlags = 14 |
| }; |
| |
| void Trace(blink::Visitor*); |
| void TraceAfterDispatch(blink::Visitor*); |
| void FinalizeGarbageCollectedObject(); |
| |
| protected: |
| explicit NodeRareData(NodeRenderingData* node_layout_data) |
| : NodeRareDataBase(node_layout_data), |
| connected_frame_count_(0), |
| element_flags_(0), |
| restyle_flags_(0), |
| is_element_rare_data_(false) { |
| CHECK_NE(node_layout_data, nullptr); |
| } |
| |
| private: |
| NodeListsNodeData& CreateNodeLists(); |
| |
| TraceWrapperMember<NodeListsNodeData> node_lists_; |
| TraceWrapperMember<NodeMutationObserverData> mutation_observer_data_; |
| |
| unsigned connected_frame_count_ : kConnectedFrameCountBits; |
| unsigned element_flags_ : kNumberOfElementFlags; |
| unsigned restyle_flags_ : kNumberOfDynamicRestyleFlags; |
| |
| protected: |
| unsigned is_element_rare_data_ : 1; |
| DISALLOW_COPY_AND_ASSIGN(NodeRareData); |
| }; |
| |
| } // namespace blink |
| |
| #endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_NODE_RARE_DATA_H_ |