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 * Copyright (C) 2014 Samsung Electronics. All rights reserved. | 5 * Copyright (C) 2014 Samsung Electronics. All rights reserved. |
6 * | 6 * |
7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 } | 358 } |
359 | 359 |
360 Element* HTMLCollection::traverseToLastElement() const | 360 Element* HTMLCollection::traverseToLastElement() const |
361 { | 361 { |
362 ASSERT(canTraverseBackward()); | 362 ASSERT(canTraverseBackward()); |
363 if (shouldOnlyIncludeDirectChildren()) | 363 if (shouldOnlyIncludeDirectChildren()) |
364 return lastMatchingChildElement(*this); | 364 return lastMatchingChildElement(*this); |
365 return lastMatchingElement(*this); | 365 return lastMatchingElement(*this); |
366 } | 366 } |
367 | 367 |
368 inline Element* HTMLCollection::traverseNextElement(Element& previous) const | |
369 { | |
370 if (overridesItemAfter()) | |
371 return virtualItemAfter(&previous); | |
372 if (shouldOnlyIncludeDirectChildren()) | |
373 return nextMatchingChildElement(*this, previous); | |
374 return nextMatchingElement(*this, previous); | |
375 } | |
376 | |
377 Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element& curre
ntElement, unsigned& currentOffset) const | 368 Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element& curre
ntElement, unsigned& currentOffset) const |
378 { | 369 { |
379 ASSERT(currentOffset < offset); | 370 ASSERT(currentOffset < offset); |
380 switch (type()) { | 371 switch (type()) { |
381 case HTMLTagCollectionType: | 372 case HTMLTagCollectionType: |
382 return traverseMatchingElementsForwardToOffset(toHTMLTagCollection(*this
), offset, currentElement, currentOffset); | 373 return traverseMatchingElementsForwardToOffset(toHTMLTagCollection(*this
), offset, currentElement, currentOffset); |
383 case ClassCollectionType: | 374 case ClassCollectionType: |
384 return traverseMatchingElementsForwardToOffset(toClassCollection(*this),
offset, currentElement, currentOffset); | 375 return traverseMatchingElementsForwardToOffset(toClassCollection(*this),
offset, currentElement, currentOffset); |
385 default: | 376 default: |
386 if (overridesItemAfter()) { | 377 if (overridesItemAfter()) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 { | 439 { |
449 // As per the specification (http://dom.spec.whatwg.org/#htmlcollection): | 440 // As per the specification (http://dom.spec.whatwg.org/#htmlcollection): |
450 // The supported property names are the values from the list returned by the
se steps: | 441 // The supported property names are the values from the list returned by the
se steps: |
451 // 1. Let result be an empty list. | 442 // 1. Let result be an empty list. |
452 // 2. For each element represented by the collection, in tree order, run the
se substeps: | 443 // 2. For each element represented by the collection, in tree order, run the
se substeps: |
453 // 1. If element has an ID which is neither the empty string nor is in res
ult, append element's ID to result. | 444 // 1. If element has an ID which is neither the empty string nor is in res
ult, append element's ID to result. |
454 // 2. If element is in the HTML namespace and has a name attribute whose v
alue is neither the empty string | 445 // 2. If element is in the HTML namespace and has a name attribute whose v
alue is neither the empty string |
455 // nor is in result, append element's name attribute value to result. | 446 // nor is in result, append element's name attribute value to result. |
456 // 3. Return result. | 447 // 3. Return result. |
457 HashSet<AtomicString> existingNames; | 448 HashSet<AtomicString> existingNames; |
458 for (Element* element = traverseToFirstElement(); element; element = travers
eNextElement(*element)) { | 449 unsigned length = this->length(); |
| 450 for (unsigned i = 0; i < length; ++i) { |
| 451 Element* element = item(i); |
459 const AtomicString& idAttribute = element->getIdAttribute(); | 452 const AtomicString& idAttribute = element->getIdAttribute(); |
460 if (!idAttribute.isEmpty()) { | 453 if (!idAttribute.isEmpty()) { |
461 HashSet<AtomicString>::AddResult addResult = existingNames.add(idAtt
ribute); | 454 HashSet<AtomicString>::AddResult addResult = existingNames.add(idAtt
ribute); |
462 if (addResult.isNewEntry) | 455 if (addResult.isNewEntry) |
463 names.append(idAttribute); | 456 names.append(idAttribute); |
464 } | 457 } |
465 if (!element->isHTMLElement()) | 458 if (!element->isHTMLElement()) |
466 continue; | 459 continue; |
467 const AtomicString& nameAttribute = element->getNameAttribute(); | 460 const AtomicString& nameAttribute = element->getNameAttribute(); |
468 if (!nameAttribute.isEmpty() && (type() != DocAll || nameShouldBeVisible
InDocumentAll(toHTMLElement(*element)))) { | 461 if (!nameAttribute.isEmpty() && (type() != DocAll || nameShouldBeVisible
InDocumentAll(toHTMLElement(*element)))) { |
469 HashSet<AtomicString>::AddResult addResult = existingNames.add(nameA
ttribute); | 462 HashSet<AtomicString>::AddResult addResult = existingNames.add(nameA
ttribute); |
470 if (addResult.isNewEntry) | 463 if (addResult.isNewEntry) |
471 names.append(nameAttribute); | 464 names.append(nameAttribute); |
472 } | 465 } |
473 } | 466 } |
474 } | 467 } |
475 | 468 |
476 void HTMLCollection::namedPropertyEnumerator(Vector<String>& names, ExceptionSta
te&) | 469 void HTMLCollection::namedPropertyEnumerator(Vector<String>& names, ExceptionSta
te&) |
477 { | 470 { |
478 supportedPropertyNames(names); | 471 supportedPropertyNames(names); |
479 } | 472 } |
480 | 473 |
481 void HTMLCollection::updateIdNameCache() const | 474 void HTMLCollection::updateIdNameCache() const |
482 { | 475 { |
483 if (hasValidIdNameCache()) | 476 if (hasValidIdNameCache()) |
484 return; | 477 return; |
485 | 478 |
486 OwnPtrWillBeRawPtr<NamedItemCache> cache = NamedItemCache::create(); | 479 OwnPtrWillBeRawPtr<NamedItemCache> cache = NamedItemCache::create(); |
487 for (Element* element = traverseToFirstElement(); element; element = travers
eNextElement(*element)) { | 480 unsigned length = this->length(); |
| 481 for (unsigned i = 0; i < length; ++i) { |
| 482 Element* element = item(i); |
488 const AtomicString& idAttrVal = element->getIdAttribute(); | 483 const AtomicString& idAttrVal = element->getIdAttribute(); |
489 if (!idAttrVal.isEmpty()) | 484 if (!idAttrVal.isEmpty()) |
490 cache->addElementWithId(idAttrVal, element); | 485 cache->addElementWithId(idAttrVal, element); |
491 if (!element->isHTMLElement()) | 486 if (!element->isHTMLElement()) |
492 continue; | 487 continue; |
493 const AtomicString& nameAttrVal = element->getNameAttribute(); | 488 const AtomicString& nameAttrVal = element->getNameAttribute(); |
494 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != Doc
All || nameShouldBeVisibleInDocumentAll(toHTMLElement(*element)))) | 489 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != Doc
All || nameShouldBeVisibleInDocumentAll(toHTMLElement(*element)))) |
495 cache->addElementWithName(nameAttrVal, element); | 490 cache->addElementWithName(nameAttrVal, element); |
496 } | 491 } |
497 // Set the named item cache last as traversing the tree may cause cache inva
lidation. | 492 // Set the named item cache last as traversing the tree may cause cache inva
lidation. |
(...skipping 24 matching lines...) Expand all Loading... |
522 } | 517 } |
523 | 518 |
524 void HTMLCollection::trace(Visitor* visitor) | 519 void HTMLCollection::trace(Visitor* visitor) |
525 { | 520 { |
526 visitor->trace(m_namedItemCache); | 521 visitor->trace(m_namedItemCache); |
527 visitor->trace(m_collectionIndexCache); | 522 visitor->trace(m_collectionIndexCache); |
528 LiveNodeListBase::trace(visitor); | 523 LiveNodeListBase::trace(visitor); |
529 } | 524 } |
530 | 525 |
531 } // namespace WebCore | 526 } // namespace WebCore |
OLD | NEW |