| OLD | NEW |
| 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 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All r
ights reserved. | 4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All r
ights reserved. |
| 5 * | 5 * |
| 6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
| 7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
| 8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
| 9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
| 10 * | 10 * |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 { | 280 { |
| 281 return onlyIncludeDirectChildren ? rootNode.lastChild() : lastDescendent(roo
tNode); | 281 return onlyIncludeDirectChildren ? rootNode.lastChild() : lastDescendent(roo
tNode); |
| 282 } | 282 } |
| 283 | 283 |
| 284 ALWAYS_INLINE Node* LiveNodeListBase::iterateForPreviousNode(Node* current) cons
t | 284 ALWAYS_INLINE Node* LiveNodeListBase::iterateForPreviousNode(Node* current) cons
t |
| 285 { | 285 { |
| 286 bool onlyIncludeDirectChildren = shouldOnlyIncludeDirectChildren(); | 286 bool onlyIncludeDirectChildren = shouldOnlyIncludeDirectChildren(); |
| 287 CollectionType collectionType = type(); | 287 CollectionType collectionType = type(); |
| 288 Node& rootNode = this->rootNode(); | 288 Node& rootNode = this->rootNode(); |
| 289 for (; current; current = previousNode(rootNode, *current, onlyIncludeDirect
Children)) { | 289 for (; current; current = previousNode(rootNode, *current, onlyIncludeDirect
Children)) { |
| 290 if (isNodeList(collectionType)) { | 290 if (isLiveNodeListType(collectionType)) { |
| 291 if (current->isElementNode() && isMatchingElement(static_cast<const
LiveNodeList*>(this), toElement(current))) | 291 if (current->isElementNode() && isMatchingElement(static_cast<const
LiveNodeList*>(this), toElement(current))) |
| 292 return toElement(current); | 292 return toElement(current); |
| 293 } else { | 293 } else { |
| 294 if (current->isElementNode() && isMatchingElement(static_cast<const
HTMLCollection*>(this), toElement(current))) | 294 if (current->isElementNode() && isMatchingElement(static_cast<const
HTMLCollection*>(this), toElement(current))) |
| 295 return toElement(current); | 295 return toElement(current); |
| 296 } | 296 } |
| 297 } | 297 } |
| 298 return 0; | 298 return 0; |
| 299 } | 299 } |
| 300 | 300 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 { | 335 { |
| 336 ASSERT(currentOffset < offset); | 336 ASSERT(currentOffset < offset); |
| 337 Element* next = ¤tElement; | 337 Element* next = ¤tElement; |
| 338 while ((next = nextMatchingElement(nodeList, *next, root))) { | 338 while ((next = nextMatchingElement(nodeList, *next, root))) { |
| 339 if (++currentOffset == offset) | 339 if (++currentOffset == offset) |
| 340 return next; | 340 return next; |
| 341 } | 341 } |
| 342 return 0; | 342 return 0; |
| 343 } | 343 } |
| 344 | 344 |
| 345 // FIXME: This should be in ChildNodeList | 345 static inline Node* traverseSiblingsForwardToOffset(unsigned offset, Node& curre
ntNode, unsigned& currentOffset) |
| 346 inline Node* LiveNodeListBase::traverseChildNodeListForwardToOffset(unsigned off
set, Node* currentNode, unsigned& currentOffset) const | |
| 347 { | 346 { |
| 348 ASSERT(type() == ChildNodeListType); | |
| 349 ASSERT(currentOffset < offset); | 347 ASSERT(currentOffset < offset); |
| 350 while ((currentNode = currentNode->nextSibling())) { | 348 Node* next = ¤tNode; |
| 349 while ((next = next->nextSibling())) { |
| 351 if (++currentOffset == offset) | 350 if (++currentOffset == offset) |
| 352 return currentNode; | 351 return next; |
| 353 } | 352 } |
| 354 return 0; | 353 return 0; |
| 355 } | 354 } |
| 356 | 355 |
| 357 // FIXME: This should be in LiveNodeList | 356 // FIXME: This should be in LiveNodeList |
| 358 inline Element* LiveNodeListBase::traverseLiveNodeListFirstElement(ContainerNode
& root) const | 357 inline Element* LiveNodeListBase::traverseLiveNodeListFirstElement(ContainerNode
& root) const |
| 359 { | 358 { |
| 360 ASSERT(isNodeList(type())); | 359 ASSERT(isLiveNodeListType(type())); |
| 361 ASSERT(type() != ChildNodeListType); | 360 ASSERT(type() != ChildNodeListType); |
| 362 if (type() == HTMLTagNodeListType) | 361 if (type() == HTMLTagNodeListType) |
| 363 return firstMatchingElement(static_cast<const HTMLTagNodeList*>(this), r
oot); | 362 return firstMatchingElement(static_cast<const HTMLTagNodeList*>(this), r
oot); |
| 364 if (type() == ClassNodeListType) | 363 if (type() == ClassNodeListType) |
| 365 return firstMatchingElement(static_cast<const ClassNodeList*>(this), roo
t); | 364 return firstMatchingElement(static_cast<const ClassNodeList*>(this), roo
t); |
| 366 return firstMatchingElement(static_cast<const LiveNodeList*>(this), root); | 365 return firstMatchingElement(static_cast<const LiveNodeList*>(this), root); |
| 367 } | 366 } |
| 368 | 367 |
| 369 // FIXME: This should be in LiveNodeList | 368 // FIXME: This should be in LiveNodeList.cpp but it needs to stay here until tra
verseMatchingElementsForwardToOffset() |
| 370 inline Element* LiveNodeListBase::traverseLiveNodeListForwardToOffset(unsigned o
ffset, Element& currentElement, unsigned& currentOffset, ContainerNode* root) co
nst | 369 // and others are moved to a separate header. |
| 370 inline Node* LiveNodeList::traverseForwardToOffset(unsigned offset, Node& curren
tNode, unsigned& currentOffset, ContainerNode* root) const |
| 371 { | 371 { |
| 372 ASSERT(isNodeList(type())); | 372 switch (type()) { |
| 373 ASSERT(type() != ChildNodeListType); | 373 case ChildNodeListType: |
| 374 if (type() == HTMLTagNodeListType) | 374 return traverseSiblingsForwardToOffset(offset, currentNode, currentOffse
t); |
| 375 return traverseMatchingElementsForwardToOffset(static_cast<const HTMLTag
NodeList*>(this), offset, currentElement, currentOffset, root); | 375 case HTMLTagNodeListType: |
| 376 if (type() == ClassNodeListType) | 376 return traverseMatchingElementsForwardToOffset(static_cast<const HTMLTag
NodeList*>(this), offset, toElement(currentNode), currentOffset, root); |
| 377 return traverseMatchingElementsForwardToOffset(static_cast<const ClassNo
deList*>(this), offset, currentElement, currentOffset, root); | 377 case ClassNodeListType: |
| 378 return traverseMatchingElementsForwardToOffset(static_cast<const LiveNodeLis
t*>(this), offset, currentElement, currentOffset, root); | 378 return traverseMatchingElementsForwardToOffset(static_cast<const ClassNo
deList*>(this), offset, toElement(currentNode), currentOffset, root); |
| 379 default: |
| 380 return traverseMatchingElementsForwardToOffset(this, offset, toElement(c
urrentNode), currentOffset, root); |
| 381 } |
| 379 } | 382 } |
| 380 | 383 |
| 381 bool ALWAYS_INLINE LiveNodeListBase::isLastItemCloserThanLastOrCachedItem(unsign
ed offset) const | 384 bool ALWAYS_INLINE LiveNodeListBase::isLastItemCloserThanLastOrCachedItem(unsign
ed offset) const |
| 382 { | 385 { |
| 383 ASSERT(isLengthCacheValid()); | 386 ASSERT(isLengthCacheValid()); |
| 384 unsigned distanceFromLastItem = cachedLength() - offset; | 387 unsigned distanceFromLastItem = cachedLength() - offset; |
| 385 if (!isItemCacheValid()) | 388 if (!isItemCacheValid()) |
| 386 return distanceFromLastItem < offset; | 389 return distanceFromLastItem < offset; |
| 387 | 390 |
| 388 return cachedItemOffset() < offset && distanceFromLastItem < offset - cached
ItemOffset(); | 391 return cachedItemOffset() < offset && distanceFromLastItem < offset - cached
ItemOffset(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 } | 429 } |
| 427 | 430 |
| 428 if (isLengthCacheValid() && !overridesItemAfter() && isLastItemCloserThanLas
tOrCachedItem(offset)) { | 431 if (isLengthCacheValid() && !overridesItemAfter() && isLastItemCloserThanLas
tOrCachedItem(offset)) { |
| 429 Node* lastItem = itemBefore(0); | 432 Node* lastItem = itemBefore(0); |
| 430 ASSERT(lastItem); | 433 ASSERT(lastItem); |
| 431 setItemCache(lastItem, cachedLength() - 1); | 434 setItemCache(lastItem, cachedLength() - 1); |
| 432 } else if (!isItemCacheValid() || isFirstItemCloserThanCachedItem(offset) ||
(overridesItemAfter() && offset < cachedItemOffset())) { | 435 } else if (!isItemCacheValid() || isFirstItemCloserThanCachedItem(offset) ||
(overridesItemAfter() && offset < cachedItemOffset())) { |
| 433 Node* firstItem; | 436 Node* firstItem; |
| 434 if (type() == ChildNodeListType) | 437 if (type() == ChildNodeListType) |
| 435 firstItem = root->firstChild(); | 438 firstItem = root->firstChild(); |
| 436 else if (isNodeList(type())) | 439 else if (isLiveNodeListType(type())) |
| 437 firstItem = traverseLiveNodeListFirstElement(*root); | 440 firstItem = traverseLiveNodeListFirstElement(*root); |
| 438 else | 441 else |
| 439 firstItem = static_cast<const HTMLCollection*>(this)->traverseFirstE
lement(*root); | 442 firstItem = static_cast<const HTMLCollection*>(this)->traverseFirstE
lement(*root); |
| 440 | 443 |
| 441 if (!firstItem) { | 444 if (!firstItem) { |
| 442 setLengthCache(0); | 445 setLengthCache(0); |
| 443 return 0; | 446 return 0; |
| 444 } | 447 } |
| 445 setItemCache(firstItem, 0); | 448 setItemCache(firstItem, 0); |
| 446 ASSERT(!cachedItemOffset()); | 449 ASSERT(!cachedItemOffset()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 466 currentOffset--; | 469 currentOffset--; |
| 467 if (currentOffset == offset) { | 470 if (currentOffset == offset) { |
| 468 setItemCache(currentItem, currentOffset); | 471 setItemCache(currentItem, currentOffset); |
| 469 return currentItem; | 472 return currentItem; |
| 470 } | 473 } |
| 471 } | 474 } |
| 472 ASSERT_NOT_REACHED(); | 475 ASSERT_NOT_REACHED(); |
| 473 return 0; | 476 return 0; |
| 474 } | 477 } |
| 475 | 478 |
| 476 if (type() == ChildNodeListType) | 479 if (isLiveNodeListType(type())) |
| 477 currentItem = traverseChildNodeListForwardToOffset(offset, currentItem,
currentOffset); | 480 currentItem = static_cast<const LiveNodeList*>(this)->traverseForwardToO
ffset(offset, *currentItem, currentOffset, root); |
| 478 else if (isNodeList(type())) | |
| 479 currentItem = traverseLiveNodeListForwardToOffset(offset, toElement(*cur
rentItem), currentOffset, root); | |
| 480 else | 481 else |
| 481 currentItem = static_cast<const HTMLCollection*>(this)->traverseForwardT
oOffset(offset, toElement(*currentItem), currentOffset, root); | 482 currentItem = static_cast<const HTMLCollection*>(this)->traverseForwardT
oOffset(offset, toElement(*currentItem), currentOffset, root); |
| 482 | 483 |
| 483 if (!currentItem) { | 484 if (!currentItem) { |
| 484 // Did not find the item. On plus side, we now know the length. | 485 // Did not find the item. On plus side, we now know the length. |
| 485 setLengthCache(currentOffset + 1); | 486 setLengthCache(currentOffset + 1); |
| 486 return 0; | 487 return 0; |
| 487 } | 488 } |
| 488 setItemCache(currentItem, currentOffset); | 489 setItemCache(currentItem, currentOffset); |
| 489 return currentItem; | 490 return currentItem; |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 656 | 657 |
| 657 void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element*
element) | 658 void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element*
element) |
| 658 { | 659 { |
| 659 OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->v
alue; | 660 OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->v
alue; |
| 660 if (!vector) | 661 if (!vector) |
| 661 vector = adoptPtr(new Vector<Element*>); | 662 vector = adoptPtr(new Vector<Element*>); |
| 662 vector->append(element); | 663 vector->append(element); |
| 663 } | 664 } |
| 664 | 665 |
| 665 } // namespace WebCore | 666 } // namespace WebCore |
| OLD | NEW |