| Index: Source/core/html/HTMLCollection.cpp
|
| diff --git a/Source/core/html/HTMLCollection.cpp b/Source/core/html/HTMLCollection.cpp
|
| index 74a2ccf0becf9cf5c154c9dea46a34c189ff9430..681cbb5f9434b9b2411bb97d712d3641cc5a49e4 100644
|
| --- a/Source/core/html/HTMLCollection.cpp
|
| +++ b/Source/core/html/HTMLCollection.cpp
|
| @@ -182,7 +182,7 @@ HTMLCollection::~HTMLCollection()
|
|
|
| void HTMLCollection::invalidateCache() const
|
| {
|
| - LiveNodeListBase::invalidateCache();
|
| + m_collectionIndexCache.invalidate();
|
| invalidateIdNameCacheMaps();
|
| }
|
|
|
| @@ -299,7 +299,7 @@ ALWAYS_INLINE Node* LiveNodeListBase::iterateForPreviousNode(Node* current) cons
|
| return 0;
|
| }
|
|
|
| -ALWAYS_INLINE Node* LiveNodeListBase::itemBefore(const Node* previous) const
|
| +Node* LiveNodeListBase::itemBefore(const Node* previous) const
|
| {
|
| Node* current;
|
| if (LIKELY(!!previous)) // Without this LIKELY, length() and item() can be 10% slower.
|
| @@ -356,7 +356,7 @@ static inline Node* traverseSiblingsForwardToOffset(unsigned offset, Node& curre
|
|
|
| // FIXME: This should be in LiveNodeList.cpp but it needs to stay here until firstMatchingElement()
|
| // and others are moved to a separate header.
|
| -inline Node* LiveNodeList::traverseToFirstElement(const ContainerNode& root) const
|
| +Node* LiveNodeList::traverseToFirstElement(const ContainerNode& root) const
|
| {
|
| ASSERT(isLiveNodeListType(type()));
|
| switch (type()) {
|
| @@ -373,7 +373,7 @@ inline Node* LiveNodeList::traverseToFirstElement(const ContainerNode& root) con
|
|
|
| // FIXME: This should be in LiveNodeList.cpp but it needs to stay here until traverseMatchingElementsForwardToOffset()
|
| // and others are moved to a separate header.
|
| -inline Node* LiveNodeList::traverseForwardToOffset(unsigned offset, Node& currentNode, unsigned& currentOffset, const ContainerNode& root) const
|
| +Node* LiveNodeList::traverseForwardToOffset(unsigned offset, Node& currentNode, unsigned& currentOffset, const ContainerNode& root) const
|
| {
|
| switch (type()) {
|
| case ChildNodeListType:
|
| @@ -387,106 +387,6 @@ inline Node* LiveNodeList::traverseForwardToOffset(unsigned offset, Node& curren
|
| }
|
| }
|
|
|
| -bool ALWAYS_INLINE LiveNodeListBase::isLastItemCloserThanLastOrCachedItem(unsigned offset) const
|
| -{
|
| - ASSERT(isLengthCacheValid());
|
| - unsigned distanceFromLastItem = cachedLength() - offset;
|
| - if (!cachedItem())
|
| - return distanceFromLastItem < offset;
|
| -
|
| - return cachedItemOffset() < offset && distanceFromLastItem < offset - cachedItemOffset();
|
| -}
|
| -
|
| -bool ALWAYS_INLINE LiveNodeListBase::isFirstItemCloserThanCachedItem(unsigned offset) const
|
| -{
|
| - if (cachedItemOffset() < offset)
|
| - return false;
|
| -
|
| - unsigned distanceFromCachedItem = cachedItemOffset() - offset;
|
| - return offset < distanceFromCachedItem;
|
| -}
|
| -
|
| -unsigned LiveNodeListBase::length() const
|
| -{
|
| - if (isLengthCacheValid())
|
| - return cachedLength();
|
| -
|
| - item(UINT_MAX);
|
| - ASSERT(isLengthCacheValid());
|
| -
|
| - return cachedLength();
|
| -}
|
| -
|
| -// FIXME: It is silly that these functions are in HTMLCollection.cpp.
|
| -Node* LiveNodeListBase::item(unsigned offset) const
|
| -{
|
| - if (cachedItem() && cachedItemOffset() == offset)
|
| - return cachedItem();
|
| -
|
| - if (isLengthCacheValid() && cachedLength() <= offset)
|
| - return 0;
|
| -
|
| - ContainerNode& root = rootNode();
|
| - if (isLengthCacheValid() && !overridesItemAfter() && isLastItemCloserThanLastOrCachedItem(offset)) {
|
| - Node* lastItem = itemBefore(0);
|
| - ASSERT(lastItem);
|
| - setItemCache(lastItem, cachedLength() - 1);
|
| - } else if (!cachedItem() || isFirstItemCloserThanCachedItem(offset) || (overridesItemAfter() && offset < cachedItemOffset())) {
|
| - Node* firstItem;
|
| - if (isLiveNodeListType(type()))
|
| - firstItem = static_cast<const LiveNodeList*>(this)->traverseToFirstElement(root);
|
| - else
|
| - firstItem = static_cast<const HTMLCollection*>(this)->traverseToFirstElement(root);
|
| -
|
| - if (!firstItem) {
|
| - setLengthCache(0);
|
| - return 0;
|
| - }
|
| - setItemCache(firstItem, 0);
|
| - ASSERT(!cachedItemOffset());
|
| - }
|
| -
|
| - if (cachedItemOffset() == offset)
|
| - return cachedItem();
|
| -
|
| - return itemBeforeOrAfterCachedItem(offset, root);
|
| -}
|
| -
|
| -inline Node* LiveNodeListBase::itemBeforeOrAfterCachedItem(unsigned offset, const ContainerNode& root) const
|
| -{
|
| - unsigned currentOffset = cachedItemOffset();
|
| - Node* currentItem = cachedItem();
|
| - ASSERT(currentItem);
|
| - ASSERT(currentOffset != offset);
|
| -
|
| - if (offset < cachedItemOffset()) {
|
| - ASSERT(!overridesItemAfter());
|
| - while ((currentItem = itemBefore(currentItem))) {
|
| - ASSERT(currentOffset);
|
| - currentOffset--;
|
| - if (currentOffset == offset) {
|
| - setItemCache(currentItem, currentOffset);
|
| - return currentItem;
|
| - }
|
| - }
|
| - ASSERT_NOT_REACHED();
|
| - return 0;
|
| - }
|
| -
|
| - if (isLiveNodeListType(type()))
|
| - currentItem = static_cast<const LiveNodeList*>(this)->traverseForwardToOffset(offset, *currentItem, currentOffset, root);
|
| - else
|
| - 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);
|
| - return currentItem;
|
| -}
|
| -
|
| Element* HTMLCollection::virtualItemAfter(Element*) const
|
| {
|
| ASSERT_NOT_REACHED();
|
| @@ -538,7 +438,7 @@ inline Element* nextMatchingChildElement(const HTMLCollection& nodeList, Element
|
| return next;
|
| }
|
|
|
| -inline Element* HTMLCollection::traverseToFirstElement(const ContainerNode& root) const
|
| +Element* HTMLCollection::traverseToFirstElement(const ContainerNode& root) const
|
| {
|
| if (overridesItemAfter())
|
| return virtualItemAfter(0);
|
| @@ -556,11 +456,11 @@ inline Element* HTMLCollection::traverseNextElement(Element& previous, const Con
|
| return nextMatchingElement(*this, previous, root);
|
| }
|
|
|
| -inline Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element& currentElement, unsigned& currentOffset, const ContainerNode& root) const
|
| +Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Node& currentElement, unsigned& currentOffset, const ContainerNode& root) const
|
| {
|
| ASSERT(currentOffset < offset);
|
| if (overridesItemAfter()) {
|
| - Element* next = ¤tElement;
|
| + Element* next = &toElement(currentElement);
|
| while ((next = virtualItemAfter(next))) {
|
| if (++currentOffset == offset)
|
| return next;
|
| @@ -568,14 +468,14 @@ inline Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element
|
| return 0;
|
| }
|
| if (shouldOnlyIncludeDirectChildren()) {
|
| - Element* next = ¤tElement;
|
| + Element* next = &toElement(currentElement);
|
| while ((next = nextMatchingChildElement(*this, *next, root))) {
|
| if (++currentOffset == offset)
|
| return next;
|
| }
|
| return 0;
|
| }
|
| - return traverseMatchingElementsForwardToOffset(*this, offset, currentElement, currentOffset, root);
|
| + return traverseMatchingElementsForwardToOffset(*this, offset, toElement(currentElement), currentOffset, root);
|
| }
|
|
|
| Element* HTMLCollection::namedItem(const AtomicString& name) const
|
| @@ -590,7 +490,7 @@ Element* HTMLCollection::namedItem(const AtomicString& name) const
|
| unsigned i = 0;
|
| for (Element* element = traverseToFirstElement(root); element; element = traverseNextElement(*element, root)) {
|
| if (checkForNameMatch(*element, /* checkName */ false, name)) {
|
| - setItemCache(element, i);
|
| + m_collectionIndexCache.setCachedNode(element, i);
|
| return element;
|
| }
|
| i++;
|
| @@ -599,7 +499,7 @@ Element* HTMLCollection::namedItem(const AtomicString& name) const
|
| i = 0;
|
| for (Element* element = traverseToFirstElement(root); element; element = traverseNextElement(*element, root)) {
|
| if (checkForNameMatch(*element, /* checkName */ true, name)) {
|
| - setItemCache(element, i);
|
| + m_collectionIndexCache.setCachedNode(element, i);
|
| return element;
|
| }
|
| i++;
|
|
|