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 |