Changeset 166369 in webkit
- Timestamp:
- Mar 27, 2014, 1:49:27 PM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 14 edited
-
ChangeLog (modified) (1 diff)
-
dom/ClassNodeList.cpp (modified) (2 diffs)
-
dom/ClassNodeList.h (modified) (4 diffs)
-
dom/LiveNodeList.cpp (modified) (3 diffs)
-
dom/LiveNodeList.h (modified) (5 diffs)
-
dom/NameNodeList.cpp (modified) (1 diff)
-
dom/NameNodeList.h (modified) (2 diffs)
-
dom/Node.cpp (modified) (3 diffs)
-
dom/TagNodeList.cpp (modified) (2 diffs)
-
dom/TagNodeList.h (modified) (4 diffs)
-
html/LabelsNodeList.cpp (modified) (1 diff)
-
html/LabelsNodeList.h (modified) (2 diffs)
-
html/RadioNodeList.cpp (modified) (1 diff)
-
html/RadioNodeList.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r166368 r166369 1 2014-03-27 Antti Koivisto <antti@apple.com> 2 3 Remove some unnecessary branches from LiveNodeList traversal 4 https://bugs.webkit.org/show_bug.cgi?id=130854 5 6 Reviewed by Andreas Kling. 7 8 Compile different traversal code paths for all NodeList subclasses. 9 10 * dom/ClassNodeList.cpp: 11 (WebCore::ClassNodeList::ClassNodeList): 12 (WebCore::ClassNodeList::~ClassNodeList): 13 (WebCore::ClassNodeList::nodeMatches): Deleted. 14 * dom/ClassNodeList.h: 15 (WebCore::ClassNodeList::nodeMatches): 16 (WebCore::ClassNodeList::nodeMatchesInlined): Deleted. 17 18 Remove separate nodeMatchesInlined functions. 19 We now rely on exact types and marking classes final. 20 21 * dom/LiveNodeList.cpp: 22 (WebCore::LiveNodeList::LiveNodeList): 23 (WebCore::LiveNodeList::~LiveNodeList): 24 (WebCore::LiveNodeList::namedItem): 25 (WebCore::LiveNodeList::rootNode): Deleted. 26 (WebCore::isMatchingElement): Deleted. 27 (WebCore::firstMatchingElement): Deleted. 28 (WebCore::lastMatchingElement): Deleted. 29 (WebCore::nextMatchingElement): Deleted. 30 (WebCore::previousMatchingElement): Deleted. 31 (WebCore::traverseMatchingElementsForward): Deleted. 32 (WebCore::traverseMatchingElementsBackward): Deleted. 33 (WebCore::LiveNodeList::collectionFirst): Deleted. 34 (WebCore::LiveNodeList::collectionLast): Deleted. 35 (WebCore::LiveNodeList::collectionTraverseForward): Deleted. 36 (WebCore::LiveNodeList::collectionTraverseBackward): Deleted. 37 (WebCore::LiveNodeList::length): Deleted. 38 (WebCore::LiveNodeList::item): Deleted. 39 (WebCore::LiveNodeList::memoryCost): Deleted. 40 (WebCore::LiveNodeList::invalidateCache): Deleted. 41 * dom/LiveNodeList.h: 42 (WebCore::LiveNodeList::invalidateCacheForAttribute): 43 (WebCore::CachedLiveNodeList::collectionCanTraverseBackward): 44 (WebCore::LiveNodeList::rootNode): 45 (WebCore::CachedLiveNodeList<NodeListType>::CachedLiveNodeList): 46 47 Add CachedLiveNodeList<NodeListType> utility type that interfaces with CollectionIndexCache. 48 It is the base class for all concrete LiveNodeLists. 49 50 (WebCore::CachedLiveNodeList<NodeListType>::~CachedLiveNodeList): 51 (WebCore::CachedLiveNodeList<NodeListType>::collectionFirst): 52 (WebCore::CachedLiveNodeList<NodeListType>::collectionLast): 53 (WebCore::nextMatchingElement): 54 (WebCore::CachedLiveNodeList<NodeListType>::collectionTraverseForward): 55 (WebCore::previousMatchingElement): 56 (WebCore::CachedLiveNodeList<NodeListType>::collectionTraverseBackward): 57 (WebCore::CachedLiveNodeList<NodeListType>::willValidateIndexCache): 58 (WebCore::CachedLiveNodeList<NodeListType>::invalidateCache): 59 (WebCore::CachedLiveNodeList<NodeListType>::length): 60 (WebCore::CachedLiveNodeList<NodeListType>::item): 61 (WebCore::CachedLiveNodeList<NodeListType>::memoryCost): 62 63 Templated code moves to header. 64 65 (WebCore::LiveNodeList::LiveNodeList): Deleted. 66 (WebCore::LiveNodeList::~LiveNodeList): Deleted. 67 (WebCore::LiveNodeList::invalidateCache): Deleted. 68 (WebCore::LiveNodeList::collectionCanTraverseBackward): Deleted. 69 (WebCore::LiveNodeList::willValidateIndexCache): Deleted. 70 * dom/NameNodeList.cpp: 71 (WebCore::NameNodeList::NameNodeList): 72 * dom/NameNodeList.h: 73 * dom/Node.cpp: 74 (WebCore::Document::invalidateNodeListAndCollectionCaches): 75 (WebCore::NodeListsNodeData::invalidateCaches): 76 * dom/TagNodeList.cpp: 77 (WebCore::TagNodeList::TagNodeList): 78 (WebCore::HTMLTagNodeList::HTMLTagNodeList): 79 (WebCore::HTMLTagNodeList::~HTMLTagNodeList): 80 (WebCore::TagNodeList::nodeMatches): Deleted. 81 (WebCore::HTMLTagNodeList::nodeMatches): Deleted. 82 * dom/TagNodeList.h: 83 (WebCore::TagNodeList::nodeMatches): 84 (WebCore::HTMLTagNodeList::nodeMatches): 85 (WebCore::TagNodeList::create): Deleted. 86 (WebCore::HTMLTagNodeList::nodeMatchesInlined): Deleted. 87 * html/LabelsNodeList.cpp: 88 (WebCore::LabelsNodeList::LabelsNodeList): 89 * html/LabelsNodeList.h: 90 * html/RadioNodeList.cpp: 91 (WebCore::RadioNodeList::RadioNodeList): 92 * html/RadioNodeList.h: 93 1 94 2014-03-27 Adenilson Cavalcanti <cavalcantii@gmail.com> 2 95 -
trunk/Source/WebCore/dom/ClassNodeList.cpp
r165676 r166369 37 37 38 38 ClassNodeList::ClassNodeList(ContainerNode& rootNode, const String& classNames) 39 : LiveNodeList(rootNode, Type::ClassNodeListType, InvalidateOnClassAttrChange)39 : CachedLiveNodeList(rootNode, Type::ClassNodeListType, InvalidateOnClassAttrChange) 40 40 , m_classNames(classNames, document().inQuirksMode()) 41 41 , m_originalClassNames(classNames) … … 46 46 { 47 47 ownerNode().nodeLists()->removeCacheWithName(this, m_originalClassNames); 48 }49 50 bool ClassNodeList::nodeMatches(Element* testNode) const51 {52 return nodeMatchesInlined(testNode);53 48 } 54 49 -
trunk/Source/WebCore/dom/ClassNodeList.h
r165676 r166369 38 38 namespace WebCore { 39 39 40 class ClassNodeList : public LiveNodeList{40 class ClassNodeList final : public CachedLiveNodeList<ClassNodeList> { 41 41 public: 42 42 static PassRefPtr<ClassNodeList> create(ContainerNode& rootNode, const String& classNames) … … 47 47 virtual ~ClassNodeList(); 48 48 49 bool nodeMatchesInlined(Element*) const;49 virtual bool nodeMatches(Element*) const override; 50 50 51 51 private: 52 52 ClassNodeList(ContainerNode& rootNode, const String& classNames); 53 54 virtual bool nodeMatches(Element*) const override;55 53 56 54 SpaceSplitString m_classNames; … … 58 56 }; 59 57 60 inline bool ClassNodeList::nodeMatches Inlined(Element* testNode) const58 inline bool ClassNodeList::nodeMatches(Element* element) const 61 59 { 62 if (! testNode->hasClass())60 if (!element->hasClass()) 63 61 return false; 64 62 if (!m_classNames.size()) … … 66 64 // FIXME: DOM4 allows getElementsByClassName to return non StyledElement. 67 65 // https://bugs.webkit.org/show_bug.cgi?id=94718 68 if (! testNode->isStyledElement())66 if (!element->isStyledElement()) 69 67 return false; 70 return testNode->classNames().containsAll(m_classNames);68 return element->classNames().containsAll(m_classNames); 71 69 } 72 70 -
trunk/Source/WebCore/dom/LiveNodeList.cpp
r165254 r166369 32 32 namespace WebCore { 33 33 34 ContainerNode& LiveNodeList::rootNode() const 34 LiveNodeList::LiveNodeList(ContainerNode& ownerNode, Type type, NodeListInvalidationType invalidationType, NodeListRootType rootType) 35 : m_ownerNode(ownerNode) 36 , m_rootType(rootType) 37 , m_invalidationType(invalidationType) 38 , m_type(static_cast<unsigned>(type)) 35 39 { 36 if (isRootedAtDocument() && ownerNode().inDocument()) 37 return ownerNode().document(); 38 39 return ownerNode(); 40 ASSERT(m_rootType == static_cast<unsigned>(rootType)); 41 ASSERT(m_invalidationType == static_cast<unsigned>(invalidationType)); 42 ASSERT(m_type == static_cast<unsigned>(type)); 40 43 } 41 44 42 template <class NodeListType> 43 inline bool isMatchingElement(const NodeListType*, Element*); 44 45 template <> inline bool isMatchingElement(const LiveNodeList* nodeList, Element* element) 45 LiveNodeList::~LiveNodeList() 46 46 { 47 return nodeList->nodeMatches(element);48 47 } 49 48 50 template <> inline bool isMatchingElement(const HTMLTagNodeList* nodeList, Element* element)51 {52 return nodeList->nodeMatchesInlined(element);53 }54 55 template <> inline bool isMatchingElement(const ClassNodeList* nodeList, Element* element)56 {57 return nodeList->nodeMatchesInlined(element);58 }59 60 template <class NodeListType>61 inline Element* firstMatchingElement(const NodeListType* nodeList, ContainerNode& root)62 {63 Element* element = ElementTraversal::firstWithin(&root);64 while (element && !isMatchingElement(nodeList, element))65 element = ElementTraversal::next(element, &root);66 return element;67 }68 69 template <class NodeListType>70 inline Element* lastMatchingElement(const NodeListType* nodeList, ContainerNode& root)71 {72 Element* element = ElementTraversal::lastWithin(&root);73 while (element && !isMatchingElement(nodeList, element))74 element = ElementTraversal::previous(element, &root);75 return element;76 }77 78 template <class NodeListType>79 inline Element* nextMatchingElement(const NodeListType* nodeList, Element* current, ContainerNode& root)80 {81 do {82 current = ElementTraversal::next(current, &root);83 } while (current && !isMatchingElement(nodeList, current));84 return current;85 }86 87 template <class NodeListType>88 inline Element* previousMatchingElement(const NodeListType* nodeList, Element* current, ContainerNode& root)89 {90 do {91 current = ElementTraversal::previous(current, &root);92 } while (current && !isMatchingElement(nodeList, current));93 return current;94 }95 96 template <class NodeListType>97 inline Element* traverseMatchingElementsForward(const NodeListType* nodeList, Element& current, unsigned count, unsigned& traversedCount, ContainerNode& root)98 {99 Element* element = ¤t;100 for (traversedCount = 0; traversedCount < count; ++traversedCount) {101 element = nextMatchingElement(nodeList, element, root);102 if (!element)103 return nullptr;104 }105 return element;106 }107 108 template <class NodeListType>109 inline Element* traverseMatchingElementsBackward(const NodeListType* nodeList, Element& current, unsigned count, ContainerNode& root)110 {111 Element* element = ¤t;112 for (; count; --count) {113 element = previousMatchingElement(nodeList, element, root);114 if (!element)115 return nullptr;116 }117 return element;118 }119 120 Element* LiveNodeList::collectionFirst() const121 {122 auto& root = rootNode();123 if (type() == Type::HTMLTagNodeListType)124 return firstMatchingElement(static_cast<const HTMLTagNodeList*>(this), root);125 if (type() == Type::ClassNodeListType)126 return firstMatchingElement(static_cast<const ClassNodeList*>(this), root);127 return firstMatchingElement(static_cast<const LiveNodeList*>(this), root);128 }129 130 Element* LiveNodeList::collectionLast() const131 {132 auto& root = rootNode();133 if (type() == Type::HTMLTagNodeListType)134 return lastMatchingElement(static_cast<const HTMLTagNodeList*>(this), root);135 if (type() == Type::ClassNodeListType)136 return lastMatchingElement(static_cast<const ClassNodeList*>(this), root);137 return lastMatchingElement(static_cast<const LiveNodeList*>(this), root);138 }139 140 Element* LiveNodeList::collectionTraverseForward(Element& current, unsigned count, unsigned& traversedCount) const141 {142 auto& root = rootNode();143 if (type() == Type::HTMLTagNodeListType)144 return traverseMatchingElementsForward(static_cast<const HTMLTagNodeList*>(this), current, count, traversedCount, root);145 if (type() == Type::ClassNodeListType)146 return traverseMatchingElementsForward(static_cast<const ClassNodeList*>(this), current, count, traversedCount, root);147 return traverseMatchingElementsForward(static_cast<const LiveNodeList*>(this), current, count, traversedCount, root);148 }149 150 Element* LiveNodeList::collectionTraverseBackward(Element& current, unsigned count) const151 {152 auto& root = rootNode();153 if (type() == Type::HTMLTagNodeListType)154 return traverseMatchingElementsBackward(static_cast<const HTMLTagNodeList*>(this), current, count, root);155 if (type() == Type::ClassNodeListType)156 return traverseMatchingElementsBackward(static_cast<const ClassNodeList*>(this), current, count, root);157 return traverseMatchingElementsBackward(static_cast<const LiveNodeList*>(this), current, count, root);158 }159 160 unsigned LiveNodeList::length() const161 {162 return m_indexCache.nodeCount(*this);163 }164 165 Node* LiveNodeList::item(unsigned offset) const166 {167 return m_indexCache.nodeAt(*this, offset);168 }169 170 size_t LiveNodeList::memoryCost() const171 {172 return m_indexCache.memoryCost();173 }174 175 void LiveNodeList::invalidateCache(Document& document) const176 {177 if (!m_indexCache.hasValidCache())178 return;179 document.unregisterNodeList(const_cast<LiveNodeList&>(*this));180 m_indexCache.invalidate();181 }182 49 183 50 Node* LiveNodeList::namedItem(const AtomicString& elementId) const … … 191 58 return element; 192 59 if (!element) 193 return 0;60 return nullptr; 194 61 // In the case of multiple nodes with the same name, just fall through. 195 62 } … … 206 73 } 207 74 208 return 0;75 return nullptr; 209 76 } 210 77 -
trunk/Source/WebCore/dom/LiveNodeList.h
r165103 r166369 28 28 #include "CollectionType.h" 29 29 #include "Document.h" 30 #include "ElementTraversal.h" 30 31 #include "HTMLNames.h" 31 32 #include "NodeList.h" … … 55 56 }; 56 57 57 LiveNodeList(ContainerNode& ownerNode, Type type, NodeListInvalidationType invalidationType, NodeListRootType rootType = NodeListIsRootedAtNode) 58 : m_ownerNode(ownerNode) 59 , m_rootType(rootType) 60 , m_invalidationType(invalidationType) 61 , m_type(static_cast<unsigned>(type)) 62 { 63 ASSERT(m_rootType == static_cast<unsigned>(rootType)); 64 ASSERT(m_invalidationType == static_cast<unsigned>(invalidationType)); 65 ASSERT(m_type == static_cast<unsigned>(type)); 66 } 58 LiveNodeList(ContainerNode& ownerNode, Type, NodeListInvalidationType, NodeListRootType); 67 59 virtual Node* namedItem(const AtomicString&) const override final; 68 60 virtual bool nodeMatches(Element*) const = 0; 69 61 70 virtual ~LiveNodeList() 71 { 72 if (m_indexCache.hasValidCache()) 73 document().unregisterNodeList(*this); 74 } 75 76 // DOM API 77 virtual unsigned length() const override final; 78 virtual Node* item(unsigned offset) const override final; 79 virtual size_t memoryCost() const override; 62 virtual ~LiveNodeList(); 80 63 81 64 ALWAYS_INLINE bool isRootedAtDocument() const { return m_rootType == NodeListIsRootedAtDocument; } … … 83 66 ALWAYS_INLINE Type type() const { return static_cast<Type>(m_type); } 84 67 ContainerNode& ownerNode() const { return const_cast<ContainerNode&>(m_ownerNode.get()); } 85 ALWAYS_INLINE void invalidateCache (const QualifiedName* attrName) const68 ALWAYS_INLINE void invalidateCacheForAttribute(const QualifiedName* attrName) const 86 69 { 87 70 if (!attrName || shouldInvalidateTypeOnAttributeChange(invalidationType(), *attrName)) 88 71 invalidateCache(document()); 89 72 } 90 void invalidateCache(Document&) const; 73 virtual void invalidateCache(Document&) const = 0; 74 75 protected: 76 Document& document() const { return m_ownerNode->document(); } 77 ContainerNode& rootNode() const; 78 79 ALWAYS_INLINE NodeListRootType rootType() const { return static_cast<NodeListRootType>(m_rootType); } 80 81 private: 82 virtual bool isLiveNodeList() const override { return true; } 83 84 Element* iterateForPreviousElement(Element* current) const; 85 86 Ref<ContainerNode> m_ownerNode; 87 88 const unsigned m_rootType : 1; 89 const unsigned m_invalidationType : 4; 90 const unsigned m_type : 3; 91 }; 92 93 template <class NodeListType> 94 class CachedLiveNodeList : public LiveNodeList { 95 public: 96 virtual ~CachedLiveNodeList(); 97 98 virtual unsigned length() const override final; 99 virtual Node* item(unsigned offset) const override final; 91 100 92 101 // For CollectionIndexCache … … 96 105 Element* collectionTraverseBackward(Element&, unsigned count) const; 97 106 bool collectionCanTraverseBackward() const { return true; } 98 void willValidateIndexCache() const { document().registerNodeList(const_cast<LiveNodeList&>(*this)); } 107 void willValidateIndexCache() const; 108 109 virtual void invalidateCache(Document&) const; 110 virtual size_t memoryCost() const override; 99 111 100 112 protected: 101 Document& document() const { return m_ownerNode->document(); } 102 ContainerNode& rootNode() const; 103 104 ALWAYS_INLINE NodeListRootType rootType() const { return static_cast<NodeListRootType>(m_rootType); } 113 CachedLiveNodeList(ContainerNode& rootNode, Type, NodeListInvalidationType, NodeListRootType = NodeListIsRootedAtNode); 105 114 106 115 private: 107 virtual bool isLiveNodeList() const override { return true; } 108 109 Element* iterateForPreviousElement(Element* current) const; 110 111 Ref<ContainerNode> m_ownerNode; 112 113 mutable CollectionIndexCache<LiveNodeList, Element> m_indexCache; 114 115 const unsigned m_rootType : 1; 116 const unsigned m_invalidationType : 4; 117 const unsigned m_type : 3; 116 mutable CollectionIndexCache<NodeListType, Element> m_indexCache; 118 117 }; 119 118 … … 142 141 } 143 142 143 inline ContainerNode& LiveNodeList::rootNode() const 144 { 145 if (isRootedAtDocument() && ownerNode().inDocument()) 146 return ownerNode().document(); 147 148 return ownerNode(); 149 } 150 151 template <class NodeListType> 152 CachedLiveNodeList<NodeListType>::CachedLiveNodeList(ContainerNode& ownerNode, Type type, NodeListInvalidationType invalidationType, NodeListRootType rootType) 153 : LiveNodeList(ownerNode, type, invalidationType, rootType) 154 { 155 } 156 157 template <class NodeListType> 158 CachedLiveNodeList<NodeListType>::~CachedLiveNodeList() 159 { 160 if (m_indexCache.hasValidCache()) 161 document().unregisterNodeList(*this); 162 } 163 164 template <class NodeListType> 165 Element* CachedLiveNodeList<NodeListType>::collectionFirst() const 166 { 167 auto& root = rootNode(); 168 Element* element = ElementTraversal::firstWithin(&root); 169 while (element && !static_cast<const NodeListType*>(this)->nodeMatches(element)) 170 element = ElementTraversal::next(element, &root); 171 return element; 172 } 173 174 template <class NodeListType> 175 Element* CachedLiveNodeList<NodeListType>::collectionLast() const 176 { 177 auto& root = rootNode(); 178 Element* element = ElementTraversal::lastWithin(&root); 179 while (element && !static_cast<const NodeListType*>(this)->nodeMatches(element)) 180 element = ElementTraversal::previous(element, &root); 181 return element; 182 } 183 184 template <class NodeListType> 185 inline Element* nextMatchingElement(const NodeListType* nodeList, Element* current, ContainerNode& root) 186 { 187 do { 188 current = ElementTraversal::next(current, &root); 189 } while (current && !static_cast<const NodeListType*>(nodeList)->nodeMatches(current)); 190 return current; 191 } 192 193 template <class NodeListType> 194 Element* CachedLiveNodeList<NodeListType>::collectionTraverseForward(Element& current, unsigned count, unsigned& traversedCount) const 195 { 196 auto& root = rootNode(); 197 Element* element = ¤t; 198 for (traversedCount = 0; traversedCount < count; ++traversedCount) { 199 element = nextMatchingElement(static_cast<const NodeListType*>(this), element, root); 200 if (!element) 201 return nullptr; 202 } 203 return element; 204 } 205 206 template <class NodeListType> 207 inline Element* previousMatchingElement(const NodeListType* nodeList, Element* current, ContainerNode& root) 208 { 209 do { 210 current = ElementTraversal::previous(current, &root); 211 } while (current && !nodeList->nodeMatches(current)); 212 return current; 213 } 214 215 template <class NodeListType> 216 Element* CachedLiveNodeList<NodeListType>::collectionTraverseBackward(Element& current, unsigned count) const 217 { 218 auto& root = rootNode(); 219 Element* element = ¤t; 220 for (; count; --count) { 221 element = previousMatchingElement(static_cast<const NodeListType*>(this), element, root); 222 if (!element) 223 return nullptr; 224 } 225 return element; 226 } 227 template <class NodeListType> 228 void CachedLiveNodeList<NodeListType>::willValidateIndexCache() const 229 { 230 document().registerNodeList(const_cast<NodeListType&>(static_cast<const NodeListType&>(*this))); 231 } 232 233 template <class NodeListType> 234 void CachedLiveNodeList<NodeListType>::invalidateCache(Document& document) const 235 { 236 if (!m_indexCache.hasValidCache()) 237 return; 238 document.unregisterNodeList(const_cast<NodeListType&>(static_cast<const NodeListType&>(*this))); 239 m_indexCache.invalidate(); 240 } 241 242 template <class NodeListType> 243 unsigned CachedLiveNodeList<NodeListType>::length() const 244 { 245 return m_indexCache.nodeCount(static_cast<const NodeListType&>(*this)); 246 } 247 248 template <class NodeListType> 249 Node* CachedLiveNodeList<NodeListType>::item(unsigned offset) const 250 { 251 return m_indexCache.nodeAt(static_cast<const NodeListType&>(*this), offset); 252 } 253 254 template <class NodeListType> 255 size_t CachedLiveNodeList<NodeListType>::memoryCost() const 256 { 257 return m_indexCache.memoryCost(); 258 } 259 144 260 } // namespace WebCore 145 261 -
trunk/Source/WebCore/dom/NameNodeList.cpp
r164654 r166369 31 31 32 32 NameNodeList::NameNodeList(ContainerNode& rootNode, const AtomicString& name) 33 : LiveNodeList(rootNode, Type::NameNodeListType, InvalidateOnNameAttrChange)33 : CachedLiveNodeList(rootNode, Type::NameNodeListType, InvalidateOnNameAttrChange) 34 34 , m_name(name) 35 35 { -
trunk/Source/WebCore/dom/NameNodeList.h
r164654 r166369 32 32 33 33 // NodeList which lists all Nodes in a Element with a given "name" attribute 34 class NameNodeList : public LiveNodeList{34 class NameNodeList final : public CachedLiveNodeList<NameNodeList> { 35 35 public: 36 36 static PassRefPtr<NameNodeList> create(ContainerNode& rootNode, Type type, const AtomicString& name) … … 42 42 virtual ~NameNodeList(); 43 43 44 virtual bool nodeMatches(Element*) const override; 45 44 46 private: 45 47 NameNodeList(ContainerNode& rootNode, const AtomicString& name); 46 47 virtual bool nodeMatches(Element*) const override;48 48 49 49 AtomicString m_name; -
trunk/Source/WebCore/dom/Node.cpp
r165607 r166369 727 727 HashSet<LiveNodeList*> lists = std::move(m_listsInvalidatedAtDocument); 728 728 for (auto* list : lists) 729 list->invalidateCache (attrName);729 list->invalidateCacheForAttribute(attrName); 730 730 HashSet<HTMLCollection*> collections = std::move(m_collectionsInvalidatedAtDocument); 731 731 for (auto* collection : collections) … … 1686 1686 { 1687 1687 for (auto& atomicName : m_atomicNameCaches) 1688 atomicName.value->invalidateCache (attrName);1688 atomicName.value->invalidateCacheForAttribute(attrName); 1689 1689 1690 1690 for (auto& name : m_nameCaches) 1691 name.value->invalidateCache (attrName);1691 name.value->invalidateCacheForAttribute(attrName); 1692 1692 1693 1693 for (auto& collection : m_cachedCollections) … … 1698 1698 1699 1699 for (auto& tagNodeList : m_tagNodeListCacheNS) 1700 tagNodeList.value->invalidateCache (nullptr);1700 tagNodeList.value->invalidateCacheForAttribute(nullptr); 1701 1701 } 1702 1702 -
trunk/Source/WebCore/dom/TagNodeList.cpp
r164654 r166369 29 29 namespace WebCore { 30 30 31 TagNodeList::TagNodeList(ContainerNode& rootNode, Type type,const AtomicString& namespaceURI, const AtomicString& localName)32 : LiveNodeList(rootNode, type, DoNotInvalidateOnAttributeChanges)31 TagNodeList::TagNodeList(ContainerNode& rootNode, const AtomicString& namespaceURI, const AtomicString& localName) 32 : CachedLiveNodeList(rootNode, Type::TagNodeListType, DoNotInvalidateOnAttributeChanges) 33 33 , m_namespaceURI(namespaceURI) 34 34 , m_localName(localName) … … 45 45 } 46 46 47 bool TagNodeList::nodeMatches(Element* testNode) const48 {49 // Implements http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-getelementsbytagnamens50 if (m_localName != starAtom && m_localName != testNode->localName())51 return false;52 53 return m_namespaceURI == starAtom || m_namespaceURI == testNode->namespaceURI();54 }55 56 47 HTMLTagNodeList::HTMLTagNodeList(ContainerNode& rootNode, const AtomicString& localName) 57 : TagNodeList(rootNode, Type::HTMLTagNodeListType, starAtom, localName) 48 : CachedLiveNodeList(rootNode, Type::HTMLTagNodeListType, DoNotInvalidateOnAttributeChanges) 49 , m_localName(localName) 58 50 , m_loweredLocalName(localName.lower()) 59 51 { 60 52 } 61 53 62 bool HTMLTagNodeList::nodeMatches(Element* testNode) const 54 HTMLTagNodeList::~HTMLTagNodeList() 63 55 { 64 return nodeMatchesInlined(testNode);56 ownerNode().nodeLists()->removeCacheWithAtomicName(this, m_localName); 65 57 } 66 58 -
trunk/Source/WebCore/dom/TagNodeList.h
r164654 r166369 32 32 33 33 // NodeList that limits to a particular tag. 34 class TagNodeList : public LiveNodeList{34 class TagNodeList final : public CachedLiveNodeList<TagNodeList> { 35 35 public: 36 36 static PassRefPtr<TagNodeList> create(ContainerNode& rootNode, const AtomicString& namespaceURI, const AtomicString& localName) 37 37 { 38 38 ASSERT(namespaceURI != starAtom); 39 return adoptRef(new TagNodeList(rootNode, Type::TagNodeListType,namespaceURI, localName));39 return adoptRef(new TagNodeList(rootNode, namespaceURI, localName)); 40 40 } 41 41 … … 43 43 { 44 44 ASSERT_UNUSED(type, type == Type::TagNodeListType); 45 return adoptRef(new TagNodeList(rootNode, Type::TagNodeListType,starAtom, localName));45 return adoptRef(new TagNodeList(rootNode, starAtom, localName)); 46 46 } 47 47 48 48 virtual ~TagNodeList(); 49 49 50 virtual bool nodeMatches(Element*) const override; 51 50 52 protected: 51 TagNodeList(ContainerNode& rootNode, Type, const AtomicString& namespaceURI, const AtomicString& localName); 52 53 virtual bool nodeMatches(Element*) const override; 53 TagNodeList(ContainerNode& rootNode, const AtomicString& namespaceURI, const AtomicString& localName); 54 54 55 55 AtomicString m_namespaceURI; … … 57 57 }; 58 58 59 class HTMLTagNodeList : public TagNodeList { 59 inline bool TagNodeList::nodeMatches(Element* element) const 60 { 61 // Implements http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-getelementsbytagnamens 62 if (m_localName != starAtom && m_localName != element->localName()) 63 return false; 64 65 return m_namespaceURI == starAtom || m_namespaceURI == element->namespaceURI(); 66 } 67 68 class HTMLTagNodeList final : public CachedLiveNodeList<HTMLTagNodeList> { 60 69 public: 61 70 static PassRefPtr<HTMLTagNodeList> create(ContainerNode& rootNode, Type type, const AtomicString& localName) … … 65 74 } 66 75 67 bool nodeMatchesInlined(Element*) const; 76 virtual ~HTMLTagNodeList(); 77 78 virtual bool nodeMatches(Element*) const override; 68 79 69 80 private: 70 81 HTMLTagNodeList(ContainerNode& rootNode, const AtomicString& localName); 71 82 72 virtual bool nodeMatches(Element*) const override; 73 83 AtomicString m_localName; 74 84 AtomicString m_loweredLocalName; 75 85 }; 76 86 77 inline bool HTMLTagNodeList::nodeMatches Inlined(Element* testNode) const87 inline bool HTMLTagNodeList::nodeMatches(Element* element) const 78 88 { 79 89 // Implements http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-getelementsbytagname 80 if (m_localName != starAtom) { 81 const AtomicString& localName = testNode->isHTMLElement() ? m_loweredLocalName : m_localName; 82 if (localName != testNode->localName()) 83 return false; 84 } 85 ASSERT(m_namespaceURI == starAtom); 86 return true; 90 if (m_localName == starAtom) 91 return true; 92 const AtomicString& localName = element->isHTMLElement() ? m_loweredLocalName : m_localName; 93 return localName == element->localName(); 87 94 } 88 95 -
trunk/Source/WebCore/html/LabelsNodeList.cpp
r164654 r166369 35 35 36 36 LabelsNodeList::LabelsNodeList(LabelableElement& forNode) 37 : LiveNodeList(forNode, Type::LabelsNodeListType, InvalidateOnForAttrChange, NodeListIsRootedAtDocument)37 : CachedLiveNodeList(forNode, Type::LabelsNodeListType, InvalidateOnForAttrChange, NodeListIsRootedAtDocument) 38 38 { 39 39 } -
trunk/Source/WebCore/html/LabelsNodeList.h
r164654 r166369 31 31 namespace WebCore { 32 32 33 class LabelsNodeList final : public LiveNodeList{33 class LabelsNodeList final : public CachedLiveNodeList<LabelsNodeList> { 34 34 public: 35 35 static PassRef<LabelsNodeList> create(LabelableElement& forNode, Type type, const AtomicString&) … … 40 40 ~LabelsNodeList(); 41 41 42 protected: 42 virtual bool nodeMatches(Element*) const override; 43 44 private: 43 45 explicit LabelsNodeList(LabelableElement& forNode); 44 45 virtual bool nodeMatches(Element*) const override;46 46 }; 47 47 -
trunk/Source/WebCore/html/RadioNodeList.cpp
r164654 r166369 39 39 40 40 RadioNodeList::RadioNodeList(ContainerNode& rootNode, const AtomicString& name) 41 : LiveNodeList(rootNode, Type::RadioNodeListType, InvalidateForFormControls, isHTMLFormElement(rootNode) ? NodeListIsRootedAtDocument : NodeListIsRootedAtNode)41 : CachedLiveNodeList(rootNode, Type::RadioNodeListType, InvalidateForFormControls, isHTMLFormElement(rootNode) ? NodeListIsRootedAtDocument : NodeListIsRootedAtNode) 42 42 , m_name(name) 43 43 { -
trunk/Source/WebCore/html/RadioNodeList.h
r164654 r166369 33 33 namespace WebCore { 34 34 35 class RadioNodeList : public LiveNodeList{35 class RadioNodeList final : public CachedLiveNodeList<RadioNodeList> { 36 36 public: 37 37 static PassRefPtr<RadioNodeList> create(ContainerNode& rootNode, Type type, const AtomicString& name) … … 46 46 void setValue(const String&); 47 47 48 protected:49 48 virtual bool nodeMatches(Element*) const override; 50 49
Note:
See TracChangeset
for help on using the changeset viewer.