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 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 for (Node* current = descendant; current; current = current->lastChild()) | 284 for (Node* current = descendant; current; current = current->lastChild()) |
285 descendant = current; | 285 descendant = current; |
286 return descendant; | 286 return descendant; |
287 } | 287 } |
288 | 288 |
289 static Node* lastNode(const Node& rootNode, bool onlyIncludeDirectChildren) | 289 static Node* lastNode(const Node& rootNode, bool onlyIncludeDirectChildren) |
290 { | 290 { |
291 return onlyIncludeDirectChildren ? rootNode.lastChild() : lastDescendant(roo
tNode); | 291 return onlyIncludeDirectChildren ? rootNode.lastChild() : lastDescendant(roo
tNode); |
292 } | 292 } |
293 | 293 |
294 ALWAYS_INLINE Node* LiveNodeListBase::iterateForPreviousNode(Node* current) cons
t | 294 template <typename Collection> |
| 295 ALWAYS_INLINE Element* LiveNodeListBase::iterateForPreviousNode(const Collection
& collection, Node* current) |
295 { | 296 { |
296 bool onlyIncludeDirectChildren = shouldOnlyIncludeDirectChildren(); | 297 bool onlyIncludeDirectChildren = collection.shouldOnlyIncludeDirectChildren(
); |
297 CollectionType collectionType = type(); | 298 Node& rootNode = collection.rootNode(); |
298 Node& rootNode = this->rootNode(); | |
299 for (; current; current = previousNode(rootNode, *current, onlyIncludeDirect
Children)) { | 299 for (; current; current = previousNode(rootNode, *current, onlyIncludeDirect
Children)) { |
300 if (isLiveNodeListType(collectionType)) { | 300 if (current->isElementNode() && isMatchingElement(collection, toElement(
*current))) |
301 if (current->isElementNode() && isMatchingElement(static_cast<const
LiveNodeList&>(*this), toElement(*current))) | 301 return toElement(current); |
302 return toElement(current); | |
303 } else { | |
304 if (current->isElementNode() && isMatchingElement(static_cast<const
HTMLCollection&>(*this), toElement(*current))) | |
305 return toElement(current); | |
306 } | |
307 } | 302 } |
308 return 0; | 303 return 0; |
309 } | 304 } |
310 | 305 |
311 Node* LiveNodeListBase::itemBefore(const Node* previous) const | 306 template <typename Collection> |
| 307 Element* LiveNodeListBase::itemBefore(const Collection& collection, const Node*
previous) |
312 { | 308 { |
313 Node* current; | 309 Node* current; |
314 if (LIKELY(!!previous)) // Without this LIKELY, length() and item() can be 1
0% slower. | 310 if (LIKELY(!!previous)) // Without this LIKELY, length() and item() can be 1
0% slower. |
315 current = previousNode(rootNode(), *previous, shouldOnlyIncludeDirectChi
ldren()); | 311 current = previousNode(collection.rootNode(), *previous, collection.shou
ldOnlyIncludeDirectChildren()); |
316 else | 312 else |
317 current = lastNode(rootNode(), shouldOnlyIncludeDirectChildren()); | 313 current = lastNode(collection.rootNode(), collection.shouldOnlyIncludeDi
rectChildren()); |
318 | 314 |
| 315 return iterateForPreviousNode(collection, current); |
| 316 } |
| 317 |
| 318 Node* LiveNodeList::itemBefore(const Node* previous) const |
| 319 { |
319 if (type() == ChildNodeListType) | 320 if (type() == ChildNodeListType) |
320 return current; | 321 return LIKELY(!!previous) ? previous->previousSibling() : rootNode().las
tChild(); |
321 return iterateForPreviousNode(current); | 322 return LiveNodeListBase::itemBefore(*this, previous); |
| 323 } |
| 324 |
| 325 Element* HTMLCollection::itemBefore(const Node* previous) const |
| 326 { |
| 327 return LiveNodeListBase::itemBefore(*this, previous); |
322 } | 328 } |
323 | 329 |
324 template <class NodeListType> | 330 template <class NodeListType> |
325 inline Element* firstMatchingElement(const NodeListType& nodeList, const Contain
erNode& root) | 331 inline Element* firstMatchingElement(const NodeListType& nodeList, const Contain
erNode& root) |
326 { | 332 { |
327 Element* element = ElementTraversal::firstWithin(root); | 333 Element* element = ElementTraversal::firstWithin(root); |
328 while (element && !isMatchingElement(nodeList, *element)) | 334 while (element && !isMatchingElement(nodeList, *element)) |
329 element = ElementTraversal::next(*element, &root); | 335 element = ElementTraversal::next(*element, &root); |
330 return element; | 336 return element; |
331 } | 337 } |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 | 456 |
451 inline Element* HTMLCollection::traverseNextElement(Element& previous, const Con
tainerNode& root) const | 457 inline Element* HTMLCollection::traverseNextElement(Element& previous, const Con
tainerNode& root) const |
452 { | 458 { |
453 if (overridesItemAfter()) | 459 if (overridesItemAfter()) |
454 return virtualItemAfter(&previous); | 460 return virtualItemAfter(&previous); |
455 if (shouldOnlyIncludeDirectChildren()) | 461 if (shouldOnlyIncludeDirectChildren()) |
456 return nextMatchingChildElement(*this, previous, root); | 462 return nextMatchingChildElement(*this, previous, root); |
457 return nextMatchingElement(*this, previous, root); | 463 return nextMatchingElement(*this, previous, root); |
458 } | 464 } |
459 | 465 |
460 Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Node& currentE
lement, unsigned& currentOffset, const ContainerNode& root) const | 466 Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element& curre
ntElement, unsigned& currentOffset, const ContainerNode& root) const |
461 { | 467 { |
462 ASSERT(currentOffset < offset); | 468 ASSERT(currentOffset < offset); |
463 if (overridesItemAfter()) { | 469 if (overridesItemAfter()) { |
464 Element* next = &toElement(currentElement); | 470 Element* next = ¤tElement; |
465 while ((next = virtualItemAfter(next))) { | 471 while ((next = virtualItemAfter(next))) { |
466 if (++currentOffset == offset) | 472 if (++currentOffset == offset) |
467 return next; | 473 return next; |
468 } | 474 } |
469 return 0; | 475 return 0; |
470 } | 476 } |
471 if (shouldOnlyIncludeDirectChildren()) { | 477 if (shouldOnlyIncludeDirectChildren()) { |
472 Element* next = &toElement(currentElement); | 478 Element* next = ¤tElement; |
473 while ((next = nextMatchingChildElement(*this, *next, root))) { | 479 while ((next = nextMatchingChildElement(*this, *next, root))) { |
474 if (++currentOffset == offset) | 480 if (++currentOffset == offset) |
475 return next; | 481 return next; |
476 } | 482 } |
477 return 0; | 483 return 0; |
478 } | 484 } |
479 return traverseMatchingElementsForwardToOffset(*this, offset, toElement(curr
entElement), currentOffset, root); | 485 return traverseMatchingElementsForwardToOffset(*this, offset, currentElement
, currentOffset, root); |
480 } | 486 } |
481 | 487 |
482 Element* HTMLCollection::namedItem(const AtomicString& name) const | 488 Element* HTMLCollection::namedItem(const AtomicString& name) const |
483 { | 489 { |
484 // http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/namedit
em.asp | 490 // http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/namedit
em.asp |
485 // This method first searches for an object with a matching id | 491 // This method first searches for an object with a matching id |
486 // attribute. If a match is not found, the method then searches for an | 492 // attribute. If a match is not found, the method then searches for an |
487 // object with a matching name attribute, but only on those elements | 493 // object with a matching name attribute, but only on those elements |
488 // that are allowed a name attribute. | 494 // that are allowed a name attribute. |
489 | 495 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 | 555 |
550 void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element*
element) | 556 void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element*
element) |
551 { | 557 { |
552 OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->v
alue; | 558 OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->v
alue; |
553 if (!vector) | 559 if (!vector) |
554 vector = adoptPtr(new Vector<Element*>); | 560 vector = adoptPtr(new Vector<Element*>); |
555 vector->append(element); | 561 vector->append(element); |
556 } | 562 } |
557 | 563 |
558 } // namespace WebCore | 564 } // namespace WebCore |
OLD | NEW |