Shrink NodeListsNodeData
[WebKit-https.git] / Source / WebCore / dom / DynamicNodeList.h
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2001 Dirk Mueller (mueller@kde.org)
5  * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  *
22  */
23
24 #ifndef DynamicNodeList_h
25 #define DynamicNodeList_h
26
27 #include "Document.h"
28 #include "NodeList.h"
29 #include <wtf/Forward.h>
30 #include <wtf/RefPtr.h>
31
32 namespace WebCore {
33
34 class Element;
35 class Node;
36
37 class DynamicNodeList : public NodeList {
38 public:
39     enum NodeListType {
40         ChildNodeListType,
41         ClassNodeListType,
42         NameNodeListType,
43         TagNodeListType,
44         RadioNodeListType,
45         LabelsNodeListType,
46         MicroDataItemListType,
47     };
48     enum RootType {
49         RootedAtNode,
50         RootedAtDocument,
51     };
52     enum InvalidationType {
53         AlwaysInvalidate,
54         DoNotInvalidateOnAttributeChange,
55     };
56     DynamicNodeList(PassRefPtr<Node> node, RootType rootType, InvalidationType invalidationType)
57         : m_node(node)
58         , m_caches(rootType, invalidationType)
59     { }
60     virtual ~DynamicNodeList() { }
61
62     // DOM methods & attributes for NodeList
63     virtual unsigned length() const = 0;
64     virtual Node* item(unsigned index) const = 0;
65     virtual Node* itemWithName(const AtomicString&) const;
66
67     // Other methods (not part of DOM)
68     Node* node() const
69     {
70         if (m_caches.rootedAtDocument && m_node->inDocument())
71             return m_node->document();
72         return m_node.get();
73     }
74     Document* document() { return m_node->document(); }
75
76     bool shouldInvalidateOnAttributeChange() const { return m_caches.shouldInvalidateOnAttributeChange; }
77
78     void invalidateCache() { m_caches.reset(); }
79
80 protected:
81     virtual bool nodeMatches(Element*) const = 0;
82
83     struct Caches {
84         Caches(RootType rootType, InvalidationType invalidationType)
85             : rootedAtDocument(rootType == RootedAtDocument)
86             , shouldInvalidateOnAttributeChange(invalidationType == AlwaysInvalidate)
87         {
88             reset();
89         }
90
91         void reset()
92         {
93             lastItem = 0;
94             isLengthCacheValid = false;
95             isItemCacheValid = false;
96         }
97
98         Node* lastItem;
99         unsigned cachedLength;
100         unsigned lastItemOffset;
101         unsigned isLengthCacheValid : 1;
102         unsigned isItemCacheValid : 1;
103
104         // Following flags should belong in DynamicSubtreeNode but are here for bit-packing.
105         unsigned type : 4;
106         unsigned rootedAtDocument : 1;
107         unsigned shouldInvalidateOnAttributeChange : 1;
108     };
109
110     RefPtr<Node> m_node;
111     mutable Caches m_caches;
112
113 private:
114     virtual bool isDynamicNodeList() const OVERRIDE { return true; }
115 };
116
117 class DynamicSubtreeNodeList : public DynamicNodeList {
118 public:
119     virtual ~DynamicSubtreeNodeList();
120     virtual unsigned length() const OVERRIDE;
121     virtual Node* item(unsigned index) const OVERRIDE;
122
123 protected:
124     DynamicSubtreeNodeList(PassRefPtr<Node> node, RootType rootType = RootedAtNode, InvalidationType invalidationType = AlwaysInvalidate)
125         : DynamicNodeList(node, rootType, invalidationType)
126     { }
127
128 private:
129     Node* itemForwardsFromCurrent(Node* start, unsigned offset, int remainingOffset) const;
130     Node* itemBackwardsFromCurrent(Node* start, unsigned offset, int remainingOffset) const;
131 };
132
133 } // namespace WebCore
134
135 #endif // DynamicNodeList_h