| 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 |