| 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 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 current = previousNode(rootNode(), *previous, shouldOnlyIncludeDirectChi
ldren()); | 295 current = previousNode(rootNode(), *previous, shouldOnlyIncludeDirectChi
ldren()); |
| 296 else | 296 else |
| 297 current = lastNode(rootNode(), shouldOnlyIncludeDirectChildren()); | 297 current = lastNode(rootNode(), shouldOnlyIncludeDirectChildren()); |
| 298 | 298 |
| 299 if (type() == ChildNodeListType) | 299 if (type() == ChildNodeListType) |
| 300 return current; | 300 return current; |
| 301 return iterateForPreviousNode(current); | 301 return iterateForPreviousNode(current); |
| 302 } | 302 } |
| 303 | 303 |
| 304 template <class NodeListType> | 304 template <class NodeListType> |
| 305 inline Element* firstMatchingElement(const NodeListType* nodeList, ContainerNode
* root) | 305 inline Element* firstMatchingElement(const NodeListType* nodeList, ContainerNode
& root) |
| 306 { | 306 { |
| 307 Element* element = ElementTraversal::firstWithin(root); | 307 Element* element = ElementTraversal::firstWithin(root); |
| 308 while (element && !isMatchingElement(nodeList, element)) | 308 while (element && !isMatchingElement(nodeList, element)) |
| 309 element = ElementTraversal::next(*element, root); | 309 element = ElementTraversal::next(*element, &root); |
| 310 return element; | 310 return element; |
| 311 } | 311 } |
| 312 | 312 |
| 313 template <class NodeListType> | 313 template <class NodeListType> |
| 314 inline Element* nextMatchingElement(const NodeListType* nodeList, Element& curre
nt, ContainerNode* root) | 314 inline Element* nextMatchingElement(const NodeListType* nodeList, Element& curre
nt, ContainerNode* root) |
| 315 { | 315 { |
| 316 Element* next = ¤t; | 316 Element* next = ¤t; |
| 317 do { | 317 do { |
| 318 next = ElementTraversal::next(*next, root); | 318 next = ElementTraversal::next(*next, root); |
| 319 } while (next && !isMatchingElement(nodeList, next)); | 319 } while (next && !isMatchingElement(nodeList, next)); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 338 ASSERT(type() == ChildNodeListType); | 338 ASSERT(type() == ChildNodeListType); |
| 339 ASSERT(currentOffset < offset); | 339 ASSERT(currentOffset < offset); |
| 340 while ((currentNode = currentNode->nextSibling())) { | 340 while ((currentNode = currentNode->nextSibling())) { |
| 341 if (++currentOffset == offset) | 341 if (++currentOffset == offset) |
| 342 return currentNode; | 342 return currentNode; |
| 343 } | 343 } |
| 344 return 0; | 344 return 0; |
| 345 } | 345 } |
| 346 | 346 |
| 347 // FIXME: This should be in LiveNodeList | 347 // FIXME: This should be in LiveNodeList |
| 348 inline Element* LiveNodeListBase::traverseLiveNodeListFirstElement(ContainerNode
* root) const | 348 inline Element* LiveNodeListBase::traverseLiveNodeListFirstElement(ContainerNode
& root) const |
| 349 { | 349 { |
| 350 ASSERT(isNodeList(type())); | 350 ASSERT(isNodeList(type())); |
| 351 ASSERT(type() != ChildNodeListType); | 351 ASSERT(type() != ChildNodeListType); |
| 352 if (type() == HTMLTagNodeListType) | 352 if (type() == HTMLTagNodeListType) |
| 353 return firstMatchingElement(static_cast<const HTMLTagNodeList*>(this), r
oot); | 353 return firstMatchingElement(static_cast<const HTMLTagNodeList*>(this), r
oot); |
| 354 if (type() == ClassNodeListType) | 354 if (type() == ClassNodeListType) |
| 355 return firstMatchingElement(static_cast<const ClassNodeList*>(this), roo
t); | 355 return firstMatchingElement(static_cast<const ClassNodeList*>(this), roo
t); |
| 356 return firstMatchingElement(static_cast<const LiveNodeList*>(this), root); | 356 return firstMatchingElement(static_cast<const LiveNodeList*>(this), root); |
| 357 } | 357 } |
| 358 | 358 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 if (isLengthCacheValid() && !overridesItemAfter() && isLastItemCloserThanLas
tOrCachedItem(offset)) { | 428 if (isLengthCacheValid() && !overridesItemAfter() && isLastItemCloserThanLas
tOrCachedItem(offset)) { |
| 429 Node* lastItem = itemBefore(0); | 429 Node* lastItem = itemBefore(0); |
| 430 ASSERT(lastItem); | 430 ASSERT(lastItem); |
| 431 setItemCache(lastItem, cachedLength() - 1, 0); | 431 setItemCache(lastItem, cachedLength() - 1, 0); |
| 432 } else if (!isItemCacheValid() || isFirstItemCloserThanCachedItem(offset) ||
(overridesItemAfter() && offset < cachedItemOffset())) { | 432 } else if (!isItemCacheValid() || isFirstItemCloserThanCachedItem(offset) ||
(overridesItemAfter() && offset < cachedItemOffset())) { |
| 433 unsigned offsetInArray = 0; | 433 unsigned offsetInArray = 0; |
| 434 Node* firstItem; | 434 Node* firstItem; |
| 435 if (type() == ChildNodeListType) | 435 if (type() == ChildNodeListType) |
| 436 firstItem = root->firstChild(); | 436 firstItem = root->firstChild(); |
| 437 else if (isNodeList(type())) | 437 else if (isNodeList(type())) |
| 438 firstItem = traverseLiveNodeListFirstElement(root); | 438 firstItem = traverseLiveNodeListFirstElement(*root); |
| 439 else | 439 else |
| 440 firstItem = static_cast<const HTMLCollection*>(this)->traverseFirstE
lement(offsetInArray, root); | 440 firstItem = static_cast<const HTMLCollection*>(this)->traverseFirstE
lement(offsetInArray, *root); |
| 441 | 441 |
| 442 if (!firstItem) { | 442 if (!firstItem) { |
| 443 setLengthCache(0); | 443 setLengthCache(0); |
| 444 return 0; | 444 return 0; |
| 445 } | 445 } |
| 446 setItemCache(firstItem, 0, offsetInArray); | 446 setItemCache(firstItem, 0, offsetInArray); |
| 447 ASSERT(!cachedItemOffset()); | 447 ASSERT(!cachedItemOffset()); |
| 448 } | 448 } |
| 449 | 449 |
| 450 if (cachedItemOffset() == offset) | 450 if (cachedItemOffset() == offset) |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 HTMLElement* e = toHTMLElement(element); | 518 HTMLElement* e = toHTMLElement(element); |
| 519 if (!checkName) | 519 if (!checkName) |
| 520 return e->getIdAttribute() == name; | 520 return e->getIdAttribute() == name; |
| 521 | 521 |
| 522 if (type() == DocAll && !nameShouldBeVisibleInDocumentAll(e)) | 522 if (type() == DocAll && !nameShouldBeVisibleInDocumentAll(e)) |
| 523 return false; | 523 return false; |
| 524 | 524 |
| 525 return e->getNameAttribute() == name && e->getIdAttribute() != name; | 525 return e->getNameAttribute() == name && e->getIdAttribute() != name; |
| 526 } | 526 } |
| 527 | 527 |
| 528 inline Element* firstMatchingChildElement(const HTMLCollection* nodeList, Contai
nerNode* root) | 528 inline Element* firstMatchingChildElement(const HTMLCollection* nodeList, Contai
nerNode& root) |
| 529 { | 529 { |
| 530 Element* element = ElementTraversal::firstWithin(root); | 530 Element* element = ElementTraversal::firstWithin(root); |
| 531 while (element && !isMatchingElement(nodeList, element)) | 531 while (element && !isMatchingElement(nodeList, element)) |
| 532 element = ElementTraversal::nextSkippingChildren(*element, root); | 532 element = ElementTraversal::nextSkippingChildren(*element, &root); |
| 533 return element; | 533 return element; |
| 534 } | 534 } |
| 535 | 535 |
| 536 inline Element* nextMatchingChildElement(const HTMLCollection* nodeList, Element
& current, ContainerNode* root) | 536 inline Element* nextMatchingChildElement(const HTMLCollection* nodeList, Element
& current, ContainerNode* root) |
| 537 { | 537 { |
| 538 Element* next = ¤t; | 538 Element* next = ¤t; |
| 539 do { | 539 do { |
| 540 next = ElementTraversal::nextSkippingChildren(*next, root); | 540 next = ElementTraversal::nextSkippingChildren(*next, root); |
| 541 } while (next && !isMatchingElement(nodeList, next)); | 541 } while (next && !isMatchingElement(nodeList, next)); |
| 542 return next; | 542 return next; |
| 543 } | 543 } |
| 544 | 544 |
| 545 inline Element* HTMLCollection::traverseFirstElement(unsigned& offsetInArray, Co
ntainerNode* root) const | 545 inline Element* HTMLCollection::traverseFirstElement(unsigned& offsetInArray, Co
ntainerNode& root) const |
| 546 { | 546 { |
| 547 if (overridesItemAfter()) | 547 if (overridesItemAfter()) |
| 548 return virtualItemAfter(offsetInArray, 0); | 548 return virtualItemAfter(offsetInArray, 0); |
| 549 ASSERT(!offsetInArray); | 549 ASSERT(!offsetInArray); |
| 550 if (shouldOnlyIncludeDirectChildren()) | 550 if (shouldOnlyIncludeDirectChildren()) |
| 551 return firstMatchingChildElement(static_cast<const HTMLCollection*>(this
), root); | 551 return firstMatchingChildElement(static_cast<const HTMLCollection*>(this
), root); |
| 552 return firstMatchingElement(static_cast<const HTMLCollection*>(this), root); | 552 return firstMatchingElement(static_cast<const HTMLCollection*>(this), root); |
| 553 } | 553 } |
| 554 | 554 |
| 555 inline Element* HTMLCollection::traverseNextElement(unsigned& offsetInArray, Ele
ment& previous, ContainerNode* root) const | 555 inline Element* HTMLCollection::traverseNextElement(unsigned& offsetInArray, Ele
ment& previous, ContainerNode* root) const |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 // attribute. If a match is not found, the method then searches for an | 592 // attribute. If a match is not found, the method then searches for an |
| 593 // object with a matching name attribute, but only on those elements | 593 // object with a matching name attribute, but only on those elements |
| 594 // that are allowed a name attribute. | 594 // that are allowed a name attribute. |
| 595 | 595 |
| 596 ContainerNode* root = rootContainerNode(); | 596 ContainerNode* root = rootContainerNode(); |
| 597 if (!root) | 597 if (!root) |
| 598 return 0; | 598 return 0; |
| 599 | 599 |
| 600 unsigned arrayOffset = 0; | 600 unsigned arrayOffset = 0; |
| 601 unsigned i = 0; | 601 unsigned i = 0; |
| 602 for (Element* element = traverseFirstElement(arrayOffset, root); element; el
ement = traverseNextElement(arrayOffset, *element, root)) { | 602 for (Element* element = traverseFirstElement(arrayOffset, *root); element; e
lement = traverseNextElement(arrayOffset, *element, root)) { |
| 603 if (checkForNameMatch(element, /* checkName */ false, name)) { | 603 if (checkForNameMatch(element, /* checkName */ false, name)) { |
| 604 setItemCache(element, i, arrayOffset); | 604 setItemCache(element, i, arrayOffset); |
| 605 return element; | 605 return element; |
| 606 } | 606 } |
| 607 i++; | 607 i++; |
| 608 } | 608 } |
| 609 | 609 |
| 610 i = 0; | 610 i = 0; |
| 611 for (Element* element = traverseFirstElement(arrayOffset, root); element; el
ement = traverseNextElement(arrayOffset, *element, root)) { | 611 for (Element* element = traverseFirstElement(arrayOffset, *root); element; e
lement = traverseNextElement(arrayOffset, *element, root)) { |
| 612 if (checkForNameMatch(element, /* checkName */ true, name)) { | 612 if (checkForNameMatch(element, /* checkName */ true, name)) { |
| 613 setItemCache(element, i, arrayOffset); | 613 setItemCache(element, i, arrayOffset); |
| 614 return element; | 614 return element; |
| 615 } | 615 } |
| 616 i++; | 616 i++; |
| 617 } | 617 } |
| 618 | 618 |
| 619 return 0; | 619 return 0; |
| 620 } | 620 } |
| 621 | 621 |
| 622 void HTMLCollection::updateNameCache() const | 622 void HTMLCollection::updateNameCache() const |
| 623 { | 623 { |
| 624 if (hasNameCache()) | 624 if (hasNameCache()) |
| 625 return; | 625 return; |
| 626 | 626 |
| 627 ContainerNode* root = rootContainerNode(); | 627 ContainerNode* root = rootContainerNode(); |
| 628 if (!root) | 628 if (!root) |
| 629 return; | 629 return; |
| 630 | 630 |
| 631 unsigned arrayOffset = 0; | 631 unsigned arrayOffset = 0; |
| 632 for (Element* element = traverseFirstElement(arrayOffset, root); element; el
ement = traverseNextElement(arrayOffset, *element, root)) { | 632 for (Element* element = traverseFirstElement(arrayOffset, *root); element; e
lement = traverseNextElement(arrayOffset, *element, root)) { |
| 633 const AtomicString& idAttrVal = element->getIdAttribute(); | 633 const AtomicString& idAttrVal = element->getIdAttribute(); |
| 634 if (!idAttrVal.isEmpty()) | 634 if (!idAttrVal.isEmpty()) |
| 635 appendIdCache(idAttrVal, element); | 635 appendIdCache(idAttrVal, element); |
| 636 if (!element->isHTMLElement()) | 636 if (!element->isHTMLElement()) |
| 637 continue; | 637 continue; |
| 638 const AtomicString& nameAttrVal = element->getNameAttribute(); | 638 const AtomicString& nameAttrVal = element->getNameAttribute(); |
| 639 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != Doc
All || nameShouldBeVisibleInDocumentAll(toHTMLElement(element)))) | 639 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != Doc
All || nameShouldBeVisibleInDocumentAll(toHTMLElement(element)))) |
| 640 appendNameCache(nameAttrVal, element); | 640 appendNameCache(nameAttrVal, element); |
| 641 } | 641 } |
| 642 | 642 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 683 | 683 |
| 684 void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element*
element) | 684 void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element*
element) |
| 685 { | 685 { |
| 686 OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->v
alue; | 686 OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->v
alue; |
| 687 if (!vector) | 687 if (!vector) |
| 688 vector = adoptPtr(new Vector<Element*>); | 688 vector = adoptPtr(new Vector<Element*>); |
| 689 vector->append(element); | 689 vector->append(element); |
| 690 } | 690 } |
| 691 | 691 |
| 692 } // namespace WebCore | 692 } // namespace WebCore |
| OLD | NEW |