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 |