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 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 }; | 294 }; |
295 | 295 |
296 } // namespace | 296 } // namespace |
297 | 297 |
298 template <class HTMLCollectionType> | 298 template <class HTMLCollectionType> |
299 static inline IsMatch<HTMLCollectionType> makeIsMatch(const HTMLCollectionType&
list) { return IsMatch<HTMLCollectionType>(list); } | 299 static inline IsMatch<HTMLCollectionType> makeIsMatch(const HTMLCollectionType&
list) { return IsMatch<HTMLCollectionType>(list); } |
300 | 300 |
301 Element* HTMLCollection::virtualItemAfter(Element*) const | 301 Element* HTMLCollection::virtualItemAfter(Element*) const |
302 { | 302 { |
303 ASSERT_NOT_REACHED(); | 303 ASSERT_NOT_REACHED(); |
304 return 0; | 304 return nullptr; |
305 } | 305 } |
306 | 306 |
307 static inline bool nameShouldBeVisibleInDocumentAll(const HTMLElement& element) | 307 static inline bool nameShouldBeVisibleInDocumentAll(const HTMLElement& element) |
308 { | 308 { |
309 // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-in
terfaces.html#dom-htmlallcollection-nameditem: | 309 // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-in
terfaces.html#dom-htmlallcollection-nameditem: |
310 // The document.all collection returns only certain types of elements by nam
e, | 310 // The document.all collection returns only certain types of elements by nam
e, |
311 // although it returns any type of element by id. | 311 // although it returns any type of element by id. |
312 return element.hasTagName(aTag) | 312 return element.hasTagName(aTag) |
313 || element.hasTagName(appletTag) | 313 || element.hasTagName(appletTag) |
314 || element.hasTagName(areaTag) | 314 || element.hasTagName(areaTag) |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 case HTMLTagCollectionType: | 354 case HTMLTagCollectionType: |
355 return traverseMatchingElementsForwardToOffset(currentElement, &rootNode
(), offset, currentOffset, makeIsMatch(toHTMLTagCollection(*this))); | 355 return traverseMatchingElementsForwardToOffset(currentElement, &rootNode
(), offset, currentOffset, makeIsMatch(toHTMLTagCollection(*this))); |
356 case ClassCollectionType: | 356 case ClassCollectionType: |
357 return traverseMatchingElementsForwardToOffset(currentElement, &rootNode
(), offset, currentOffset, makeIsMatch(toClassCollection(*this))); | 357 return traverseMatchingElementsForwardToOffset(currentElement, &rootNode
(), offset, currentOffset, makeIsMatch(toClassCollection(*this))); |
358 default: | 358 default: |
359 if (overridesItemAfter()) { | 359 if (overridesItemAfter()) { |
360 for (Element* next = virtualItemAfter(¤tElement); next; next =
virtualItemAfter(next)) { | 360 for (Element* next = virtualItemAfter(¤tElement); next; next =
virtualItemAfter(next)) { |
361 if (++currentOffset == offset) | 361 if (++currentOffset == offset) |
362 return next; | 362 return next; |
363 } | 363 } |
364 return 0; | 364 return nullptr; |
365 } | 365 } |
366 if (shouldOnlyIncludeDirectChildren()) { | 366 if (shouldOnlyIncludeDirectChildren()) { |
367 IsMatch<HTMLCollection> isMatch(*this); | 367 IsMatch<HTMLCollection> isMatch(*this); |
368 for (Element* next = ElementTraversal::nextSibling(currentElement, i
sMatch); next; next = ElementTraversal::nextSibling(*next, isMatch)) { | 368 for (Element* next = ElementTraversal::nextSibling(currentElement, i
sMatch); next; next = ElementTraversal::nextSibling(*next, isMatch)) { |
369 if (++currentOffset == offset) | 369 if (++currentOffset == offset) |
370 return next; | 370 return next; |
371 } | 371 } |
372 return 0; | 372 return nullptr; |
373 } | 373 } |
374 return traverseMatchingElementsForwardToOffset(currentElement, &rootNode
(), offset, currentOffset, makeIsMatch(*this)); | 374 return traverseMatchingElementsForwardToOffset(currentElement, &rootNode
(), offset, currentOffset, makeIsMatch(*this)); |
375 } | 375 } |
376 } | 376 } |
377 | 377 |
378 Element* HTMLCollection::traverseBackwardToOffset(unsigned offset, Element& curr
entElement, unsigned& currentOffset) const | 378 Element* HTMLCollection::traverseBackwardToOffset(unsigned offset, Element& curr
entElement, unsigned& currentOffset) const |
379 { | 379 { |
380 ASSERT(currentOffset > offset); | 380 ASSERT(currentOffset > offset); |
381 ASSERT(canTraverseBackward()); | 381 ASSERT(canTraverseBackward()); |
382 if (shouldOnlyIncludeDirectChildren()) { | 382 if (shouldOnlyIncludeDirectChildren()) { |
383 IsMatch<HTMLCollection> isMatch(*this); | 383 IsMatch<HTMLCollection> isMatch(*this); |
384 for (Element* previous = ElementTraversal::previousSibling(currentElemen
t, isMatch); previous; previous = ElementTraversal::previousSibling(*previous, i
sMatch)) { | 384 for (Element* previous = ElementTraversal::previousSibling(currentElemen
t, isMatch); previous; previous = ElementTraversal::previousSibling(*previous, i
sMatch)) { |
385 if (--currentOffset == offset) | 385 if (--currentOffset == offset) |
386 return previous; | 386 return previous; |
387 } | 387 } |
388 return 0; | 388 return nullptr; |
389 } | 389 } |
390 return traverseMatchingElementsBackwardToOffset(currentElement, &rootNode(),
offset, currentOffset, makeIsMatch(*this)); | 390 return traverseMatchingElementsBackwardToOffset(currentElement, &rootNode(),
offset, currentOffset, makeIsMatch(*this)); |
391 } | 391 } |
392 | 392 |
393 Element* HTMLCollection::namedItem(const AtomicString& name) const | 393 Element* HTMLCollection::namedItem(const AtomicString& name) const |
394 { | 394 { |
395 // http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/namedit
em.asp | 395 // http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/namedit
em.asp |
396 // This method first searches for an object with a matching id | 396 // This method first searches for an object with a matching id |
397 // attribute. If a match is not found, the method then searches for an | 397 // attribute. If a match is not found, the method then searches for an |
398 // object with a matching name attribute, but only on those elements | 398 // object with a matching name attribute, but only on those elements |
399 // that are allowed a name attribute. | 399 // that are allowed a name attribute. |
400 updateIdNameCache(); | 400 updateIdNameCache(); |
401 | 401 |
402 const NamedItemCache& cache = namedItemCache(); | 402 const NamedItemCache& cache = namedItemCache(); |
403 WillBeHeapVector<RawPtrWillBeMember<Element> >* idResults = cache.getElement
sById(name); | 403 WillBeHeapVector<RawPtrWillBeMember<Element>>* idResults = cache.getElements
ById(name); |
404 if (idResults && !idResults->isEmpty()) | 404 if (idResults && !idResults->isEmpty()) |
405 return idResults->first(); | 405 return idResults->first(); |
406 | 406 |
407 WillBeHeapVector<RawPtrWillBeMember<Element> >* nameResults = cache.getEleme
ntsByName(name); | 407 WillBeHeapVector<RawPtrWillBeMember<Element>>* nameResults = cache.getElemen
tsByName(name); |
408 if (nameResults && !nameResults->isEmpty()) | 408 if (nameResults && !nameResults->isEmpty()) |
409 return nameResults->first(); | 409 return nameResults->first(); |
410 | 410 |
411 return 0; | 411 return nullptr; |
412 } | 412 } |
413 | 413 |
414 bool HTMLCollection::namedPropertyQuery(const AtomicString& name, ExceptionState
&) | 414 bool HTMLCollection::namedPropertyQuery(const AtomicString& name, ExceptionState
&) |
415 { | 415 { |
416 return namedItem(name); | 416 return namedItem(name); |
417 } | 417 } |
418 | 418 |
419 void HTMLCollection::supportedPropertyNames(Vector<String>& names) | 419 void HTMLCollection::supportedPropertyNames(Vector<String>& names) |
420 { | 420 { |
421 // As per the specification (http://dom.spec.whatwg.org/#htmlcollection): | 421 // As per the specification (http://dom.spec.whatwg.org/#htmlcollection): |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 if (!element->isHTMLElement()) | 467 if (!element->isHTMLElement()) |
468 continue; | 468 continue; |
469 const AtomicString& nameAttrVal = element->getNameAttribute(); | 469 const AtomicString& nameAttrVal = element->getNameAttribute(); |
470 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != Doc
All || nameShouldBeVisibleInDocumentAll(toHTMLElement(*element)))) | 470 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != Doc
All || nameShouldBeVisibleInDocumentAll(toHTMLElement(*element)))) |
471 cache->addElementWithName(nameAttrVal, element); | 471 cache->addElementWithName(nameAttrVal, element); |
472 } | 472 } |
473 // Set the named item cache last as traversing the tree may cause cache inva
lidation. | 473 // Set the named item cache last as traversing the tree may cause cache inva
lidation. |
474 setNamedItemCache(cache.release()); | 474 setNamedItemCache(cache.release()); |
475 } | 475 } |
476 | 476 |
477 void HTMLCollection::namedItems(const AtomicString& name, WillBeHeapVector<RefPt
rWillBeMember<Element> >& result) const | 477 void HTMLCollection::namedItems(const AtomicString& name, WillBeHeapVector<RefPt
rWillBeMember<Element>>& result) const |
478 { | 478 { |
479 ASSERT(result.isEmpty()); | 479 ASSERT(result.isEmpty()); |
480 if (name.isEmpty()) | 480 if (name.isEmpty()) |
481 return; | 481 return; |
482 | 482 |
483 updateIdNameCache(); | 483 updateIdNameCache(); |
484 | 484 |
485 const NamedItemCache& cache = namedItemCache(); | 485 const NamedItemCache& cache = namedItemCache(); |
486 if (WillBeHeapVector<RawPtrWillBeMember<Element> >* idResults = cache.getEle
mentsById(name)) { | 486 if (WillBeHeapVector<RawPtrWillBeMember<Element>>* idResults = cache.getElem
entsById(name)) { |
487 for (unsigned i = 0; i < idResults->size(); ++i) | 487 for (unsigned i = 0; i < idResults->size(); ++i) |
488 result.append(idResults->at(i)); | 488 result.append(idResults->at(i)); |
489 } | 489 } |
490 if (WillBeHeapVector<RawPtrWillBeMember<Element> >* nameResults = cache.getE
lementsByName(name)) { | 490 if (WillBeHeapVector<RawPtrWillBeMember<Element>>* nameResults = cache.getEl
ementsByName(name)) { |
491 for (unsigned i = 0; i < nameResults->size(); ++i) | 491 for (unsigned i = 0; i < nameResults->size(); ++i) |
492 result.append(nameResults->at(i)); | 492 result.append(nameResults->at(i)); |
493 } | 493 } |
494 } | 494 } |
495 | 495 |
496 HTMLCollection::NamedItemCache::NamedItemCache() | 496 HTMLCollection::NamedItemCache::NamedItemCache() |
497 { | 497 { |
498 } | 498 } |
499 | 499 |
500 void HTMLCollection::trace(Visitor* visitor) | 500 void HTMLCollection::trace(Visitor* visitor) |
501 { | 501 { |
502 visitor->trace(m_namedItemCache); | 502 visitor->trace(m_namedItemCache); |
503 visitor->trace(m_collectionItemsCache); | 503 visitor->trace(m_collectionItemsCache); |
504 LiveNodeListBase::trace(visitor); | 504 LiveNodeListBase::trace(visitor); |
505 } | 505 } |
506 | 506 |
507 } // namespace blink | 507 } // namespace blink |
OLD | NEW |