Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: Source/core/html/HTMLCollection.cpp

Issue 67473002: Have ElementTraversal / NodeTraversal's next() methods take a reference (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebase on master Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/html/HTMLCollection.h ('k') | Source/core/html/HTMLDialogElement.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 if (type() == ChildNodeListType) 299 if (type() == ChildNodeListType)
300 return current; 300 return current;
301 return iterateForPreviousNode(current); 301 return iterateForPreviousNode(current);
302 } 302 }
303 303
304 template <class NodeListType> 304 template <class NodeListType>
305 inline Element* firstMatchingElement(const NodeListType* nodeList, ContainerNode * root) 305 inline Element* firstMatchingElement(const NodeListType* nodeList, ContainerNode * root)
306 { 306 {
307 Element* element = ElementTraversal::firstWithin(root); 307 Element* element = ElementTraversal::firstWithin(root);
308 while (element && !isMatchingElement(nodeList, element)) 308 while (element && !isMatchingElement(nodeList, element))
309 element = ElementTraversal::next(element, root); 309 element = ElementTraversal::next(*element, root);
310 return element; 310 return element;
311 } 311 }
312 312
313 template <class NodeListType> 313 template <class NodeListType>
314 inline Element* nextMatchingElement(const NodeListType* nodeList, Element* curre nt, ContainerNode* root) 314 inline Element* nextMatchingElement(const NodeListType* nodeList, Element& curre nt, ContainerNode* root)
315 { 315 {
316 Element* next = &current;
316 do { 317 do {
317 current = ElementTraversal::next(current, root); 318 next = ElementTraversal::next(*next, root);
318 } while (current && !isMatchingElement(nodeList, current)); 319 } while (next && !isMatchingElement(nodeList, next));
319 return current; 320 return next;
320 } 321 }
321 322
322 template <class NodeListType> 323 template <class NodeListType>
323 inline Element* traverseMatchingElementsForwardToOffset(const NodeListType* node List, unsigned offset, Element* currentElement, unsigned& currentOffset, Contain erNode* root) 324 inline Element* traverseMatchingElementsForwardToOffset(const NodeListType* node List, unsigned offset, Element& currentElement, unsigned& currentOffset, Contain erNode* root)
324 { 325 {
325 ASSERT(currentOffset < offset); 326 ASSERT(currentOffset < offset);
326 while ((currentElement = nextMatchingElement(nodeList, currentElement, root) )) { 327 Element* next = &currentElement;
328 while ((next = nextMatchingElement(nodeList, *next, root))) {
327 if (++currentOffset == offset) 329 if (++currentOffset == offset)
328 return currentElement; 330 return next;
329 } 331 }
330 return 0; 332 return 0;
331 } 333 }
332 334
333 // FIXME: This should be in ChildNodeList 335 // FIXME: This should be in ChildNodeList
334 inline Node* LiveNodeListBase::traverseChildNodeListForwardToOffset(unsigned off set, Node* currentNode, unsigned& currentOffset) const 336 inline Node* LiveNodeListBase::traverseChildNodeListForwardToOffset(unsigned off set, Node* currentNode, unsigned& currentOffset) const
335 { 337 {
336 ASSERT(type() == ChildNodeListType); 338 ASSERT(type() == ChildNodeListType);
337 ASSERT(currentOffset < offset); 339 ASSERT(currentOffset < offset);
338 while ((currentNode = currentNode->nextSibling())) { 340 while ((currentNode = currentNode->nextSibling())) {
339 if (++currentOffset == offset) 341 if (++currentOffset == offset)
340 return currentNode; 342 return currentNode;
341 } 343 }
342 return 0; 344 return 0;
343 } 345 }
344 346
345 // FIXME: This should be in LiveNodeList 347 // FIXME: This should be in LiveNodeList
346 inline Element* LiveNodeListBase::traverseLiveNodeListFirstElement(ContainerNode * root) const 348 inline Element* LiveNodeListBase::traverseLiveNodeListFirstElement(ContainerNode * root) const
347 { 349 {
348 ASSERT(isNodeList(type())); 350 ASSERT(isNodeList(type()));
349 ASSERT(type() != ChildNodeListType); 351 ASSERT(type() != ChildNodeListType);
350 if (type() == HTMLTagNodeListType) 352 if (type() == HTMLTagNodeListType)
351 return firstMatchingElement(static_cast<const HTMLTagNodeList*>(this), r oot); 353 return firstMatchingElement(static_cast<const HTMLTagNodeList*>(this), r oot);
352 if (type() == ClassNodeListType) 354 if (type() == ClassNodeListType)
353 return firstMatchingElement(static_cast<const ClassNodeList*>(this), roo t); 355 return firstMatchingElement(static_cast<const ClassNodeList*>(this), roo t);
354 return firstMatchingElement(static_cast<const LiveNodeList*>(this), root); 356 return firstMatchingElement(static_cast<const LiveNodeList*>(this), root);
355 } 357 }
356 358
357 // FIXME: This should be in LiveNodeList 359 // FIXME: This should be in LiveNodeList
358 inline Element* LiveNodeListBase::traverseLiveNodeListForwardToOffset(unsigned o ffset, Element* currentElement, unsigned& currentOffset, ContainerNode* root) co nst 360 inline Element* LiveNodeListBase::traverseLiveNodeListForwardToOffset(unsigned o ffset, Element& currentElement, unsigned& currentOffset, ContainerNode* root) co nst
359 { 361 {
360 ASSERT(isNodeList(type())); 362 ASSERT(isNodeList(type()));
361 ASSERT(type() != ChildNodeListType); 363 ASSERT(type() != ChildNodeListType);
362 if (type() == HTMLTagNodeListType) 364 if (type() == HTMLTagNodeListType)
363 return traverseMatchingElementsForwardToOffset(static_cast<const HTMLTag NodeList*>(this), offset, currentElement, currentOffset, root); 365 return traverseMatchingElementsForwardToOffset(static_cast<const HTMLTag NodeList*>(this), offset, currentElement, currentOffset, root);
364 if (type() == ClassNodeListType) 366 if (type() == ClassNodeListType)
365 return traverseMatchingElementsForwardToOffset(static_cast<const ClassNo deList*>(this), offset, currentElement, currentOffset, root); 367 return traverseMatchingElementsForwardToOffset(static_cast<const ClassNo deList*>(this), offset, currentElement, currentOffset, root);
366 return traverseMatchingElementsForwardToOffset(static_cast<const LiveNodeLis t*>(this), offset, currentElement, currentOffset, root); 368 return traverseMatchingElementsForwardToOffset(static_cast<const LiveNodeLis t*>(this), offset, currentElement, currentOffset, root);
367 } 369 }
368 370
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 } 471 }
470 } 472 }
471 ASSERT_NOT_REACHED(); 473 ASSERT_NOT_REACHED();
472 return 0; 474 return 0;
473 } 475 }
474 476
475 unsigned offsetInArray = 0; 477 unsigned offsetInArray = 0;
476 if (type() == ChildNodeListType) 478 if (type() == ChildNodeListType)
477 currentItem = traverseChildNodeListForwardToOffset(offset, currentItem, currentOffset); 479 currentItem = traverseChildNodeListForwardToOffset(offset, currentItem, currentOffset);
478 else if (isNodeList(type())) 480 else if (isNodeList(type()))
479 currentItem = traverseLiveNodeListForwardToOffset(offset, toElement(curr entItem), currentOffset, root); 481 currentItem = traverseLiveNodeListForwardToOffset(offset, toElement(*cur rentItem), currentOffset, root);
480 else 482 else
481 currentItem = static_cast<const HTMLCollection*>(this)->traverseForwardT oOffset(offset, toElement(currentItem), currentOffset, offsetInArray, root); 483 currentItem = static_cast<const HTMLCollection*>(this)->traverseForwardT oOffset(offset, toElement(*currentItem), currentOffset, offsetInArray, root);
482 484
483 if (!currentItem) { 485 if (!currentItem) {
484 // Did not find the item. On plus side, we now know the length. 486 // Did not find the item. On plus side, we now know the length.
485 setLengthCache(currentOffset + 1); 487 setLengthCache(currentOffset + 1);
486 return 0; 488 return 0;
487 } 489 }
488 setItemCache(currentItem, currentOffset, offsetInArray); 490 setItemCache(currentItem, currentOffset, offsetInArray);
489 return currentItem; 491 return currentItem;
490 } 492 }
491 493
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 inline Element* HTMLCollection::traverseFirstElement(unsigned& offsetInArray, Co ntainerNode* root) const 544 inline Element* HTMLCollection::traverseFirstElement(unsigned& offsetInArray, Co ntainerNode* root) const
543 { 545 {
544 if (overridesItemAfter()) 546 if (overridesItemAfter())
545 return virtualItemAfter(offsetInArray, 0); 547 return virtualItemAfter(offsetInArray, 0);
546 ASSERT(!offsetInArray); 548 ASSERT(!offsetInArray);
547 if (shouldOnlyIncludeDirectChildren()) 549 if (shouldOnlyIncludeDirectChildren())
548 return firstMatchingChildElement(static_cast<const HTMLCollection*>(this ), root); 550 return firstMatchingChildElement(static_cast<const HTMLCollection*>(this ), root);
549 return firstMatchingElement(static_cast<const HTMLCollection*>(this), root); 551 return firstMatchingElement(static_cast<const HTMLCollection*>(this), root);
550 } 552 }
551 553
552 inline Element* HTMLCollection::traverseNextElement(unsigned& offsetInArray, Ele ment* previous, ContainerNode* root) const 554 inline Element* HTMLCollection::traverseNextElement(unsigned& offsetInArray, Ele ment& previous, ContainerNode* root) const
553 { 555 {
554 if (overridesItemAfter()) 556 if (overridesItemAfter())
555 return virtualItemAfter(offsetInArray, previous); 557 return virtualItemAfter(offsetInArray, &previous);
556 ASSERT(!offsetInArray); 558 ASSERT(!offsetInArray);
557 if (shouldOnlyIncludeDirectChildren()) 559 if (shouldOnlyIncludeDirectChildren())
558 return nextMatchingChildElement(this, previous, root); 560 return nextMatchingChildElement(this, &previous, root);
559 return nextMatchingElement(this, previous, root); 561 return nextMatchingElement(this, previous, root);
560 } 562 }
561 563
562 inline Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element * currentElement, unsigned& currentOffset, unsigned& offsetInArray, ContainerNod e* root) const 564 inline Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element & currentElement, unsigned& currentOffset, unsigned& offsetInArray, ContainerNod e* root) const
563 { 565 {
564 ASSERT(currentOffset < offset); 566 ASSERT(currentOffset < offset);
565 if (overridesItemAfter()) { 567 if (overridesItemAfter()) {
566 offsetInArray = m_cachedElementsArrayOffset; 568 offsetInArray = m_cachedElementsArrayOffset;
567 while ((currentElement = virtualItemAfter(offsetInArray, currentElement) )) { 569 Element* next = &currentElement;
570 while ((next = virtualItemAfter(offsetInArray, next))) {
568 if (++currentOffset == offset) 571 if (++currentOffset == offset)
569 return currentElement; 572 return next;
570 } 573 }
571 return 0; 574 return 0;
572 } 575 }
573 if (shouldOnlyIncludeDirectChildren()) { 576 if (shouldOnlyIncludeDirectChildren()) {
574 while ((currentElement = nextMatchingChildElement(this, currentElement, root))) { 577 Element* next = &currentElement;
578 while ((next = nextMatchingChildElement(this, next, root))) {
575 if (++currentOffset == offset) 579 if (++currentOffset == offset)
576 return currentElement; 580 return next;
577 } 581 }
578 return 0; 582 return 0;
579 } 583 }
580 return traverseMatchingElementsForwardToOffset(this, offset, currentElement, currentOffset, root); 584 return traverseMatchingElementsForwardToOffset(this, offset, currentElement, currentOffset, root);
581 } 585 }
582 586
583 Node* HTMLCollection::namedItem(const AtomicString& name) const 587 Node* HTMLCollection::namedItem(const AtomicString& name) const
584 { 588 {
585 // http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/namedit em.asp 589 // http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/namedit em.asp
586 // This method first searches for an object with a matching id 590 // This method first searches for an object with a matching id
587 // attribute. If a match is not found, the method then searches for an 591 // attribute. If a match is not found, the method then searches for an
588 // object with a matching name attribute, but only on those elements 592 // object with a matching name attribute, but only on those elements
589 // that are allowed a name attribute. 593 // that are allowed a name attribute.
590 594
591 ContainerNode* root = rootContainerNode(); 595 ContainerNode* root = rootContainerNode();
592 if (!root) 596 if (!root)
593 return 0; 597 return 0;
594 598
595 unsigned arrayOffset = 0; 599 unsigned arrayOffset = 0;
596 unsigned i = 0; 600 unsigned i = 0;
597 for (Element* element = traverseFirstElement(arrayOffset, root); element; el ement = traverseNextElement(arrayOffset, element, root)) { 601 for (Element* element = traverseFirstElement(arrayOffset, root); element; el ement = traverseNextElement(arrayOffset, *element, root)) {
598 if (checkForNameMatch(element, /* checkName */ false, name)) { 602 if (checkForNameMatch(element, /* checkName */ false, name)) {
599 setItemCache(element, i, arrayOffset); 603 setItemCache(element, i, arrayOffset);
600 return element; 604 return element;
601 } 605 }
602 i++; 606 i++;
603 } 607 }
604 608
605 i = 0; 609 i = 0;
606 for (Element* element = traverseFirstElement(arrayOffset, root); element; el ement = traverseNextElement(arrayOffset, element, root)) { 610 for (Element* element = traverseFirstElement(arrayOffset, root); element; el ement = traverseNextElement(arrayOffset, *element, root)) {
607 if (checkForNameMatch(element, /* checkName */ true, name)) { 611 if (checkForNameMatch(element, /* checkName */ true, name)) {
608 setItemCache(element, i, arrayOffset); 612 setItemCache(element, i, arrayOffset);
609 return element; 613 return element;
610 } 614 }
611 i++; 615 i++;
612 } 616 }
613 617
614 return 0; 618 return 0;
615 } 619 }
616 620
617 void HTMLCollection::updateNameCache() const 621 void HTMLCollection::updateNameCache() const
618 { 622 {
619 if (hasNameCache()) 623 if (hasNameCache())
620 return; 624 return;
621 625
622 ContainerNode* root = rootContainerNode(); 626 ContainerNode* root = rootContainerNode();
623 if (!root) 627 if (!root)
624 return; 628 return;
625 629
626 unsigned arrayOffset = 0; 630 unsigned arrayOffset = 0;
627 for (Element* element = traverseFirstElement(arrayOffset, root); element; el ement = traverseNextElement(arrayOffset, element, root)) { 631 for (Element* element = traverseFirstElement(arrayOffset, root); element; el ement = traverseNextElement(arrayOffset, *element, root)) {
628 const AtomicString& idAttrVal = element->getIdAttribute(); 632 const AtomicString& idAttrVal = element->getIdAttribute();
629 if (!idAttrVal.isEmpty()) 633 if (!idAttrVal.isEmpty())
630 appendIdCache(idAttrVal, element); 634 appendIdCache(idAttrVal, element);
631 if (!element->isHTMLElement()) 635 if (!element->isHTMLElement())
632 continue; 636 continue;
633 const AtomicString& nameAttrVal = element->getNameAttribute(); 637 const AtomicString& nameAttrVal = element->getNameAttribute();
634 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != Doc All || nameShouldBeVisibleInDocumentAll(toHTMLElement(element)))) 638 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != Doc All || nameShouldBeVisibleInDocumentAll(toHTMLElement(element))))
635 appendNameCache(nameAttrVal, element); 639 appendNameCache(nameAttrVal, element);
636 } 640 }
637 641
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 682
679 void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element* element) 683 void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element* element)
680 { 684 {
681 OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->v alue; 685 OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->v alue;
682 if (!vector) 686 if (!vector)
683 vector = adoptPtr(new Vector<Element*>); 687 vector = adoptPtr(new Vector<Element*>);
684 vector->append(element); 688 vector->append(element);
685 } 689 }
686 690
687 } // namespace WebCore 691 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/html/HTMLCollection.h ('k') | Source/core/html/HTMLDialogElement.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698