1 /*
2  * Copyright (C) 2008, 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 NodeRareData_h
23 #define NodeRareData_h
24 
25 #include "ClassNodeList.h"
26 #include "DynamicNodeList.h"
27 #include "NameNodeList.h"
28 #include "QualifiedName.h"
29 #include "TagNodeList.h"
30 #include <wtf/HashSet.h>
31 #include <wtf/OwnPtr.h>
32 #include <wtf/PassOwnPtr.h>
33 #include <wtf/text/StringHash.h>
34 
35 namespace WebCore {
36 
37 class LabelsNodeList;
38 class TreeScope;
39 
40 struct NodeListsNodeData {
41     WTF_MAKE_NONCOPYABLE(NodeListsNodeData); WTF_MAKE_FAST_ALLOCATED;
42 public:
43     typedef HashSet<DynamicNodeList*> NodeListSet;
44     NodeListSet m_listsWithCaches;
45 
46     RefPtr<DynamicNodeList::Caches> m_childNodeListCaches;
47 
48     typedef HashMap<String, ClassNodeList*> ClassNodeListCache;
49     ClassNodeListCache m_classNodeListCache;
50 
51     typedef HashMap<String, NameNodeList*> NameNodeListCache;
52     NameNodeListCache m_nameNodeListCache;
53 
54     typedef HashMap<AtomicString, TagNodeList*> TagNodeListCache;
55     TagNodeListCache m_tagNodeListCache;
56 
57     typedef HashMap<RefPtr<QualifiedName::QualifiedNameImpl>, TagNodeList*> TagNodeListCacheNS;
58     TagNodeListCacheNS m_tagNodeListCacheNS;
59 
60     LabelsNodeList* m_labelsNodeListCache;
61 
createNodeListsNodeData62     static PassOwnPtr<NodeListsNodeData> create()
63     {
64         return adoptPtr(new NodeListsNodeData);
65     }
66 
67     void invalidateCaches();
68     void invalidateCachesThatDependOnAttributes();
69     bool isEmpty() const;
70 
71 private:
NodeListsNodeDataNodeListsNodeData72     NodeListsNodeData()
73         : m_childNodeListCaches(DynamicNodeList::Caches::create()), m_labelsNodeListCache(0)
74     {
75     }
76 };
77 
78 class NodeRareData {
79     WTF_MAKE_NONCOPYABLE(NodeRareData); WTF_MAKE_FAST_ALLOCATED;
80 public:
NodeRareData()81     NodeRareData()
82         : m_treeScope(0)
83         , m_tabIndex(0)
84         , m_tabIndexWasSetExplicitly(false)
85         , m_isFocused(false)
86         , m_needsFocusAppearanceUpdateSoonAfterAttach(false)
87     {
88     }
89 
~NodeRareData()90     virtual ~NodeRareData()
91     {
92     }
93 
94     typedef HashMap<const Node*, NodeRareData*> NodeRareDataMap;
95 
rareDataMap()96     static NodeRareDataMap& rareDataMap()
97     {
98         static NodeRareDataMap* dataMap = new NodeRareDataMap;
99         return *dataMap;
100     }
101 
rareDataFromMap(const Node * node)102     static NodeRareData* rareDataFromMap(const Node* node)
103     {
104         return rareDataMap().get(node);
105     }
106 
treeScope()107     TreeScope* treeScope() const { return m_treeScope; }
setTreeScope(TreeScope * treeScope)108     void setTreeScope(TreeScope* treeScope) { m_treeScope = treeScope; }
109 
clearNodeLists()110     void clearNodeLists() { m_nodeLists.clear(); }
setNodeLists(PassOwnPtr<NodeListsNodeData> lists)111     void setNodeLists(PassOwnPtr<NodeListsNodeData> lists) { m_nodeLists = lists; }
nodeLists()112     NodeListsNodeData* nodeLists() const { return m_nodeLists.get(); }
113 
tabIndex()114     short tabIndex() const { return m_tabIndex; }
setTabIndexExplicitly(short index)115     void setTabIndexExplicitly(short index) { m_tabIndex = index; m_tabIndexWasSetExplicitly = true; }
tabIndexSetExplicitly()116     bool tabIndexSetExplicitly() const { return m_tabIndexWasSetExplicitly; }
clearTabIndexExplicitly()117     void clearTabIndexExplicitly() { m_tabIndex = 0; m_tabIndexWasSetExplicitly = false; }
118 
eventTargetData()119     EventTargetData* eventTargetData() { return m_eventTargetData.get(); }
ensureEventTargetData()120     EventTargetData* ensureEventTargetData()
121     {
122         if (!m_eventTargetData)
123             m_eventTargetData = adoptPtr(new EventTargetData);
124         return m_eventTargetData.get();
125     }
126 
isFocused()127     bool isFocused() const { return m_isFocused; }
setFocused(bool focused)128     void setFocused(bool focused) { m_isFocused = focused; }
129 
130 protected:
131     // for ElementRareData
needsFocusAppearanceUpdateSoonAfterAttach()132     bool needsFocusAppearanceUpdateSoonAfterAttach() const { return m_needsFocusAppearanceUpdateSoonAfterAttach; }
setNeedsFocusAppearanceUpdateSoonAfterAttach(bool needs)133     void setNeedsFocusAppearanceUpdateSoonAfterAttach(bool needs) { m_needsFocusAppearanceUpdateSoonAfterAttach = needs; }
134 
135 private:
136     TreeScope* m_treeScope;
137     OwnPtr<NodeListsNodeData> m_nodeLists;
138     OwnPtr<EventTargetData> m_eventTargetData;
139     short m_tabIndex;
140     bool m_tabIndexWasSetExplicitly : 1;
141     bool m_isFocused : 1;
142     bool m_needsFocusAppearanceUpdateSoonAfterAttach : 1;
143 };
144 
145 } // namespace WebCore
146 
147 #endif // NodeRareData_h
148