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

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

Issue 224303004: Stop passing the root node to node lists traversal functions (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 8 months 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 | Annotate | Revision Log
« no previous file with comments | « Source/core/html/HTMLCollection.h ('k') | no next file » | 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 * 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 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 || element.hasLocalName(formTag) 299 || element.hasLocalName(formTag)
300 || element.hasLocalName(frameTag) 300 || element.hasLocalName(frameTag)
301 || element.hasLocalName(framesetTag) 301 || element.hasLocalName(framesetTag)
302 || element.hasLocalName(iframeTag) 302 || element.hasLocalName(iframeTag)
303 || element.hasLocalName(imgTag) 303 || element.hasLocalName(imgTag)
304 || element.hasLocalName(inputTag) 304 || element.hasLocalName(inputTag)
305 || element.hasLocalName(objectTag) 305 || element.hasLocalName(objectTag)
306 || element.hasLocalName(selectTag); 306 || element.hasLocalName(selectTag);
307 } 307 }
308 308
309 inline Element* firstMatchingChildElement(const HTMLCollection& nodeList, const ContainerNode& root) 309 inline Element* firstMatchingChildElement(const HTMLCollection& nodeList)
310 { 310 {
311 Element* element = ElementTraversal::firstChild(root); 311 Element* element = ElementTraversal::firstChild(nodeList.rootNode());
312 while (element && !isMatchingElement(nodeList, *element)) 312 while (element && !isMatchingElement(nodeList, *element))
313 element = ElementTraversal::nextSibling(*element); 313 element = ElementTraversal::nextSibling(*element);
314 return element; 314 return element;
315 } 315 }
316 316
317 inline Element* nextMatchingChildElement(const HTMLCollection& nodeList, Element & current) 317 inline Element* nextMatchingChildElement(const HTMLCollection& nodeList, Element & current)
318 { 318 {
319 Element* next = &current; 319 Element* next = &current;
320 do { 320 do {
321 next = ElementTraversal::nextSibling(*next); 321 next = ElementTraversal::nextSibling(*next);
322 } while (next && !isMatchingElement(nodeList, *next)); 322 } while (next && !isMatchingElement(nodeList, *next));
323 return next; 323 return next;
324 } 324 }
325 325
326 Element* HTMLCollection::traverseToFirstElement(const ContainerNode& root) const 326 Element* HTMLCollection::traverseToFirstElement() const
327 { 327 {
328 switch (type()) { 328 switch (type()) {
329 case HTMLTagCollectionType: 329 case HTMLTagCollectionType:
330 return firstMatchingElement(static_cast<const HTMLTagCollection&>(*this) , root); 330 return firstMatchingElement(static_cast<const HTMLTagCollection&>(*this) );
331 case ClassCollectionType: 331 case ClassCollectionType:
332 return firstMatchingElement(static_cast<const ClassCollection&>(*this), root); 332 return firstMatchingElement(static_cast<const ClassCollection&>(*this));
333 default: 333 default:
334 if (overridesItemAfter()) 334 if (overridesItemAfter())
335 return virtualItemAfter(0); 335 return virtualItemAfter(0);
336 if (shouldOnlyIncludeDirectChildren()) 336 if (shouldOnlyIncludeDirectChildren())
337 return firstMatchingChildElement(*this, root); 337 return firstMatchingChildElement(*this);
338 return firstMatchingElement(*this, root); 338 return firstMatchingElement(*this);
339 } 339 }
340 } 340 }
341 341
342 inline Element* HTMLCollection::traverseNextElement(Element& previous, const Con tainerNode& root) const 342 inline Element* HTMLCollection::traverseNextElement(Element& previous) const
343 { 343 {
344 if (overridesItemAfter()) 344 if (overridesItemAfter())
345 return virtualItemAfter(&previous); 345 return virtualItemAfter(&previous);
346 if (shouldOnlyIncludeDirectChildren()) 346 if (shouldOnlyIncludeDirectChildren())
347 return nextMatchingChildElement(*this, previous); 347 return nextMatchingChildElement(*this, previous);
348 return nextMatchingElement(*this, previous, root); 348 return nextMatchingElement(*this, previous);
349 } 349 }
350 350
351 Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element& curre ntElement, unsigned& currentOffset, const ContainerNode& root) const 351 Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element& curre ntElement, unsigned& currentOffset) const
352 { 352 {
353 ASSERT(currentOffset < offset); 353 ASSERT(currentOffset < offset);
354 switch (type()) { 354 switch (type()) {
355 case HTMLTagCollectionType: 355 case HTMLTagCollectionType:
356 return traverseMatchingElementsForwardToOffset(static_cast<const HTMLTag Collection&>(*this), offset, currentElement, currentOffset, root); 356 return traverseMatchingElementsForwardToOffset(static_cast<const HTMLTag Collection&>(*this), offset, currentElement, currentOffset);
357 case ClassCollectionType: 357 case ClassCollectionType:
358 return traverseMatchingElementsForwardToOffset(static_cast<const ClassCo llection&>(*this), offset, currentElement, currentOffset, root); 358 return traverseMatchingElementsForwardToOffset(static_cast<const ClassCo llection&>(*this), offset, currentElement, currentOffset);
359 default: 359 default:
360 if (overridesItemAfter()) { 360 if (overridesItemAfter()) {
361 Element* next = &currentElement; 361 Element* next = &currentElement;
362 while ((next = virtualItemAfter(next))) { 362 while ((next = virtualItemAfter(next))) {
363 if (++currentOffset == offset) 363 if (++currentOffset == offset)
364 return next; 364 return next;
365 } 365 }
366 return 0; 366 return 0;
367 } 367 }
368 if (shouldOnlyIncludeDirectChildren()) { 368 if (shouldOnlyIncludeDirectChildren()) {
369 Element* next = &currentElement; 369 Element* next = &currentElement;
370 while ((next = nextMatchingChildElement(*this, *next))) { 370 while ((next = nextMatchingChildElement(*this, *next))) {
371 if (++currentOffset == offset) 371 if (++currentOffset == offset)
372 return next; 372 return next;
373 } 373 }
374 return 0; 374 return 0;
375 } 375 }
376 return traverseMatchingElementsForwardToOffset(*this, offset, currentEle ment, currentOffset, root); 376 return traverseMatchingElementsForwardToOffset(*this, offset, currentEle ment, currentOffset);
377 } 377 }
378 } 378 }
379 379
380 Element* HTMLCollection::namedItem(const AtomicString& name) const 380 Element* HTMLCollection::namedItem(const AtomicString& name) const
381 { 381 {
382 // http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/namedit em.asp 382 // http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/namedit em.asp
383 // This method first searches for an object with a matching id 383 // This method first searches for an object with a matching id
384 // attribute. If a match is not found, the method then searches for an 384 // attribute. If a match is not found, the method then searches for an
385 // object with a matching name attribute, but only on those elements 385 // object with a matching name attribute, but only on those elements
386 // that are allowed a name attribute. 386 // that are allowed a name attribute.
(...skipping 20 matching lines...) Expand all
407 { 407 {
408 // As per the specification (http://dom.spec.whatwg.org/#htmlcollection): 408 // As per the specification (http://dom.spec.whatwg.org/#htmlcollection):
409 // The supported property names are the values from the list returned by the se steps: 409 // The supported property names are the values from the list returned by the se steps:
410 // 1. Let result be an empty list. 410 // 1. Let result be an empty list.
411 // 2. For each element represented by the collection, in tree order, run the se substeps: 411 // 2. For each element represented by the collection, in tree order, run the se substeps:
412 // 1. If element has an ID which is neither the empty string nor is in res ult, append element's ID to result. 412 // 1. If element has an ID which is neither the empty string nor is in res ult, append element's ID to result.
413 // 2. If element is in the HTML namespace and has a name attribute whose v alue is neither the empty string 413 // 2. If element is in the HTML namespace and has a name attribute whose v alue is neither the empty string
414 // nor is in result, append element's name attribute value to result. 414 // nor is in result, append element's name attribute value to result.
415 // 3. Return result. 415 // 3. Return result.
416 HashSet<AtomicString> existingNames; 416 HashSet<AtomicString> existingNames;
417 ContainerNode& root = rootNode(); 417 for (Element* element = traverseToFirstElement(); element; element = travers eNextElement(*element)) {
418 for (Element* element = traverseToFirstElement(root); element; element = tra verseNextElement(*element, root)) {
419 const AtomicString& idAttribute = element->getIdAttribute(); 418 const AtomicString& idAttribute = element->getIdAttribute();
420 if (!idAttribute.isEmpty()) { 419 if (!idAttribute.isEmpty()) {
421 HashSet<AtomicString>::AddResult addResult = existingNames.add(idAtt ribute); 420 HashSet<AtomicString>::AddResult addResult = existingNames.add(idAtt ribute);
422 if (addResult.isNewEntry) 421 if (addResult.isNewEntry)
423 names.append(idAttribute); 422 names.append(idAttribute);
424 } 423 }
425 if (!element->isHTMLElement()) 424 if (!element->isHTMLElement())
426 continue; 425 continue;
427 const AtomicString& nameAttribute = element->getNameAttribute(); 426 const AtomicString& nameAttribute = element->getNameAttribute();
428 if (!nameAttribute.isEmpty() && (type() != DocAll || nameShouldBeVisible InDocumentAll(toHTMLElement(*element)))) { 427 if (!nameAttribute.isEmpty() && (type() != DocAll || nameShouldBeVisible InDocumentAll(toHTMLElement(*element)))) {
429 HashSet<AtomicString>::AddResult addResult = existingNames.add(nameA ttribute); 428 HashSet<AtomicString>::AddResult addResult = existingNames.add(nameA ttribute);
430 if (addResult.isNewEntry) 429 if (addResult.isNewEntry)
431 names.append(nameAttribute); 430 names.append(nameAttribute);
432 } 431 }
433 } 432 }
434 } 433 }
435 434
436 void HTMLCollection::namedPropertyEnumerator(Vector<String>& names, ExceptionSta te&) 435 void HTMLCollection::namedPropertyEnumerator(Vector<String>& names, ExceptionSta te&)
437 { 436 {
438 supportedPropertyNames(names); 437 supportedPropertyNames(names);
439 } 438 }
440 439
441 void HTMLCollection::updateIdNameCache() const 440 void HTMLCollection::updateIdNameCache() const
442 { 441 {
443 if (hasValidIdNameCache()) 442 if (hasValidIdNameCache())
444 return; 443 return;
445 444
446 NamedItemCache& cache = createNamedItemCache(); 445 NamedItemCache& cache = createNamedItemCache();
447 ContainerNode& root = rootNode(); 446 for (Element* element = traverseToFirstElement(); element; element = travers eNextElement(*element)) {
448 for (Element* element = traverseToFirstElement(root); element; element = tra verseNextElement(*element, root)) {
449 const AtomicString& idAttrVal = element->getIdAttribute(); 447 const AtomicString& idAttrVal = element->getIdAttribute();
450 if (!idAttrVal.isEmpty()) 448 if (!idAttrVal.isEmpty())
451 cache.addElementWithId(idAttrVal, element); 449 cache.addElementWithId(idAttrVal, element);
452 if (!element->isHTMLElement()) 450 if (!element->isHTMLElement())
453 continue; 451 continue;
454 const AtomicString& nameAttrVal = element->getNameAttribute(); 452 const AtomicString& nameAttrVal = element->getNameAttribute();
455 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != Doc All || nameShouldBeVisibleInDocumentAll(toHTMLElement(*element)))) 453 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != Doc All || nameShouldBeVisibleInDocumentAll(toHTMLElement(*element))))
456 cache.addElementWithName(nameAttrVal, element); 454 cache.addElementWithName(nameAttrVal, element);
457 } 455 }
458 } 456 }
(...skipping 11 matching lines...) Expand all
470 Vector<Element*>* nameResults = cache.getElementsByName(name); 468 Vector<Element*>* nameResults = cache.getElementsByName(name);
471 469
472 for (unsigned i = 0; idResults && i < idResults->size(); ++i) 470 for (unsigned i = 0; idResults && i < idResults->size(); ++i)
473 result.append(idResults->at(i)); 471 result.append(idResults->at(i));
474 472
475 for (unsigned i = 0; nameResults && i < nameResults->size(); ++i) 473 for (unsigned i = 0; nameResults && i < nameResults->size(); ++i)
476 result.append(nameResults->at(i)); 474 result.append(nameResults->at(i));
477 } 475 }
478 476
479 } // namespace WebCore 477 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/html/HTMLCollection.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698