| 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-2008, 2011, 2012, 2014 Apple Inc. All rights reserved. | 4 * Copyright (C) 2003-2008, 2011, 2012, 2014 Apple Inc. All rights 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 case TRCells: | 68 case TRCells: |
| 69 case TSectionRows: | 69 case TSectionRows: |
| 70 case TableTBodies: | 70 case TableTBodies: |
| 71 return true; | 71 return true; |
| 72 case NameNodeListType: | 72 case NameNodeListType: |
| 73 case RadioNodeListType: | 73 case RadioNodeListType: |
| 74 case RadioImgNodeListType: | 74 case RadioImgNodeListType: |
| 75 case LabelsNodeListType: | 75 case LabelsNodeListType: |
| 76 break; | 76 break; |
| 77 } | 77 } |
| 78 ASSERT_NOT_REACHED(); | 78 NOTREACHED(); |
| 79 return false; | 79 return false; |
| 80 } | 80 } |
| 81 | 81 |
| 82 static NodeListRootType rootTypeFromCollectionType(CollectionType type) | 82 static NodeListRootType rootTypeFromCollectionType(CollectionType type) |
| 83 { | 83 { |
| 84 switch (type) { | 84 switch (type) { |
| 85 case DocImages: | 85 case DocImages: |
| 86 case DocApplets: | 86 case DocApplets: |
| 87 case DocEmbeds: | 87 case DocEmbeds: |
| 88 case DocForms: | 88 case DocForms: |
| (...skipping 17 matching lines...) Expand all Loading... |
| 106 case SelectedOptions: | 106 case SelectedOptions: |
| 107 case DataListOptions: | 107 case DataListOptions: |
| 108 case MapAreas: | 108 case MapAreas: |
| 109 return NodeListRootType::Node; | 109 return NodeListRootType::Node; |
| 110 case NameNodeListType: | 110 case NameNodeListType: |
| 111 case RadioNodeListType: | 111 case RadioNodeListType: |
| 112 case RadioImgNodeListType: | 112 case RadioImgNodeListType: |
| 113 case LabelsNodeListType: | 113 case LabelsNodeListType: |
| 114 break; | 114 break; |
| 115 } | 115 } |
| 116 ASSERT_NOT_REACHED(); | 116 NOTREACHED(); |
| 117 return NodeListRootType::Node; | 117 return NodeListRootType::Node; |
| 118 } | 118 } |
| 119 | 119 |
| 120 static NodeListInvalidationType invalidationTypeExcludingIdAndNameAttributes(Col
lectionType type) | 120 static NodeListInvalidationType invalidationTypeExcludingIdAndNameAttributes(Col
lectionType type) |
| 121 { | 121 { |
| 122 switch (type) { | 122 switch (type) { |
| 123 case TagCollectionType: | 123 case TagCollectionType: |
| 124 case HTMLTagCollectionType: | 124 case HTMLTagCollectionType: |
| 125 case DocImages: | 125 case DocImages: |
| 126 case DocEmbeds: | 126 case DocEmbeds: |
| (...skipping 24 matching lines...) Expand all Loading... |
| 151 case FormControls: | 151 case FormControls: |
| 152 return InvalidateForFormControls; | 152 return InvalidateForFormControls; |
| 153 case ClassCollectionType: | 153 case ClassCollectionType: |
| 154 return InvalidateOnClassAttrChange; | 154 return InvalidateOnClassAttrChange; |
| 155 case NameNodeListType: | 155 case NameNodeListType: |
| 156 case RadioNodeListType: | 156 case RadioNodeListType: |
| 157 case RadioImgNodeListType: | 157 case RadioImgNodeListType: |
| 158 case LabelsNodeListType: | 158 case LabelsNodeListType: |
| 159 break; | 159 break; |
| 160 } | 160 } |
| 161 ASSERT_NOT_REACHED(); | 161 NOTREACHED(); |
| 162 return DoNotInvalidateOnAttributeChanges; | 162 return DoNotInvalidateOnAttributeChanges; |
| 163 } | 163 } |
| 164 | 164 |
| 165 HTMLCollection::HTMLCollection(ContainerNode& ownerNode, CollectionType type, It
emAfterOverrideType itemAfterOverrideType) | 165 HTMLCollection::HTMLCollection(ContainerNode& ownerNode, CollectionType type, It
emAfterOverrideType itemAfterOverrideType) |
| 166 : LiveNodeListBase(ownerNode, rootTypeFromCollectionType(type), invalidation
TypeExcludingIdAndNameAttributes(type), type) | 166 : LiveNodeListBase(ownerNode, rootTypeFromCollectionType(type), invalidation
TypeExcludingIdAndNameAttributes(type), type) |
| 167 , m_overridesItemAfter(itemAfterOverrideType == OverridesItemAfter) | 167 , m_overridesItemAfter(itemAfterOverrideType == OverridesItemAfter) |
| 168 , m_shouldOnlyIncludeDirectChildren(shouldTypeOnlyIncludeDirectChildren(type
)) | 168 , m_shouldOnlyIncludeDirectChildren(shouldTypeOnlyIncludeDirectChildren(type
)) |
| 169 { | 169 { |
| 170 } | 170 } |
| 171 | 171 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 case HTMLTagCollectionType: | 232 case HTMLTagCollectionType: |
| 233 case DocAll: | 233 case DocAll: |
| 234 case NodeChildren: | 234 case NodeChildren: |
| 235 case FormControls: | 235 case FormControls: |
| 236 case TableRows: | 236 case TableRows: |
| 237 case WindowNamedItems: | 237 case WindowNamedItems: |
| 238 case NameNodeListType: | 238 case NameNodeListType: |
| 239 case RadioNodeListType: | 239 case RadioNodeListType: |
| 240 case RadioImgNodeListType: | 240 case RadioImgNodeListType: |
| 241 case LabelsNodeListType: | 241 case LabelsNodeListType: |
| 242 ASSERT_NOT_REACHED(); | 242 NOTREACHED(); |
| 243 } | 243 } |
| 244 return false; | 244 return false; |
| 245 } | 245 } |
| 246 | 246 |
| 247 inline bool HTMLCollection::elementMatches(const Element& element) const | 247 inline bool HTMLCollection::elementMatches(const Element& element) const |
| 248 { | 248 { |
| 249 // These collections apply to any kind of Elements, not just HTMLElements. | 249 // These collections apply to any kind of Elements, not just HTMLElements. |
| 250 switch (type()) { | 250 switch (type()) { |
| 251 case DocAll: | 251 case DocAll: |
| 252 case NodeChildren: | 252 case NodeChildren: |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 Member<const HTMLCollectionType> m_list; | 286 Member<const HTMLCollectionType> m_list; |
| 287 }; | 287 }; |
| 288 | 288 |
| 289 } // namespace | 289 } // namespace |
| 290 | 290 |
| 291 template <class HTMLCollectionType> | 291 template <class HTMLCollectionType> |
| 292 static inline IsMatch<HTMLCollectionType> makeIsMatch(const HTMLCollectionType&
list) { return IsMatch<HTMLCollectionType>(list); } | 292 static inline IsMatch<HTMLCollectionType> makeIsMatch(const HTMLCollectionType&
list) { return IsMatch<HTMLCollectionType>(list); } |
| 293 | 293 |
| 294 Element* HTMLCollection::virtualItemAfter(Element*) const | 294 Element* HTMLCollection::virtualItemAfter(Element*) const |
| 295 { | 295 { |
| 296 ASSERT_NOT_REACHED(); | 296 NOTREACHED(); |
| 297 return nullptr; | 297 return nullptr; |
| 298 } | 298 } |
| 299 | 299 |
| 300 // https://html.spec.whatwg.org/multipage/infrastructure.html#all-named-elements | 300 // https://html.spec.whatwg.org/multipage/infrastructure.html#all-named-elements |
| 301 // The document.all collection returns only certain types of elements by name, | 301 // The document.all collection returns only certain types of elements by name, |
| 302 // although it returns any type of element by id. | 302 // although it returns any type of element by id. |
| 303 static inline bool nameShouldBeVisibleInDocumentAll(const HTMLElement& element) | 303 static inline bool nameShouldBeVisibleInDocumentAll(const HTMLElement& element) |
| 304 { | 304 { |
| 305 return element.hasTagName(aTag) | 305 return element.hasTagName(aTag) |
| 306 || element.hasTagName(appletTag) | 306 || element.hasTagName(appletTag) |
| (...skipping 23 matching lines...) Expand all Loading... |
| 330 if (overridesItemAfter()) | 330 if (overridesItemAfter()) |
| 331 return virtualItemAfter(0); | 331 return virtualItemAfter(0); |
| 332 if (shouldOnlyIncludeDirectChildren()) | 332 if (shouldOnlyIncludeDirectChildren()) |
| 333 return ElementTraversal::firstChild(rootNode(), makeIsMatch(*this)); | 333 return ElementTraversal::firstChild(rootNode(), makeIsMatch(*this)); |
| 334 return ElementTraversal::firstWithin(rootNode(), makeIsMatch(*this)); | 334 return ElementTraversal::firstWithin(rootNode(), makeIsMatch(*this)); |
| 335 } | 335 } |
| 336 } | 336 } |
| 337 | 337 |
| 338 Element* HTMLCollection::traverseToLast() const | 338 Element* HTMLCollection::traverseToLast() const |
| 339 { | 339 { |
| 340 ASSERT(canTraverseBackward()); | 340 DCHECK(canTraverseBackward()); |
| 341 if (shouldOnlyIncludeDirectChildren()) | 341 if (shouldOnlyIncludeDirectChildren()) |
| 342 return ElementTraversal::lastChild(rootNode(), makeIsMatch(*this)); | 342 return ElementTraversal::lastChild(rootNode(), makeIsMatch(*this)); |
| 343 return ElementTraversal::lastWithin(rootNode(), makeIsMatch(*this)); | 343 return ElementTraversal::lastWithin(rootNode(), makeIsMatch(*this)); |
| 344 } | 344 } |
| 345 | 345 |
| 346 Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element& curre
ntElement, unsigned& currentOffset) const | 346 Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element& curre
ntElement, unsigned& currentOffset) const |
| 347 { | 347 { |
| 348 ASSERT(currentOffset < offset); | 348 DCHECK_LT(currentOffset, offset); |
| 349 switch (type()) { | 349 switch (type()) { |
| 350 case HTMLTagCollectionType: | 350 case HTMLTagCollectionType: |
| 351 return traverseMatchingElementsForwardToOffset(currentElement, &rootNode
(), offset, currentOffset, makeIsMatch(toHTMLTagCollection(*this))); | 351 return traverseMatchingElementsForwardToOffset(currentElement, &rootNode
(), offset, currentOffset, makeIsMatch(toHTMLTagCollection(*this))); |
| 352 case ClassCollectionType: | 352 case ClassCollectionType: |
| 353 return traverseMatchingElementsForwardToOffset(currentElement, &rootNode
(), offset, currentOffset, makeIsMatch(toClassCollection(*this))); | 353 return traverseMatchingElementsForwardToOffset(currentElement, &rootNode
(), offset, currentOffset, makeIsMatch(toClassCollection(*this))); |
| 354 default: | 354 default: |
| 355 if (overridesItemAfter()) { | 355 if (overridesItemAfter()) { |
| 356 for (Element* next = virtualItemAfter(¤tElement); next; next =
virtualItemAfter(next)) { | 356 for (Element* next = virtualItemAfter(¤tElement); next; next =
virtualItemAfter(next)) { |
| 357 if (++currentOffset == offset) | 357 if (++currentOffset == offset) |
| 358 return next; | 358 return next; |
| 359 } | 359 } |
| 360 return nullptr; | 360 return nullptr; |
| 361 } | 361 } |
| 362 if (shouldOnlyIncludeDirectChildren()) { | 362 if (shouldOnlyIncludeDirectChildren()) { |
| 363 IsMatch<HTMLCollection> isMatch(*this); | 363 IsMatch<HTMLCollection> isMatch(*this); |
| 364 for (Element* next = ElementTraversal::nextSibling(currentElement, i
sMatch); next; next = ElementTraversal::nextSibling(*next, isMatch)) { | 364 for (Element* next = ElementTraversal::nextSibling(currentElement, i
sMatch); next; next = ElementTraversal::nextSibling(*next, isMatch)) { |
| 365 if (++currentOffset == offset) | 365 if (++currentOffset == offset) |
| 366 return next; | 366 return next; |
| 367 } | 367 } |
| 368 return nullptr; | 368 return nullptr; |
| 369 } | 369 } |
| 370 return traverseMatchingElementsForwardToOffset(currentElement, &rootNode
(), offset, currentOffset, makeIsMatch(*this)); | 370 return traverseMatchingElementsForwardToOffset(currentElement, &rootNode
(), offset, currentOffset, makeIsMatch(*this)); |
| 371 } | 371 } |
| 372 } | 372 } |
| 373 | 373 |
| 374 Element* HTMLCollection::traverseBackwardToOffset(unsigned offset, Element& curr
entElement, unsigned& currentOffset) const | 374 Element* HTMLCollection::traverseBackwardToOffset(unsigned offset, Element& curr
entElement, unsigned& currentOffset) const |
| 375 { | 375 { |
| 376 ASSERT(currentOffset > offset); | 376 DCHECK_GT(currentOffset, offset); |
| 377 ASSERT(canTraverseBackward()); | 377 DCHECK(canTraverseBackward()); |
| 378 if (shouldOnlyIncludeDirectChildren()) { | 378 if (shouldOnlyIncludeDirectChildren()) { |
| 379 IsMatch<HTMLCollection> isMatch(*this); | 379 IsMatch<HTMLCollection> isMatch(*this); |
| 380 for (Element* previous = ElementTraversal::previousSibling(currentElemen
t, isMatch); previous; previous = ElementTraversal::previousSibling(*previous, i
sMatch)) { | 380 for (Element* previous = ElementTraversal::previousSibling(currentElemen
t, isMatch); previous; previous = ElementTraversal::previousSibling(*previous, i
sMatch)) { |
| 381 if (--currentOffset == offset) | 381 if (--currentOffset == offset) |
| 382 return previous; | 382 return previous; |
| 383 } | 383 } |
| 384 return nullptr; | 384 return nullptr; |
| 385 } | 385 } |
| 386 return traverseMatchingElementsBackwardToOffset(currentElement, &rootNode(),
offset, currentOffset, makeIsMatch(*this)); | 386 return traverseMatchingElementsBackwardToOffset(currentElement, &rootNode(),
offset, currentOffset, makeIsMatch(*this)); |
| 387 } | 387 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 const AtomicString& nameAttrVal = element->getNameAttribute(); | 465 const AtomicString& nameAttrVal = element->getNameAttribute(); |
| 466 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != Doc
All || nameShouldBeVisibleInDocumentAll(toHTMLElement(*element)))) | 466 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != Doc
All || nameShouldBeVisibleInDocumentAll(toHTMLElement(*element)))) |
| 467 cache->addElementWithName(nameAttrVal, element); | 467 cache->addElementWithName(nameAttrVal, element); |
| 468 } | 468 } |
| 469 // Set the named item cache last as traversing the tree may cause cache inva
lidation. | 469 // Set the named item cache last as traversing the tree may cause cache inva
lidation. |
| 470 setNamedItemCache(cache); | 470 setNamedItemCache(cache); |
| 471 } | 471 } |
| 472 | 472 |
| 473 void HTMLCollection::namedItems(const AtomicString& name, HeapVector<Member<Elem
ent>>& result) const | 473 void HTMLCollection::namedItems(const AtomicString& name, HeapVector<Member<Elem
ent>>& result) const |
| 474 { | 474 { |
| 475 ASSERT(result.isEmpty()); | 475 DCHECK(result.isEmpty()); |
| 476 if (name.isEmpty()) | 476 if (name.isEmpty()) |
| 477 return; | 477 return; |
| 478 | 478 |
| 479 updateIdNameCache(); | 479 updateIdNameCache(); |
| 480 | 480 |
| 481 const NamedItemCache& cache = namedItemCache(); | 481 const NamedItemCache& cache = namedItemCache(); |
| 482 if (HeapVector<Member<Element>>* idResults = cache.getElementsById(name)) { | 482 if (HeapVector<Member<Element>>* idResults = cache.getElementsById(name)) { |
| 483 for (unsigned i = 0; i < idResults->size(); ++i) | 483 for (unsigned i = 0; i < idResults->size(); ++i) |
| 484 result.append(idResults->at(i)); | 484 result.append(idResults->at(i)); |
| 485 } | 485 } |
| 486 if (HeapVector<Member<Element>>* nameResults = cache.getElementsByName(name)
) { | 486 if (HeapVector<Member<Element>>* nameResults = cache.getElementsByName(name)
) { |
| 487 for (unsigned i = 0; i < nameResults->size(); ++i) | 487 for (unsigned i = 0; i < nameResults->size(); ++i) |
| 488 result.append(nameResults->at(i)); | 488 result.append(nameResults->at(i)); |
| 489 } | 489 } |
| 490 } | 490 } |
| 491 | 491 |
| 492 HTMLCollection::NamedItemCache::NamedItemCache() | 492 HTMLCollection::NamedItemCache::NamedItemCache() |
| 493 { | 493 { |
| 494 } | 494 } |
| 495 | 495 |
| 496 DEFINE_TRACE(HTMLCollection) | 496 DEFINE_TRACE(HTMLCollection) |
| 497 { | 497 { |
| 498 visitor->trace(m_namedItemCache); | 498 visitor->trace(m_namedItemCache); |
| 499 visitor->trace(m_collectionItemsCache); | 499 visitor->trace(m_collectionItemsCache); |
| 500 LiveNodeListBase::trace(visitor); | 500 LiveNodeListBase::trace(visitor); |
| 501 } | 501 } |
| 502 | 502 |
| 503 } // namespace blink | 503 } // namespace blink |
| OLD | NEW |