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