1 /* 2 * Copyright (C) 2008, 2009, 2010 Apple Inc. All rights reserved. 3 * Copyright (C) 2008 David Smith <catfish.man (at) 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 ElementRareData_h 23 #define ElementRareData_h 24 25 #include "core/animation/ActiveAnimations.h" 26 #include "core/dom/Attr.h" 27 #include "core/dom/DatasetDOMStringMap.h" 28 #include "core/dom/NamedNodeMap.h" 29 #include "core/dom/NodeRareData.h" 30 #include "core/dom/PseudoElement.h" 31 #include "core/dom/custom/CustomElementDefinition.h" 32 #include "core/dom/shadow/ElementShadow.h" 33 #include "core/html/ClassList.h" 34 #include "core/html/ime/InputMethodContext.h" 35 #include "core/rendering/style/StyleInheritedData.h" 36 #include "platform/heap/Handle.h" 37 #include "wtf/OwnPtr.h" 38 39 namespace WebCore { 40 41 class HTMLElement; 42 43 class ElementRareData : public NodeRareData { 44 public: 45 static ElementRareData* create(RenderObject* renderer) 46 { 47 return new ElementRareData(renderer); 48 } 49 50 ~ElementRareData(); 51 52 void setPseudoElement(PseudoId, PassRefPtrWillBeRawPtr<PseudoElement>); 53 PseudoElement* pseudoElement(PseudoId) const; 54 55 void resetStyleState(); 56 57 short tabIndex() const { return m_tabindex; } 58 59 void setTabIndexExplicitly(short index) 60 { 61 m_tabindex = index; 62 setElementFlag(TabIndexWasSetExplicitly, true); 63 } 64 65 void clearTabIndexExplicitly() 66 { 67 m_tabindex = 0; 68 clearElementFlag(TabIndexWasSetExplicitly); 69 } 70 71 CSSStyleDeclaration& ensureInlineCSSStyleDeclaration(Element* ownerElement); 72 73 void clearShadow() { m_shadow = nullptr; } 74 ElementShadow* shadow() const { return m_shadow.get(); } 75 ElementShadow& ensureShadow() 76 { 77 if (!m_shadow) 78 m_shadow = ElementShadow::create(); 79 return *m_shadow; 80 } 81 82 NamedNodeMap* attributeMap() const { return m_attributeMap.get(); } 83 void setAttributeMap(PassOwnPtrWillBeRawPtr<NamedNodeMap> attributeMap) { m_attributeMap = attributeMap; } 84 85 RenderStyle* computedStyle() const { return m_computedStyle.get(); } 86 void setComputedStyle(PassRefPtr<RenderStyle> computedStyle) { m_computedStyle = computedStyle; } 87 void clearComputedStyle() { m_computedStyle = nullptr; } 88 89 ClassList* classList() const { return m_classList.get(); } 90 void setClassList(PassOwnPtrWillBeRawPtr<ClassList> classList) { m_classList = classList; } 91 void clearClassListValueForQuirksMode() 92 { 93 if (!m_classList) 94 return; 95 m_classList->clearValueForQuirksMode(); 96 } 97 98 DatasetDOMStringMap* dataset() const { return m_dataset.get(); } 99 void setDataset(PassOwnPtrWillBeRawPtr<DatasetDOMStringMap> dataset) { m_dataset = dataset; } 100 101 LayoutSize minimumSizeForResizing() const { return m_minimumSizeForResizing; } 102 void setMinimumSizeForResizing(LayoutSize size) { m_minimumSizeForResizing = size; } 103 104 IntSize savedLayerScrollOffset() const { return m_savedLayerScrollOffset; } 105 void setSavedLayerScrollOffset(IntSize size) { m_savedLayerScrollOffset = size; } 106 107 ActiveAnimations* activeAnimations() { return m_activeAnimations.get(); } 108 void setActiveAnimations(PassOwnPtrWillBeRawPtr<ActiveAnimations> activeAnimations) 109 { 110 m_activeAnimations = activeAnimations; 111 } 112 113 bool hasInputMethodContext() const { return m_inputMethodContext; } 114 InputMethodContext& ensureInputMethodContext(HTMLElement* element) 115 { 116 if (!m_inputMethodContext) 117 m_inputMethodContext = InputMethodContext::create(element); 118 return *m_inputMethodContext; 119 } 120 121 bool hasPseudoElements() const; 122 void clearPseudoElements(); 123 124 void setCustomElementDefinition(PassRefPtr<CustomElementDefinition> definition) { m_customElementDefinition = definition; } 125 CustomElementDefinition* customElementDefinition() const { return m_customElementDefinition.get(); } 126 127 WillBeHeapVector<RefPtrWillBeMember<Attr> >& ensureAttrNodeList(); 128 WillBeHeapVector<RefPtrWillBeMember<Attr> >* attrNodeList() { return m_attrNodeList.get(); } 129 void removeAttrNodeList() { m_attrNodeList.clear(); } 130 131 void traceAfterDispatch(Visitor*); 132 133 private: 134 short m_tabindex; 135 136 LayoutSize m_minimumSizeForResizing; 137 IntSize m_savedLayerScrollOffset; 138 139 OwnPtrWillBeMember<DatasetDOMStringMap> m_dataset; 140 OwnPtrWillBeMember<ClassList> m_classList; 141 OwnPtrWillBeMember<ElementShadow> m_shadow; 142 OwnPtrWillBeMember<NamedNodeMap> m_attributeMap; 143 OwnPtrWillBeMember<WillBeHeapVector<RefPtrWillBeMember<Attr> > > m_attrNodeList; 144 OwnPtrWillBeMember<InputMethodContext> m_inputMethodContext; 145 OwnPtrWillBeMember<ActiveAnimations> m_activeAnimations; 146 OwnPtrWillBeMember<InlineCSSStyleDeclaration> m_cssomWrapper; 147 148 RefPtr<RenderStyle> m_computedStyle; 149 RefPtr<CustomElementDefinition> m_customElementDefinition; 150 151 RefPtrWillBeMember<PseudoElement> m_generatedBefore; 152 RefPtrWillBeMember<PseudoElement> m_generatedAfter; 153 RefPtrWillBeMember<PseudoElement> m_backdrop; 154 155 explicit ElementRareData(RenderObject*); 156 }; 157 158 inline IntSize defaultMinimumSizeForResizing() 159 { 160 return IntSize(LayoutUnit::max(), LayoutUnit::max()); 161 } 162 163 inline ElementRareData::ElementRareData(RenderObject* renderer) 164 : NodeRareData(renderer) 165 , m_tabindex(0) 166 , m_minimumSizeForResizing(defaultMinimumSizeForResizing()) 167 { 168 m_isElementRareData = true; 169 } 170 171 inline ElementRareData::~ElementRareData() 172 { 173 #if !ENABLE(OILPAN) 174 ASSERT(!m_shadow); 175 #endif 176 ASSERT(!m_generatedBefore); 177 ASSERT(!m_generatedAfter); 178 ASSERT(!m_backdrop); 179 } 180 181 inline bool ElementRareData::hasPseudoElements() const 182 { 183 return m_generatedBefore || m_generatedAfter || m_backdrop; 184 } 185 186 inline void ElementRareData::clearPseudoElements() 187 { 188 setPseudoElement(BEFORE, nullptr); 189 setPseudoElement(AFTER, nullptr); 190 setPseudoElement(BACKDROP, nullptr); 191 } 192 193 inline void ElementRareData::setPseudoElement(PseudoId pseudoId, PassRefPtrWillBeRawPtr<PseudoElement> element) 194 { 195 switch (pseudoId) { 196 case BEFORE: 197 if (m_generatedBefore) 198 m_generatedBefore->dispose(); 199 m_generatedBefore = element; 200 break; 201 case AFTER: 202 if (m_generatedAfter) 203 m_generatedAfter->dispose(); 204 m_generatedAfter = element; 205 break; 206 case BACKDROP: 207 if (m_backdrop) 208 m_backdrop->dispose(); 209 m_backdrop = element; 210 break; 211 default: 212 ASSERT_NOT_REACHED(); 213 } 214 } 215 216 inline PseudoElement* ElementRareData::pseudoElement(PseudoId pseudoId) const 217 { 218 switch (pseudoId) { 219 case BEFORE: 220 return m_generatedBefore.get(); 221 case AFTER: 222 return m_generatedAfter.get(); 223 case BACKDROP: 224 return m_backdrop.get(); 225 default: 226 return 0; 227 } 228 } 229 230 inline void ElementRareData::resetStyleState() 231 { 232 clearElementFlag(StyleAffectedByEmpty); 233 } 234 235 } // namespace 236 237 #endif // ElementRareData_h 238