Index: Source/core/html/HTMLCollection.cpp |
diff --git a/Source/core/html/HTMLCollection.cpp b/Source/core/html/HTMLCollection.cpp |
index c621ed715d386428a80f229fa8ebad085ba9e2a2..e3c01c9a1607b704c995286a8f063870c3ff5b44 100644 |
--- a/Source/core/html/HTMLCollection.cpp |
+++ b/Source/core/html/HTMLCollection.cpp |
@@ -179,6 +179,12 @@ HTMLCollection::~HTMLCollection() |
ownerNode()->nodeLists()->removeCacheWithAtomicName(this, type()); |
} |
+void HTMLCollection::invalidateCache() const |
+{ |
+ LiveNodeListBase::invalidateCache(); |
+ invalidateIdNameCacheMaps(); |
+} |
+ |
template <class NodeListType> |
inline bool isMatchingElement(const NodeListType*, Element*); |
@@ -392,16 +398,6 @@ bool ALWAYS_INLINE LiveNodeListBase::isFirstItemCloserThanCachedItem(unsigned of |
return offset < distanceFromCachedItem; |
} |
-ALWAYS_INLINE void LiveNodeListBase::setItemCache(Node* item, unsigned offset, unsigned elementsArrayOffset) const |
-{ |
- setItemCache(item, offset); |
- if (overridesItemAfter()) { |
- ASSERT_WITH_SECURITY_IMPLICATION(item->isElementNode()); |
- static_cast<const HTMLCollection*>(this)->m_cachedElementsArrayOffset = elementsArrayOffset; |
- } else |
- ASSERT(!elementsArrayOffset); |
-} |
- |
unsigned LiveNodeListBase::length() const |
{ |
if (isLengthCacheValid()) |
@@ -432,22 +428,21 @@ Node* LiveNodeListBase::item(unsigned offset) const |
if (isLengthCacheValid() && !overridesItemAfter() && isLastItemCloserThanLastOrCachedItem(offset)) { |
Node* lastItem = itemBefore(0); |
ASSERT(lastItem); |
- setItemCache(lastItem, cachedLength() - 1, 0); |
+ setItemCache(lastItem, cachedLength() - 1); |
} else if (!isItemCacheValid() || isFirstItemCloserThanCachedItem(offset) || (overridesItemAfter() && offset < cachedItemOffset())) { |
- unsigned offsetInArray = 0; |
Node* firstItem; |
if (type() == ChildNodeListType) |
firstItem = root->firstChild(); |
else if (isNodeList(type())) |
firstItem = traverseLiveNodeListFirstElement(*root); |
else |
- firstItem = static_cast<const HTMLCollection*>(this)->traverseFirstElement(offsetInArray, *root); |
+ firstItem = static_cast<const HTMLCollection*>(this)->traverseFirstElement(*root); |
if (!firstItem) { |
setLengthCache(0); |
return 0; |
} |
- setItemCache(firstItem, 0, offsetInArray); |
+ setItemCache(firstItem, 0); |
ASSERT(!cachedItemOffset()); |
} |
@@ -470,7 +465,7 @@ inline Node* LiveNodeListBase::itemBeforeOrAfterCachedItem(unsigned offset, Cont |
ASSERT(currentOffset); |
currentOffset--; |
if (currentOffset == offset) { |
- setItemCache(currentItem, currentOffset, 0); |
+ setItemCache(currentItem, currentOffset); |
return currentItem; |
} |
} |
@@ -478,24 +473,23 @@ inline Node* LiveNodeListBase::itemBeforeOrAfterCachedItem(unsigned offset, Cont |
return 0; |
} |
- unsigned offsetInArray = 0; |
if (type() == ChildNodeListType) |
currentItem = traverseChildNodeListForwardToOffset(offset, currentItem, currentOffset); |
else if (isNodeList(type())) |
currentItem = traverseLiveNodeListForwardToOffset(offset, toElement(*currentItem), currentOffset, root); |
else |
- currentItem = static_cast<const HTMLCollection*>(this)->traverseForwardToOffset(offset, toElement(*currentItem), currentOffset, offsetInArray, root); |
+ currentItem = static_cast<const HTMLCollection*>(this)->traverseForwardToOffset(offset, toElement(*currentItem), currentOffset, root); |
if (!currentItem) { |
// Did not find the item. On plus side, we now know the length. |
setLengthCache(currentOffset + 1); |
return 0; |
} |
- setItemCache(currentItem, currentOffset, offsetInArray); |
+ setItemCache(currentItem, currentOffset); |
return currentItem; |
} |
-Element* HTMLCollection::virtualItemAfter(unsigned&, Element*) const |
+Element* HTMLCollection::virtualItemAfter(Element*) const |
{ |
ASSERT_NOT_REACHED(); |
return 0; |
@@ -546,33 +540,30 @@ inline Element* nextMatchingChildElement(const HTMLCollection* nodeList, Element |
return next; |
} |
-inline Element* HTMLCollection::traverseFirstElement(unsigned& offsetInArray, ContainerNode& root) const |
+inline Element* HTMLCollection::traverseFirstElement(ContainerNode& root) const |
{ |
if (overridesItemAfter()) |
- return virtualItemAfter(offsetInArray, 0); |
- ASSERT(!offsetInArray); |
+ return virtualItemAfter(0); |
if (shouldOnlyIncludeDirectChildren()) |
return firstMatchingChildElement(static_cast<const HTMLCollection*>(this), root); |
return firstMatchingElement(static_cast<const HTMLCollection*>(this), root); |
} |
-inline Element* HTMLCollection::traverseNextElement(unsigned& offsetInArray, Element& previous, ContainerNode* root) const |
+inline Element* HTMLCollection::traverseNextElement(Element& previous, ContainerNode* root) const |
{ |
if (overridesItemAfter()) |
- return virtualItemAfter(offsetInArray, &previous); |
- ASSERT(!offsetInArray); |
+ return virtualItemAfter(&previous); |
if (shouldOnlyIncludeDirectChildren()) |
return nextMatchingChildElement(this, previous, root); |
return nextMatchingElement(this, previous, root); |
} |
-inline Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element& currentElement, unsigned& currentOffset, unsigned& offsetInArray, ContainerNode* root) const |
+inline Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element& currentElement, unsigned& currentOffset, ContainerNode* root) const |
{ |
ASSERT(currentOffset < offset); |
if (overridesItemAfter()) { |
- offsetInArray = m_cachedElementsArrayOffset; |
Element* next = ¤tElement; |
- while ((next = virtualItemAfter(offsetInArray, next))) { |
+ while ((next = virtualItemAfter(next))) { |
if (++currentOffset == offset) |
return next; |
} |
@@ -601,20 +592,19 @@ Node* HTMLCollection::namedItem(const AtomicString& name) const |
if (!root) |
return 0; |
- unsigned arrayOffset = 0; |
unsigned i = 0; |
- for (Element* element = traverseFirstElement(arrayOffset, *root); element; element = traverseNextElement(arrayOffset, *element, root)) { |
+ for (Element* element = traverseFirstElement(*root); element; element = traverseNextElement(*element, root)) { |
if (checkForNameMatch(element, /* checkName */ false, name)) { |
- setItemCache(element, i, arrayOffset); |
+ setItemCache(element, i); |
return element; |
} |
i++; |
} |
i = 0; |
- for (Element* element = traverseFirstElement(arrayOffset, *root); element; element = traverseNextElement(arrayOffset, *element, root)) { |
+ for (Element* element = traverseFirstElement(*root); element; element = traverseNextElement(*element, root)) { |
if (checkForNameMatch(element, /* checkName */ true, name)) { |
- setItemCache(element, i, arrayOffset); |
+ setItemCache(element, i); |
return element; |
} |
i++; |
@@ -632,8 +622,7 @@ void HTMLCollection::updateNameCache() const |
if (!root) |
return; |
- unsigned arrayOffset = 0; |
- for (Element* element = traverseFirstElement(arrayOffset, *root); element; element = traverseNextElement(arrayOffset, *element, root)) { |
+ for (Element* element = traverseFirstElement(*root); element; element = traverseNextElement(*element, root)) { |
const AtomicString& idAttrVal = element->getIdAttribute(); |
if (!idAttrVal.isEmpty()) |
appendIdCache(idAttrVal, element); |