Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(934)

Side by Side Diff: Source/core/dom/LiveNodeList.h

Issue 132923003: Make sure the rootNode of a LiveNodeListBase is always a ContainerNode (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Slightly clearer cast Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. 5 * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
6 * 6 *
7 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public 8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
(...skipping 30 matching lines...) Expand all
41 NodeListIsRootedAtDocumentIfOwnerHasItemrefAttr, 41 NodeListIsRootedAtDocumentIfOwnerHasItemrefAttr,
42 }; 42 };
43 43
44 class LiveNodeListBase { 44 class LiveNodeListBase {
45 public: 45 public:
46 enum ItemAfterOverrideType { 46 enum ItemAfterOverrideType {
47 OverridesItemAfter, 47 OverridesItemAfter,
48 DoesNotOverrideItemAfter, 48 DoesNotOverrideItemAfter,
49 }; 49 };
50 50
51 LiveNodeListBase(Node* ownerNode, NodeListRootType rootType, NodeListInvalid ationType invalidationType, 51 LiveNodeListBase(ContainerNode* ownerNode, NodeListRootType rootType, NodeLi stInvalidationType invalidationType,
52 bool shouldOnlyIncludeDirectChildren, CollectionType collectionType, Ite mAfterOverrideType itemAfterOverrideType) 52 bool shouldOnlyIncludeDirectChildren, CollectionType collectionType, Ite mAfterOverrideType itemAfterOverrideType)
53 : m_ownerNode(ownerNode) 53 : m_ownerNode(ownerNode)
54 , m_cachedItem(0) 54 , m_cachedItem(0)
55 , m_isLengthCacheValid(false) 55 , m_isLengthCacheValid(false)
56 , m_isItemCacheValid(false) 56 , m_isItemCacheValid(false)
57 , m_rootType(rootType) 57 , m_rootType(rootType)
58 , m_invalidationType(invalidationType) 58 , m_invalidationType(invalidationType)
59 , m_shouldOnlyIncludeDirectChildren(shouldOnlyIncludeDirectChildren) 59 , m_shouldOnlyIncludeDirectChildren(shouldOnlyIncludeDirectChildren)
60 , m_collectionType(collectionType) 60 , m_collectionType(collectionType)
61 , m_overridesItemAfter(itemAfterOverrideType == OverridesItemAfter) 61 , m_overridesItemAfter(itemAfterOverrideType == OverridesItemAfter)
62 { 62 {
63 ASSERT(m_ownerNode);
63 ASSERT(m_rootType == static_cast<unsigned>(rootType)); 64 ASSERT(m_rootType == static_cast<unsigned>(rootType));
64 ASSERT(m_invalidationType == static_cast<unsigned>(invalidationType)); 65 ASSERT(m_invalidationType == static_cast<unsigned>(invalidationType));
65 ASSERT(m_collectionType == static_cast<unsigned>(collectionType)); 66 ASSERT(m_collectionType == static_cast<unsigned>(collectionType));
66 ASSERT(!m_overridesItemAfter || !isLiveNodeListType(collectionType)); 67 ASSERT(!m_overridesItemAfter || !isLiveNodeListType(collectionType));
67 68
68 if (collectionType != ChildNodeListType) 69 if (collectionType != ChildNodeListType)
69 document().registerNodeList(this); 70 document().registerNodeList(this);
70 } 71 }
71 72
72 virtual ~LiveNodeListBase() 73 virtual ~LiveNodeListBase()
73 { 74 {
74 if (type() != ChildNodeListType) 75 if (type() != ChildNodeListType)
75 document().unregisterNodeList(this); 76 document().unregisterNodeList(this);
76 } 77 }
77 78
78 unsigned length() const; 79 unsigned length() const;
79 Node* item(unsigned offset) const; 80 Node* item(unsigned offset) const;
80 81
81 ALWAYS_INLINE bool hasIdNameCache() const { return !isLiveNodeListType(type( )); } 82 ALWAYS_INLINE bool hasIdNameCache() const { return !isLiveNodeListType(type( )); }
82 ALWAYS_INLINE bool isRootedAtDocument() const { return m_rootType == NodeLis tIsRootedAtDocument || m_rootType == NodeListIsRootedAtDocumentIfOwnerHasItemref Attr; } 83 ALWAYS_INLINE bool isRootedAtDocument() const { return m_rootType == NodeLis tIsRootedAtDocument || m_rootType == NodeListIsRootedAtDocumentIfOwnerHasItemref Attr; }
83 ALWAYS_INLINE NodeListInvalidationType invalidationType() const { return sta tic_cast<NodeListInvalidationType>(m_invalidationType); } 84 ALWAYS_INLINE NodeListInvalidationType invalidationType() const { return sta tic_cast<NodeListInvalidationType>(m_invalidationType); }
84 ALWAYS_INLINE CollectionType type() const { return static_cast<CollectionTyp e>(m_collectionType); } 85 ALWAYS_INLINE CollectionType type() const { return static_cast<CollectionTyp e>(m_collectionType); }
85 Node* ownerNode() const { return m_ownerNode.get(); } 86 ContainerNode* ownerNode() const { return m_ownerNode.get(); }
86 ALWAYS_INLINE void invalidateCache(const QualifiedName* attrName) const 87 ALWAYS_INLINE void invalidateCache(const QualifiedName* attrName) const
87 { 88 {
88 if (!attrName || shouldInvalidateTypeOnAttributeChange(invalidationType( ), *attrName)) 89 if (!attrName || shouldInvalidateTypeOnAttributeChange(invalidationType( ), *attrName))
89 invalidateCache(); 90 invalidateCache();
90 else if (hasIdNameCache() && (*attrName == HTMLNames::idAttr || *attrNam e == HTMLNames::nameAttr)) 91 else if (hasIdNameCache() && (*attrName == HTMLNames::idAttr || *attrNam e == HTMLNames::nameAttr))
91 invalidateIdNameCacheMaps(); 92 invalidateIdNameCacheMaps();
92 } 93 }
93 virtual void invalidateCache() const; 94 virtual void invalidateCache() const;
94 95
95 static bool shouldInvalidateTypeOnAttributeChange(NodeListInvalidationType, const QualifiedName&); 96 static bool shouldInvalidateTypeOnAttributeChange(NodeListInvalidationType, const QualifiedName&);
96 97
97 protected: 98 protected:
98 Document& document() const { return m_ownerNode->document(); } 99 Document& document() const { return m_ownerNode->document(); }
99 Node& rootNode() const; 100 ContainerNode& rootNode() const;
100 ContainerNode* rootContainerNode() const;
101 bool overridesItemAfter() const { return m_overridesItemAfter; } 101 bool overridesItemAfter() const { return m_overridesItemAfter; }
102 102
103 ALWAYS_INLINE bool isItemCacheValid() const { return m_isItemCacheValid; } 103 ALWAYS_INLINE bool isItemCacheValid() const { return m_isItemCacheValid; }
104 ALWAYS_INLINE Node* cachedItem() const { return m_cachedItem; } 104 ALWAYS_INLINE Node* cachedItem() const { return m_cachedItem; }
105 ALWAYS_INLINE unsigned cachedItemOffset() const { return m_cachedItemOffset; } 105 ALWAYS_INLINE unsigned cachedItemOffset() const { return m_cachedItemOffset; }
106 106
107 ALWAYS_INLINE bool isLengthCacheValid() const { return m_isLengthCacheValid; } 107 ALWAYS_INLINE bool isLengthCacheValid() const { return m_isLengthCacheValid; }
108 ALWAYS_INLINE unsigned cachedLength() const { return m_cachedLength; } 108 ALWAYS_INLINE unsigned cachedLength() const { return m_cachedLength; }
109 ALWAYS_INLINE void setLengthCache(unsigned length) const 109 ALWAYS_INLINE void setLengthCache(unsigned length) const
110 { 110 {
111 m_cachedLength = length; 111 m_cachedLength = length;
112 m_isLengthCacheValid = true; 112 m_isLengthCacheValid = true;
113 } 113 }
114 ALWAYS_INLINE void setItemCache(Node* item, unsigned offset) const 114 ALWAYS_INLINE void setItemCache(Node* item, unsigned offset) const
115 { 115 {
116 ASSERT(item); 116 ASSERT(item);
117 m_cachedItem = item; 117 m_cachedItem = item;
118 m_cachedItemOffset = offset; 118 m_cachedItemOffset = offset;
119 m_isItemCacheValid = true; 119 m_isItemCacheValid = true;
120 } 120 }
121 121
122 ALWAYS_INLINE NodeListRootType rootType() const { return static_cast<NodeLis tRootType>(m_rootType); } 122 ALWAYS_INLINE NodeListRootType rootType() const { return static_cast<NodeLis tRootType>(m_rootType); }
123 bool shouldOnlyIncludeDirectChildren() const { return m_shouldOnlyIncludeDir ectChildren; } 123 bool shouldOnlyIncludeDirectChildren() const { return m_shouldOnlyIncludeDir ectChildren; }
124 124
125 private: 125 private:
126 Node* itemBeforeOrAfterCachedItem(unsigned offset, ContainerNode* root) cons t; 126 Node* itemBeforeOrAfterCachedItem(unsigned offset, ContainerNode& root) cons t;
127 bool isLastItemCloserThanLastOrCachedItem(unsigned offset) const; 127 bool isLastItemCloserThanLastOrCachedItem(unsigned offset) const;
128 bool isFirstItemCloserThanCachedItem(unsigned offset) const; 128 bool isFirstItemCloserThanCachedItem(unsigned offset) const;
129 Node* iterateForPreviousNode(Node* current) const; 129 Node* iterateForPreviousNode(Node* current) const;
130 Node* itemBefore(Node* previousItem) const; 130 Node* itemBefore(Node* previousItem) const;
131 void invalidateIdNameCacheMaps() const; 131 void invalidateIdNameCacheMaps() const;
132 132
133 RefPtr<Node> m_ownerNode; 133 RefPtr<ContainerNode> m_ownerNode; // Cannot be null.
134 mutable Node* m_cachedItem; 134 mutable Node* m_cachedItem;
135 mutable unsigned m_cachedLength; 135 mutable unsigned m_cachedLength;
136 mutable unsigned m_cachedItemOffset; 136 mutable unsigned m_cachedItemOffset;
137 mutable unsigned m_isLengthCacheValid : 1; 137 mutable unsigned m_isLengthCacheValid : 1;
138 mutable unsigned m_isItemCacheValid : 1; 138 mutable unsigned m_isItemCacheValid : 1;
139 const unsigned m_rootType : 2; 139 const unsigned m_rootType : 2;
140 const unsigned m_invalidationType : 4; 140 const unsigned m_invalidationType : 4;
141 const unsigned m_shouldOnlyIncludeDirectChildren : 1; 141 const unsigned m_shouldOnlyIncludeDirectChildren : 1;
142 const unsigned m_collectionType : 5; 142 const unsigned m_collectionType : 5;
143 143
(...skipping 21 matching lines...) Expand all
165 case DoNotInvalidateOnAttributeChanges: 165 case DoNotInvalidateOnAttributeChanges:
166 return false; 166 return false;
167 case InvalidateOnAnyAttrChange: 167 case InvalidateOnAnyAttrChange:
168 return true; 168 return true;
169 } 169 }
170 return false; 170 return false;
171 } 171 }
172 172
173 class LiveNodeList : public NodeList, public LiveNodeListBase { 173 class LiveNodeList : public NodeList, public LiveNodeListBase {
174 public: 174 public:
175 LiveNodeList(PassRefPtr<Node> ownerNode, CollectionType collectionType, Node ListInvalidationType invalidationType, NodeListRootType rootType = NodeListIsRoo tedAtNode) 175 LiveNodeList(PassRefPtr<ContainerNode> ownerNode, CollectionType collectionT ype, NodeListInvalidationType invalidationType, NodeListRootType rootType = Node ListIsRootedAtNode)
176 : LiveNodeListBase(ownerNode.get(), rootType, invalidationType, collecti onType == ChildNodeListType, 176 : LiveNodeListBase(ownerNode.get(), rootType, invalidationType, collecti onType == ChildNodeListType,
177 collectionType, DoesNotOverrideItemAfter) 177 collectionType, DoesNotOverrideItemAfter)
178 { } 178 { }
179 179
180 virtual unsigned length() const OVERRIDE FINAL { return LiveNodeListBase::le ngth(); } 180 virtual unsigned length() const OVERRIDE FINAL { return LiveNodeListBase::le ngth(); }
181 virtual Node* item(unsigned offset) const OVERRIDE FINAL { return LiveNodeLi stBase::item(offset); } 181 virtual Node* item(unsigned offset) const OVERRIDE FINAL { return LiveNodeLi stBase::item(offset); }
182 virtual Node* namedItem(const AtomicString&) const OVERRIDE FINAL; 182 virtual Node* namedItem(const AtomicString&) const OVERRIDE FINAL;
183 virtual bool nodeMatches(Element*) const = 0; 183 virtual bool nodeMatches(Element*) const = 0;
184 // Avoid ambiguity since both NodeList and LiveNodeListBase have an ownerNod e() method. 184 // Avoid ambiguity since both NodeList and LiveNodeListBase have an ownerNod e() method.
185 using LiveNodeListBase::ownerNode; 185 using LiveNodeListBase::ownerNode;
186 186
187 Node* traverseToFirstElement(ContainerNode& root) const; 187 Node* traverseToFirstElement(ContainerNode& root) const;
188 Node* traverseForwardToOffset(unsigned offset, Node& currentNode, unsigned& currentOffset, ContainerNode* root) const; 188 Node* traverseForwardToOffset(unsigned offset, Node& currentNode, unsigned& currentOffset, ContainerNode& root) const;
189 189
190 private: 190 private:
191 virtual bool isLiveNodeList() const OVERRIDE FINAL { return true; } 191 virtual bool isLiveNodeList() const OVERRIDE FINAL { return true; }
192 }; 192 };
193 193
194 } // namespace WebCore 194 } // namespace WebCore
195 195
196 #endif // LiveNodeList_h 196 #endif // LiveNodeList_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698