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 ElementRareData_h 23#define ElementRareData_h 24 25#include "ClassList.h" 26#include "DatasetDOMStringMap.h" 27#include "ElementShadow.h" 28#include "NamedNodeMap.h" 29#include "NodeRareData.h" 30#include "PseudoElement.h" 31#include "StyleInheritedData.h" 32#include <wtf/OwnPtr.h> 33 34namespace WebCore { 35 36class ElementRareData : public NodeRareData { 37public: 38 static PassOwnPtr<ElementRareData> create(RenderObject* renderer) { return adoptPtr(new ElementRareData(renderer)); } 39 40 ~ElementRareData(); 41 42 void setPseudoElement(PseudoId, PassRefPtr<PseudoElement>); 43 PseudoElement* pseudoElement(PseudoId) const; 44 bool hasPseudoElements() const { return m_generatedBefore || m_generatedAfter; } 45 46 void resetComputedStyle(); 47 void resetDynamicRestyleObservations(); 48 49 short tabIndex() const { return m_tabIndex; } 50 void setTabIndexExplicitly(short index) { m_tabIndex = index; m_tabIndexWasSetExplicitly = true; } 51 bool tabIndexSetExplicitly() const { return m_tabIndexWasSetExplicitly; } 52 void clearTabIndexExplicitly() { m_tabIndex = 0; m_tabIndexWasSetExplicitly = false; } 53 54 bool needsFocusAppearanceUpdateSoonAfterAttach() const { return m_needsFocusAppearanceUpdateSoonAfterAttach; } 55 void setNeedsFocusAppearanceUpdateSoonAfterAttach(bool needs) { m_needsFocusAppearanceUpdateSoonAfterAttach = needs; } 56 57 bool styleAffectedByEmpty() const { return m_styleAffectedByEmpty; } 58 void setStyleAffectedByEmpty(bool value) { m_styleAffectedByEmpty = value; } 59 60 bool isInCanvasSubtree() const { return m_isInCanvasSubtree; } 61 void setIsInCanvasSubtree(bool value) { m_isInCanvasSubtree = value; } 62 63 bool isInsideRegion() const { return m_isInsideRegion; } 64 void setIsInsideRegion(bool value) { m_isInsideRegion = value; } 65 66#if ENABLE(FULLSCREEN_API) 67 bool containsFullScreenElement() { return m_containsFullScreenElement; } 68 void setContainsFullScreenElement(bool value) { m_containsFullScreenElement = value; } 69#endif 70 71#if ENABLE(DIALOG_ELEMENT) 72 bool isInTopLayer() const { return m_isInTopLayer; } 73 void setIsInTopLayer(bool value) { m_isInTopLayer = value; } 74#endif 75 76 bool childrenAffectedByHover() const { return m_childrenAffectedByHover; } 77 void setChildrenAffectedByHover(bool value) { m_childrenAffectedByHover = value; } 78 bool childrenAffectedByActive() const { return m_childrenAffectedByActive; } 79 void setChildrenAffectedByActive(bool value) { m_childrenAffectedByActive = value; } 80 bool childrenAffectedByDrag() const { return m_childrenAffectedByDrag; } 81 void setChildrenAffectedByDrag(bool value) { m_childrenAffectedByDrag = value; } 82 83 bool childrenAffectedByFirstChildRules() const { return m_childrenAffectedByFirstChildRules; } 84 void setChildrenAffectedByFirstChildRules(bool value) { m_childrenAffectedByFirstChildRules = value; } 85 bool childrenAffectedByLastChildRules() const { return m_childrenAffectedByLastChildRules; } 86 void setChildrenAffectedByLastChildRules(bool value) { m_childrenAffectedByLastChildRules = value; } 87 bool childrenAffectedByDirectAdjacentRules() const { return m_childrenAffectedByDirectAdjacentRules; } 88 void setChildrenAffectedByDirectAdjacentRules(bool value) { m_childrenAffectedByDirectAdjacentRules = value; } 89 bool childrenAffectedByForwardPositionalRules() const { return m_childrenAffectedByForwardPositionalRules; } 90 void setChildrenAffectedByForwardPositionalRules(bool value) { m_childrenAffectedByForwardPositionalRules = value; } 91 bool childrenAffectedByBackwardPositionalRules() const { return m_childrenAffectedByBackwardPositionalRules; } 92 void setChildrenAffectedByBackwardPositionalRules(bool value) { m_childrenAffectedByBackwardPositionalRules = value; } 93 unsigned childIndex() const { return m_childIndex; } 94 void setChildIndex(unsigned index) { m_childIndex = index; } 95 96 void clearShadow() { m_shadow = nullptr; } 97 ElementShadow* shadow() const { return m_shadow.get(); } 98 ElementShadow* ensureShadow() 99 { 100 if (!m_shadow) 101 m_shadow = ElementShadow::create(); 102 return m_shadow.get(); 103 } 104 105 NamedNodeMap* attributeMap() const { return m_attributeMap.get(); } 106 void setAttributeMap(PassOwnPtr<NamedNodeMap> attributeMap) { m_attributeMap = attributeMap; } 107 108 RenderStyle* computedStyle() const { return m_computedStyle.get(); } 109 void setComputedStyle(PassRefPtr<RenderStyle> computedStyle) { m_computedStyle = computedStyle; } 110 111 ClassList* classList() const { return m_classList.get(); } 112 void setClassList(PassOwnPtr<ClassList> classList) { m_classList = classList; } 113 void clearClassListValueForQuirksMode() 114 { 115 if (!m_classList) 116 return; 117 m_classList->clearValueForQuirksMode(); 118 } 119 120 DatasetDOMStringMap* dataset() const { return m_dataset.get(); } 121 void setDataset(PassOwnPtr<DatasetDOMStringMap> dataset) { m_dataset = dataset; } 122 123 LayoutSize minimumSizeForResizing() const { return m_minimumSizeForResizing; } 124 void setMinimumSizeForResizing(LayoutSize size) { m_minimumSizeForResizing = size; } 125 126 IntSize savedLayerScrollOffset() const { return m_savedLayerScrollOffset; } 127 void setSavedLayerScrollOffset(IntSize size) { m_savedLayerScrollOffset = size; } 128 129#if ENABLE(SVG) 130 bool hasPendingResources() const { return m_hasPendingResources; } 131 void setHasPendingResources(bool has) { m_hasPendingResources = has; } 132#endif 133 134private: 135 short m_tabIndex; 136 unsigned short m_childIndex; 137 unsigned m_tabIndexWasSetExplicitly : 1; 138 unsigned m_needsFocusAppearanceUpdateSoonAfterAttach : 1; 139 unsigned m_styleAffectedByEmpty : 1; 140 unsigned m_isInCanvasSubtree : 1; 141#if ENABLE(FULLSCREEN_API) 142 unsigned m_containsFullScreenElement : 1; 143#endif 144#if ENABLE(DIALOG_ELEMENT) 145 unsigned m_isInTopLayer : 1; 146#endif 147#if ENABLE(SVG) 148 unsigned m_hasPendingResources : 1; 149#endif 150 unsigned m_childrenAffectedByHover : 1; 151 unsigned m_childrenAffectedByActive : 1; 152 unsigned m_childrenAffectedByDrag : 1; 153 // Bits for dynamic child matching. 154 // We optimize for :first-child and :last-child. The other positional child selectors like nth-child or 155 // *-child-of-type, we will just give up and re-evaluate whenever children change at all. 156 unsigned m_childrenAffectedByFirstChildRules : 1; 157 unsigned m_childrenAffectedByLastChildRules : 1; 158 unsigned m_childrenAffectedByDirectAdjacentRules : 1; 159 unsigned m_childrenAffectedByForwardPositionalRules : 1; 160 unsigned m_childrenAffectedByBackwardPositionalRules : 1; 161 162 unsigned m_isInsideRegion : 1; 163 LayoutSize m_minimumSizeForResizing; 164 IntSize m_savedLayerScrollOffset; 165 RefPtr<RenderStyle> m_computedStyle; 166 167 OwnPtr<DatasetDOMStringMap> m_dataset; 168 OwnPtr<ClassList> m_classList; 169 OwnPtr<ElementShadow> m_shadow; 170 OwnPtr<NamedNodeMap> m_attributeMap; 171 172 RefPtr<PseudoElement> m_generatedBefore; 173 RefPtr<PseudoElement> m_generatedAfter; 174 175 ElementRareData(RenderObject*); 176 void releasePseudoElement(PseudoElement*); 177}; 178 179inline IntSize defaultMinimumSizeForResizing() 180{ 181 return IntSize(LayoutUnit::max(), LayoutUnit::max()); 182} 183 184inline ElementRareData::ElementRareData(RenderObject* renderer) 185 : NodeRareData(renderer) 186 , m_tabIndex(0) 187 , m_childIndex(0) 188 , m_tabIndexWasSetExplicitly(false) 189 , m_needsFocusAppearanceUpdateSoonAfterAttach(false) 190 , m_styleAffectedByEmpty(false) 191 , m_isInCanvasSubtree(false) 192#if ENABLE(FULLSCREEN_API) 193 , m_containsFullScreenElement(false) 194#endif 195#if ENABLE(DIALOG_ELEMENT) 196 , m_isInTopLayer(false) 197#endif 198#if ENABLE(SVG) 199 , m_hasPendingResources(false) 200#endif 201 , m_childrenAffectedByHover(false) 202 , m_childrenAffectedByActive(false) 203 , m_childrenAffectedByDrag(false) 204 , m_childrenAffectedByFirstChildRules(false) 205 , m_childrenAffectedByLastChildRules(false) 206 , m_childrenAffectedByDirectAdjacentRules(false) 207 , m_childrenAffectedByForwardPositionalRules(false) 208 , m_childrenAffectedByBackwardPositionalRules(false) 209 , m_isInsideRegion(false) 210 , m_minimumSizeForResizing(defaultMinimumSizeForResizing()) 211{ 212} 213 214inline ElementRareData::~ElementRareData() 215{ 216 ASSERT(!m_shadow); 217 ASSERT(!m_generatedBefore); 218 ASSERT(!m_generatedAfter); 219} 220 221inline void ElementRareData::setPseudoElement(PseudoId pseudoId, PassRefPtr<PseudoElement> element) 222{ 223 switch (pseudoId) { 224 case BEFORE: 225 releasePseudoElement(m_generatedBefore.get()); 226 m_generatedBefore = element; 227 break; 228 case AFTER: 229 releasePseudoElement(m_generatedAfter.get()); 230 m_generatedAfter = element; 231 break; 232 default: 233 ASSERT_NOT_REACHED(); 234 } 235} 236 237inline PseudoElement* ElementRareData::pseudoElement(PseudoId pseudoId) const 238{ 239 switch (pseudoId) { 240 case BEFORE: 241 return m_generatedBefore.get(); 242 case AFTER: 243 return m_generatedAfter.get(); 244 default: 245 return 0; 246 } 247} 248 249inline void ElementRareData::releasePseudoElement(PseudoElement* element) 250{ 251 if (!element) 252 return; 253 254 if (element->attached()) 255 element->detach(); 256 257 ASSERT(!element->nextSibling()); 258 ASSERT(!element->previousSibling()); 259 260 element->setParentOrShadowHostNode(0); 261} 262 263inline void ElementRareData::resetComputedStyle() 264{ 265 setComputedStyle(0); 266 setStyleAffectedByEmpty(false); 267 setChildIndex(0); 268} 269 270inline void ElementRareData::resetDynamicRestyleObservations() 271{ 272 setChildrenAffectedByHover(false); 273 setChildrenAffectedByActive(false); 274 setChildrenAffectedByDrag(false); 275 setChildrenAffectedByFirstChildRules(false); 276 setChildrenAffectedByLastChildRules(false); 277 setChildrenAffectedByDirectAdjacentRules(false); 278 setChildrenAffectedByForwardPositionalRules(false); 279 setChildrenAffectedByBackwardPositionalRules(false); 280} 281 282} // namespace 283 284#endif // ElementRareData_h 285