1 /*
2  * Copyright (C) 2008, 2009, 2010 Apple Inc. All rights reserved.
3  * Copyright (C) 2008 David Smith <catfish.man@gmail.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  *
20  */
21 
22 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_ELEMENT_RARE_DATA_H_
23 #define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_ELEMENT_RARE_DATA_H_
24 
25 #include <memory>
26 #include "third_party/blink/renderer/core/animation/element_animations.h"
27 #include "third_party/blink/renderer/core/aom/accessible_node.h"
28 #include "third_party/blink/renderer/core/css/cssom/inline_style_property_map.h"
29 #include "third_party/blink/renderer/core/css/inline_css_style_declaration.h"
30 #include "third_party/blink/renderer/core/display_lock/display_lock_context.h"
31 #include "third_party/blink/renderer/core/dom/attr.h"
32 #include "third_party/blink/renderer/core/dom/dataset_dom_string_map.h"
33 #include "third_party/blink/renderer/core/dom/dom_token_list.h"
34 #include "third_party/blink/renderer/core/dom/named_node_map.h"
35 #include "third_party/blink/renderer/core/dom/names_map.h"
36 #include "third_party/blink/renderer/core/dom/node_rare_data.h"
37 #include "third_party/blink/renderer/core/dom/pseudo_element.h"
38 #include "third_party/blink/renderer/core/dom/pseudo_element_data.h"
39 #include "third_party/blink/renderer/core/dom/shadow_root.h"
40 #include "third_party/blink/renderer/core/dom/space_split_string.h"
41 #include "third_party/blink/renderer/core/html/custom/custom_element_definition.h"
42 #include "third_party/blink/renderer/core/html/custom/v0_custom_element_definition.h"
43 #include "third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.h"
44 #include "third_party/blink/renderer/platform/heap/handle.h"
45 #include "third_party/blink/renderer/platform/wtf/hash_set.h"
46 
47 namespace blink {
48 
49 class Element;
50 class HTMLElement;
51 class ResizeObservation;
52 class ResizeObserver;
53 
54 class ElementRareData : public NodeRareData {
55  public:
56   explicit ElementRareData(NodeRenderingData*);
57   ~ElementRareData();
58 
59   void SetPseudoElement(PseudoId, PseudoElement*);
60   PseudoElement* GetPseudoElement(PseudoId) const;
61   PseudoElementData::PseudoElementVector GetPseudoElements() const;
62 
SetTabIndexExplicitly()63   void SetTabIndexExplicitly() {
64     SetElementFlag(ElementFlags::kTabIndexWasSetExplicitly, true);
65   }
66 
ClearTabIndexExplicitly()67   void ClearTabIndexExplicitly() {
68     ClearElementFlag(ElementFlags::kTabIndexWasSetExplicitly);
69   }
70 
71   CSSStyleDeclaration& EnsureInlineCSSStyleDeclaration(Element* owner_element);
72   InlineStylePropertyMap& EnsureInlineStylePropertyMap(Element* owner_element);
73 
GetInlineStylePropertyMap()74   InlineStylePropertyMap* GetInlineStylePropertyMap() {
75     return cssom_map_wrapper_.Get();
76   }
77 
GetShadowRoot()78   ShadowRoot* GetShadowRoot() const { return shadow_root_.Get(); }
SetShadowRoot(ShadowRoot & shadow_root)79   void SetShadowRoot(ShadowRoot& shadow_root) {
80     DCHECK(!shadow_root_);
81     shadow_root_ = &shadow_root;
82   }
83 
AttributeMap()84   NamedNodeMap* AttributeMap() const { return attribute_map_.Get(); }
SetAttributeMap(NamedNodeMap * attribute_map)85   void SetAttributeMap(NamedNodeMap* attribute_map) {
86     attribute_map_ = attribute_map;
87   }
88 
GetClassList()89   DOMTokenList* GetClassList() const { return class_list_.Get(); }
SetClassList(DOMTokenList * class_list)90   void SetClassList(DOMTokenList* class_list) {
91     class_list_ = class_list;
92   }
93 
SetPart(DOMTokenList * part)94   void SetPart(DOMTokenList* part) {
95     part_ = part;
96   }
GetPart()97   DOMTokenList* GetPart() const { return part_.Get(); }
98 
SetPartNamesMap(const AtomicString part_names)99   void SetPartNamesMap(const AtomicString part_names) {
100     if (!part_names_map_) {
101       part_names_map_.reset(new NamesMap());
102     }
103     part_names_map_->Set(part_names);
104   }
PartNamesMap()105   const NamesMap* PartNamesMap() const { return part_names_map_.get(); }
106 
Dataset()107   DatasetDOMStringMap* Dataset() const { return dataset_.Get(); }
SetDataset(DatasetDOMStringMap * dataset)108   void SetDataset(DatasetDOMStringMap* dataset) {
109     dataset_ = dataset;
110   }
111 
SavedLayerScrollOffset()112   ScrollOffset SavedLayerScrollOffset() const {
113     return saved_layer_scroll_offset_;
114   }
SetSavedLayerScrollOffset(ScrollOffset offset)115   void SetSavedLayerScrollOffset(ScrollOffset offset) {
116     saved_layer_scroll_offset_ = offset;
117   }
118 
GetElementAnimations()119   ElementAnimations* GetElementAnimations() {
120     return element_animations_.Get();
121   }
SetElementAnimations(ElementAnimations * element_animations)122   void SetElementAnimations(ElementAnimations* element_animations) {
123     element_animations_ = element_animations;
124   }
125 
126   bool HasPseudoElements() const;
127   void ClearPseudoElements();
128 
V0SetCustomElementDefinition(V0CustomElementDefinition * definition)129   void V0SetCustomElementDefinition(V0CustomElementDefinition* definition) {
130     v0_custom_element_definition_ = definition;
131   }
GetV0CustomElementDefinition()132   V0CustomElementDefinition* GetV0CustomElementDefinition() const {
133     return v0_custom_element_definition_.Get();
134   }
135 
SetCustomElementDefinition(CustomElementDefinition * definition)136   void SetCustomElementDefinition(CustomElementDefinition* definition) {
137     custom_element_definition_ = definition;
138   }
GetCustomElementDefinition()139   CustomElementDefinition* GetCustomElementDefinition() const {
140     return custom_element_definition_.Get();
141   }
SetIsValue(const AtomicString & is_value)142   void SetIsValue(const AtomicString& is_value) { is_value_ = is_value; }
IsValue()143   const AtomicString& IsValue() const { return is_value_; }
SetDidAttachInternals()144   void SetDidAttachInternals() { did_attach_internals_ = true; }
DidAttachInternals()145   bool DidAttachInternals() const { return did_attach_internals_; }
146   ElementInternals& EnsureElementInternals(HTMLElement& target);
147 
SetStyleShouldForceLegacyLayout(bool force)148   void SetStyleShouldForceLegacyLayout(bool force) {
149     style_should_force_legacy_layout_ = force;
150   }
StyleShouldForceLegacyLayout()151   bool StyleShouldForceLegacyLayout() const {
152     return style_should_force_legacy_layout_;
153   }
SetShouldForceLegacyLayoutForChild(bool force)154   void SetShouldForceLegacyLayoutForChild(bool force) {
155     should_force_legacy_layout_for_child_ = force;
156   }
ShouldForceLegacyLayoutForChild()157   bool ShouldForceLegacyLayoutForChild() const {
158     return should_force_legacy_layout_for_child_;
159   }
160 
GetAccessibleNode()161   AccessibleNode* GetAccessibleNode() const { return accessible_node_.Get(); }
EnsureAccessibleNode(Element * owner_element)162   AccessibleNode* EnsureAccessibleNode(Element* owner_element) {
163     if (!accessible_node_) {
164       accessible_node_ = MakeGarbageCollected<AccessibleNode>(owner_element);
165     }
166     return accessible_node_;
167   }
168 
169   AttrNodeList& EnsureAttrNodeList();
GetAttrNodeList()170   AttrNodeList* GetAttrNodeList() { return attr_node_list_.Get(); }
RemoveAttrNodeList()171   void RemoveAttrNodeList() { attr_node_list_.Clear(); }
AddAttr(Attr * attr)172   void AddAttr(Attr* attr) {
173     EnsureAttrNodeList().push_back(attr);
174   }
175 
IntersectionObserverData()176   ElementIntersectionObserverData* IntersectionObserverData() const {
177     return intersection_observer_data_.Get();
178   }
EnsureIntersectionObserverData()179   ElementIntersectionObserverData& EnsureIntersectionObserverData() {
180     if (!intersection_observer_data_) {
181       intersection_observer_data_ =
182           MakeGarbageCollected<ElementIntersectionObserverData>();
183     }
184     return *intersection_observer_data_;
185   }
186 
187   using ResizeObserverDataMap =
188       HeapHashMap<Member<ResizeObserver>, Member<ResizeObservation>>;
189 
ResizeObserverData()190   ResizeObserverDataMap* ResizeObserverData() const {
191     return resize_observer_data_;
192   }
193   ResizeObserverDataMap& EnsureResizeObserverData();
194 
EnsureDisplayLockContext(Element * element)195   DisplayLockContext* EnsureDisplayLockContext(Element* element) {
196     if (!display_lock_context_) {
197       display_lock_context_ = MakeGarbageCollected<DisplayLockContext>(element);
198     }
199     return display_lock_context_.Get();
200   }
GetDisplayLockContext()201   DisplayLockContext* GetDisplayLockContext() const {
202     return display_lock_context_;
203   }
204 
GetNonce()205   const AtomicString& GetNonce() const { return nonce_; }
SetNonce(const AtomicString & nonce)206   void SetNonce(const AtomicString& nonce) { nonce_ = nonce; }
207 
208   void TraceAfterDispatch(blink::Visitor*) const;
209 
210  private:
211   ScrollOffset saved_layer_scroll_offset_;
212   AtomicString nonce_;
213 
214   Member<DatasetDOMStringMap> dataset_;
215   Member<ShadowRoot> shadow_root_;
216   Member<DOMTokenList> class_list_;
217   Member<DOMTokenList> part_;
218   std::unique_ptr<NamesMap> part_names_map_;
219   Member<NamedNodeMap> attribute_map_;
220   Member<AttrNodeList> attr_node_list_;
221   Member<InlineCSSStyleDeclaration> cssom_wrapper_;
222   Member<InlineStylePropertyMap> cssom_map_wrapper_;
223 
224   Member<ElementAnimations> element_animations_;
225   Member<ElementIntersectionObserverData> intersection_observer_data_;
226   Member<ResizeObserverDataMap> resize_observer_data_;
227 
228   // TODO(davaajav):remove this field when v0 custom elements are deprecated
229   Member<V0CustomElementDefinition> v0_custom_element_definition_;
230   Member<CustomElementDefinition> custom_element_definition_;
231   AtomicString is_value_;
232   Member<ElementInternals> element_internals_;
233 
234   Member<PseudoElementData> pseudo_element_data_;
235 
236   Member<AccessibleNode> accessible_node_;
237 
238   Member<DisplayLockContext> display_lock_context_;
239   bool did_attach_internals_ = false;
240   bool should_force_legacy_layout_for_child_ = false;
241   bool style_should_force_legacy_layout_ = false;
242 };
243 
DefaultMinimumSizeForResizing()244 inline LayoutSize DefaultMinimumSizeForResizing() {
245   return LayoutSize(LayoutUnit::Max(), LayoutUnit::Max());
246 }
247 
HasPseudoElements()248 inline bool ElementRareData::HasPseudoElements() const {
249   return (pseudo_element_data_ && pseudo_element_data_->HasPseudoElements());
250 }
251 
ClearPseudoElements()252 inline void ElementRareData::ClearPseudoElements() {
253   if (pseudo_element_data_) {
254     pseudo_element_data_->ClearPseudoElements();
255     pseudo_element_data_.Clear();
256   }
257 }
258 
SetPseudoElement(PseudoId pseudo_id,PseudoElement * element)259 inline void ElementRareData::SetPseudoElement(PseudoId pseudo_id,
260                                               PseudoElement* element) {
261   if (!pseudo_element_data_) {
262     if (!element)
263       return;
264     pseudo_element_data_ = MakeGarbageCollected<PseudoElementData>();
265   }
266   pseudo_element_data_->SetPseudoElement(pseudo_id, element);
267 }
268 
GetPseudoElement(PseudoId pseudo_id)269 inline PseudoElement* ElementRareData::GetPseudoElement(
270     PseudoId pseudo_id) const {
271   if (!pseudo_element_data_)
272     return nullptr;
273   return pseudo_element_data_->GetPseudoElement(pseudo_id);
274 }
275 
276 inline PseudoElementData::PseudoElementVector
GetPseudoElements()277 ElementRareData::GetPseudoElements() const {
278   if (!pseudo_element_data_)
279     return {};
280   return pseudo_element_data_->GetPseudoElements();
281 }
282 
283 }  // namespace blink
284 
285 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_ELEMENT_RARE_DATA_H_
286