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