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