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 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 { | 346 { |
347 ASSERT(currentOffset < offset); | 347 ASSERT(currentOffset < offset); |
348 Node* next = ¤tNode; | 348 Node* next = ¤tNode; |
349 while ((next = next->nextSibling())) { | 349 while ((next = next->nextSibling())) { |
350 if (++currentOffset == offset) | 350 if (++currentOffset == offset) |
351 return next; | 351 return next; |
352 } | 352 } |
353 return 0; | 353 return 0; |
354 } | 354 } |
355 | 355 |
356 // FIXME: This should be in LiveNodeList | 356 // FIXME: This should be in LiveNodeList.cpp but it needs to stay here until fir
stMatchingElement() |
357 inline Element* LiveNodeListBase::traverseLiveNodeListFirstElement(ContainerNode
& root) const | 357 // and others are moved to a separate header. |
| 358 inline Node* LiveNodeList::traverseToFirstElement(ContainerNode& root) const |
358 { | 359 { |
359 ASSERT(isLiveNodeListType(type())); | 360 ASSERT(isLiveNodeListType(type())); |
360 ASSERT(type() != ChildNodeListType); | 361 switch (type()) { |
361 if (type() == HTMLTagNodeListType) | 362 case ChildNodeListType: |
| 363 return root.firstChild(); |
| 364 case HTMLTagNodeListType: |
362 return firstMatchingElement(static_cast<const HTMLTagNodeList*>(this), r
oot); | 365 return firstMatchingElement(static_cast<const HTMLTagNodeList*>(this), r
oot); |
363 if (type() == ClassNodeListType) | 366 case ClassNodeListType: |
364 return firstMatchingElement(static_cast<const ClassNodeList*>(this), roo
t); | 367 return firstMatchingElement(static_cast<const ClassNodeList*>(this), roo
t); |
365 return firstMatchingElement(static_cast<const LiveNodeList*>(this), root); | 368 default: |
| 369 return firstMatchingElement(static_cast<const LiveNodeList*>(this), root
); |
| 370 } |
366 } | 371 } |
367 | 372 |
368 // FIXME: This should be in LiveNodeList.cpp but it needs to stay here until tra
verseMatchingElementsForwardToOffset() | 373 // FIXME: This should be in LiveNodeList.cpp but it needs to stay here until tra
verseMatchingElementsForwardToOffset() |
369 // and others are moved to a separate header. | 374 // and others are moved to a separate header. |
370 inline Node* LiveNodeList::traverseForwardToOffset(unsigned offset, Node& curren
tNode, unsigned& currentOffset, ContainerNode* root) const | 375 inline Node* LiveNodeList::traverseForwardToOffset(unsigned offset, Node& curren
tNode, unsigned& currentOffset, ContainerNode* root) const |
371 { | 376 { |
372 switch (type()) { | 377 switch (type()) { |
373 case ChildNodeListType: | 378 case ChildNodeListType: |
374 return traverseSiblingsForwardToOffset(offset, currentNode, currentOffse
t); | 379 return traverseSiblingsForwardToOffset(offset, currentNode, currentOffse
t); |
375 case HTMLTagNodeListType: | 380 case HTMLTagNodeListType: |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 setLengthCache(0); | 432 setLengthCache(0); |
428 return 0; | 433 return 0; |
429 } | 434 } |
430 | 435 |
431 if (isLengthCacheValid() && !overridesItemAfter() && isLastItemCloserThanLas
tOrCachedItem(offset)) { | 436 if (isLengthCacheValid() && !overridesItemAfter() && isLastItemCloserThanLas
tOrCachedItem(offset)) { |
432 Node* lastItem = itemBefore(0); | 437 Node* lastItem = itemBefore(0); |
433 ASSERT(lastItem); | 438 ASSERT(lastItem); |
434 setItemCache(lastItem, cachedLength() - 1); | 439 setItemCache(lastItem, cachedLength() - 1); |
435 } else if (!isItemCacheValid() || isFirstItemCloserThanCachedItem(offset) ||
(overridesItemAfter() && offset < cachedItemOffset())) { | 440 } else if (!isItemCacheValid() || isFirstItemCloserThanCachedItem(offset) ||
(overridesItemAfter() && offset < cachedItemOffset())) { |
436 Node* firstItem; | 441 Node* firstItem; |
437 if (type() == ChildNodeListType) | 442 if (isLiveNodeListType(type())) |
438 firstItem = root->firstChild(); | 443 firstItem = static_cast<const LiveNodeList*>(this)->traverseToFirstE
lement(*root); |
439 else if (isLiveNodeListType(type())) | |
440 firstItem = traverseLiveNodeListFirstElement(*root); | |
441 else | 444 else |
442 firstItem = static_cast<const HTMLCollection*>(this)->traverseFirstE
lement(*root); | 445 firstItem = static_cast<const HTMLCollection*>(this)->traverseToFirs
tElement(*root); |
443 | 446 |
444 if (!firstItem) { | 447 if (!firstItem) { |
445 setLengthCache(0); | 448 setLengthCache(0); |
446 return 0; | 449 return 0; |
447 } | 450 } |
448 setItemCache(firstItem, 0); | 451 setItemCache(firstItem, 0); |
449 ASSERT(!cachedItemOffset()); | 452 ASSERT(!cachedItemOffset()); |
450 } | 453 } |
451 | 454 |
452 if (cachedItemOffset() == offset) | 455 if (cachedItemOffset() == offset) |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 | 537 |
535 inline Element* nextMatchingChildElement(const HTMLCollection* nodeList, Element
& current, ContainerNode* root) | 538 inline Element* nextMatchingChildElement(const HTMLCollection* nodeList, Element
& current, ContainerNode* root) |
536 { | 539 { |
537 Element* next = ¤t; | 540 Element* next = ¤t; |
538 do { | 541 do { |
539 next = ElementTraversal::nextSkippingChildren(*next, root); | 542 next = ElementTraversal::nextSkippingChildren(*next, root); |
540 } while (next && !isMatchingElement(nodeList, next)); | 543 } while (next && !isMatchingElement(nodeList, next)); |
541 return next; | 544 return next; |
542 } | 545 } |
543 | 546 |
544 inline Element* HTMLCollection::traverseFirstElement(ContainerNode& root) const | 547 inline Element* HTMLCollection::traverseToFirstElement(ContainerNode& root) cons
t |
545 { | 548 { |
546 if (overridesItemAfter()) | 549 if (overridesItemAfter()) |
547 return virtualItemAfter(0); | 550 return virtualItemAfter(0); |
548 if (shouldOnlyIncludeDirectChildren()) | 551 if (shouldOnlyIncludeDirectChildren()) |
549 return firstMatchingChildElement(static_cast<const HTMLCollection*>(this
), root); | 552 return firstMatchingChildElement(static_cast<const HTMLCollection*>(this
), root); |
550 return firstMatchingElement(static_cast<const HTMLCollection*>(this), root); | 553 return firstMatchingElement(static_cast<const HTMLCollection*>(this), root); |
551 } | 554 } |
552 | 555 |
553 inline Element* HTMLCollection::traverseNextElement(Element& previous, Container
Node* root) const | 556 inline Element* HTMLCollection::traverseNextElement(Element& previous, Container
Node* root) const |
554 { | 557 { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
587 // This method first searches for an object with a matching id | 590 // This method first searches for an object with a matching id |
588 // attribute. If a match is not found, the method then searches for an | 591 // attribute. If a match is not found, the method then searches for an |
589 // object with a matching name attribute, but only on those elements | 592 // object with a matching name attribute, but only on those elements |
590 // that are allowed a name attribute. | 593 // that are allowed a name attribute. |
591 | 594 |
592 ContainerNode* root = rootContainerNode(); | 595 ContainerNode* root = rootContainerNode(); |
593 if (!root) | 596 if (!root) |
594 return 0; | 597 return 0; |
595 | 598 |
596 unsigned i = 0; | 599 unsigned i = 0; |
597 for (Element* element = traverseFirstElement(*root); element; element = trav
erseNextElement(*element, root)) { | 600 for (Element* element = traverseToFirstElement(*root); element; element = tr
averseNextElement(*element, root)) { |
598 if (checkForNameMatch(element, /* checkName */ false, name)) { | 601 if (checkForNameMatch(element, /* checkName */ false, name)) { |
599 setItemCache(element, i); | 602 setItemCache(element, i); |
600 return element; | 603 return element; |
601 } | 604 } |
602 i++; | 605 i++; |
603 } | 606 } |
604 | 607 |
605 i = 0; | 608 i = 0; |
606 for (Element* element = traverseFirstElement(*root); element; element = trav
erseNextElement(*element, root)) { | 609 for (Element* element = traverseToFirstElement(*root); element; element = tr
averseNextElement(*element, root)) { |
607 if (checkForNameMatch(element, /* checkName */ true, name)) { | 610 if (checkForNameMatch(element, /* checkName */ true, name)) { |
608 setItemCache(element, i); | 611 setItemCache(element, i); |
609 return element; | 612 return element; |
610 } | 613 } |
611 i++; | 614 i++; |
612 } | 615 } |
613 | 616 |
614 return 0; | 617 return 0; |
615 } | 618 } |
616 | 619 |
617 void HTMLCollection::updateNameCache() const | 620 void HTMLCollection::updateNameCache() const |
618 { | 621 { |
619 if (hasNameCache()) | 622 if (hasNameCache()) |
620 return; | 623 return; |
621 | 624 |
622 ContainerNode* root = rootContainerNode(); | 625 ContainerNode* root = rootContainerNode(); |
623 if (!root) | 626 if (!root) |
624 return; | 627 return; |
625 | 628 |
626 for (Element* element = traverseFirstElement(*root); element; element = trav
erseNextElement(*element, root)) { | 629 for (Element* element = traverseToFirstElement(*root); element; element = tr
averseNextElement(*element, root)) { |
627 const AtomicString& idAttrVal = element->getIdAttribute(); | 630 const AtomicString& idAttrVal = element->getIdAttribute(); |
628 if (!idAttrVal.isEmpty()) | 631 if (!idAttrVal.isEmpty()) |
629 appendIdCache(idAttrVal, element); | 632 appendIdCache(idAttrVal, element); |
630 if (!element->isHTMLElement()) | 633 if (!element->isHTMLElement()) |
631 continue; | 634 continue; |
632 const AtomicString& nameAttrVal = element->getNameAttribute(); | 635 const AtomicString& nameAttrVal = element->getNameAttribute(); |
633 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != Doc
All || nameShouldBeVisibleInDocumentAll(toHTMLElement(element)))) | 636 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != Doc
All || nameShouldBeVisibleInDocumentAll(toHTMLElement(element)))) |
634 appendNameCache(nameAttrVal, element); | 637 appendNameCache(nameAttrVal, element); |
635 } | 638 } |
636 | 639 |
(...skipping 20 matching lines...) Expand all Loading... |
657 | 660 |
658 void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element*
element) | 661 void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element*
element) |
659 { | 662 { |
660 OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->v
alue; | 663 OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->v
alue; |
661 if (!vector) | 664 if (!vector) |
662 vector = adoptPtr(new Vector<Element*>); | 665 vector = adoptPtr(new Vector<Element*>); |
663 vector->append(element); | 666 vector->append(element); |
664 } | 667 } |
665 | 668 |
666 } // namespace WebCore | 669 } // namespace WebCore |
OLD | NEW |