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

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

Issue 141683004: Use more const references in HTMLCollection / LiveNodeList (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 11 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
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 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 ownerNode()->nodeLists()->removeCacheWithAtomicName(this, type()); 180 ownerNode()->nodeLists()->removeCacheWithAtomicName(this, type());
181 } 181 }
182 182
183 void HTMLCollection::invalidateCache() const 183 void HTMLCollection::invalidateCache() const
184 { 184 {
185 LiveNodeListBase::invalidateCache(); 185 LiveNodeListBase::invalidateCache();
186 invalidateIdNameCacheMaps(); 186 invalidateIdNameCacheMaps();
187 } 187 }
188 188
189 template <class NodeListType> 189 template <class NodeListType>
190 inline bool isMatchingElement(const NodeListType*, Element*); 190 inline bool isMatchingElement(const NodeListType&, const Element&);
191 191
192 template <> inline bool isMatchingElement(const HTMLCollection* htmlCollection, Element* element) 192 template <> inline bool isMatchingElement(const HTMLCollection& htmlCollection, const Element& element)
193 { 193 {
194 CollectionType type = htmlCollection->type(); 194 CollectionType type = htmlCollection.type();
195 if (!element->isHTMLElement() && !(type == DocAll || type == NodeChildren || type == WindowNamedItems)) 195 if (!element.isHTMLElement() && !(type == DocAll || type == NodeChildren || type == WindowNamedItems))
196 return false; 196 return false;
197 197
198 switch (type) { 198 switch (type) {
199 case DocImages: 199 case DocImages:
200 return element->hasLocalName(imgTag); 200 return element.hasLocalName(imgTag);
201 case DocScripts: 201 case DocScripts:
202 return element->hasLocalName(scriptTag); 202 return element.hasLocalName(scriptTag);
203 case DocForms: 203 case DocForms:
204 return element->hasLocalName(formTag); 204 return element.hasLocalName(formTag);
205 case TableTBodies: 205 case TableTBodies:
206 return element->hasLocalName(tbodyTag); 206 return element.hasLocalName(tbodyTag);
207 case TRCells: 207 case TRCells:
208 return element->hasLocalName(tdTag) || element->hasLocalName(thTag); 208 return element.hasLocalName(tdTag) || element.hasLocalName(thTag);
209 case TSectionRows: 209 case TSectionRows:
210 return element->hasLocalName(trTag); 210 return element.hasLocalName(trTag);
211 case SelectOptions: 211 case SelectOptions:
212 return element->hasLocalName(optionTag); 212 return element.hasLocalName(optionTag);
213 case SelectedOptions: 213 case SelectedOptions:
214 return element->hasLocalName(optionTag) && toHTMLOptionElement(element)- >selected(); 214 return element.hasLocalName(optionTag) && toHTMLOptionElement(element).s elected();
215 case DataListOptions: 215 case DataListOptions:
216 if (element->hasLocalName(optionTag)) { 216 if (element.hasLocalName(optionTag)) {
217 HTMLOptionElement* option = toHTMLOptionElement(element); 217 const HTMLOptionElement& option = toHTMLOptionElement(element);
218 if (!option->isDisabledFormControl() && !option->value().isEmpty()) 218 if (!option.isDisabledFormControl() && !option.value().isEmpty())
219 return true; 219 return true;
220 } 220 }
221 return false; 221 return false;
222 case MapAreas: 222 case MapAreas:
223 return element->hasLocalName(areaTag); 223 return element.hasLocalName(areaTag);
224 case DocApplets: 224 case DocApplets:
225 return element->hasLocalName(appletTag) || (element->hasLocalName(object Tag) && toHTMLObjectElement(element)->containsJavaApplet()); 225 return element.hasLocalName(appletTag) || (element.hasLocalName(objectTa g) && toHTMLObjectElement(element).containsJavaApplet());
226 case DocEmbeds: 226 case DocEmbeds:
227 return element->hasLocalName(embedTag); 227 return element.hasLocalName(embedTag);
228 case DocLinks: 228 case DocLinks:
229 return (element->hasLocalName(aTag) || element->hasLocalName(areaTag)) & & element->fastHasAttribute(hrefAttr); 229 return (element.hasLocalName(aTag) || element.hasLocalName(areaTag)) && element.fastHasAttribute(hrefAttr);
230 case DocAnchors: 230 case DocAnchors:
231 return element->hasLocalName(aTag) && element->fastHasAttribute(nameAttr ); 231 return element.hasLocalName(aTag) && element.fastHasAttribute(nameAttr);
232 case DocAll: 232 case DocAll:
233 case NodeChildren: 233 case NodeChildren:
234 return true; 234 return true;
235 case FormControls: 235 case FormControls:
236 case DocumentNamedItems: 236 case DocumentNamedItems:
237 case TableRows: 237 case TableRows:
238 case WindowNamedItems: 238 case WindowNamedItems:
239 case ChildNodeListType: 239 case ChildNodeListType:
240 case ClassNodeListType: 240 case ClassNodeListType:
241 case NameNodeListType: 241 case NameNodeListType:
242 case TagNodeListType: 242 case TagNodeListType:
243 case HTMLTagNodeListType: 243 case HTMLTagNodeListType:
244 case RadioNodeListType: 244 case RadioNodeListType:
245 case RadioImgNodeListType: 245 case RadioImgNodeListType:
246 case LabelsNodeListType: 246 case LabelsNodeListType:
247 ASSERT_NOT_REACHED(); 247 ASSERT_NOT_REACHED();
248 } 248 }
249 return false; 249 return false;
250 } 250 }
251 251
252 template <> inline bool isMatchingElement(const LiveNodeList* nodeList, Element* element) 252 template <> inline bool isMatchingElement(const LiveNodeList& nodeList, const El ement& element)
253 { 253 {
254 return nodeList->nodeMatches(element); 254 return nodeList.nodeMatches(element);
255 } 255 }
256 256
257 template <> inline bool isMatchingElement(const HTMLTagNodeList* nodeList, Eleme nt* element) 257 template <> inline bool isMatchingElement(const HTMLTagNodeList& nodeList, const Element& element)
258 { 258 {
259 return nodeList->nodeMatchesInlined(element); 259 return nodeList.nodeMatchesInlined(element);
260 } 260 }
261 261
262 template <> inline bool isMatchingElement(const ClassNodeList* nodeList, Element * element) 262 template <> inline bool isMatchingElement(const ClassNodeList& nodeList, const E lement& element)
263 { 263 {
264 return nodeList->nodeMatchesInlined(element); 264 return nodeList.nodeMatchesInlined(element);
265 } 265 }
266 266
267 static Node* previousNode(Node& base, Node& previous, bool onlyIncludeDirectChil dren) 267 static Node* previousNode(const Node& base, const Node& previous, bool onlyInclu deDirectChildren)
268 { 268 {
269 return onlyIncludeDirectChildren ? previous.previousSibling() : NodeTraversa l::previous(previous, &base); 269 return onlyIncludeDirectChildren ? previous.previousSibling() : NodeTraversa l::previous(previous, &base);
270 } 270 }
271 271
272 static inline Node* lastDescendent(Node& node) 272 static inline Node* lastDescendant(const Node& node)
273 { 273 {
274 Node* descendent = node.lastChild(); 274 Node* descendant = node.lastChild();
275 for (Node* current = descendent; current; current = current->lastChild()) 275 for (Node* current = descendant; current; current = current->lastChild())
276 descendent = current; 276 descendant = current;
277 return descendent; 277 return descendant;
278 } 278 }
279 279
280 static Node* lastNode(Node& rootNode, bool onlyIncludeDirectChildren) 280 static Node* lastNode(const Node& rootNode, bool onlyIncludeDirectChildren)
281 { 281 {
282 return onlyIncludeDirectChildren ? rootNode.lastChild() : lastDescendent(roo tNode); 282 return onlyIncludeDirectChildren ? rootNode.lastChild() : lastDescendant(roo tNode);
283 } 283 }
284 284
285 ALWAYS_INLINE Node* LiveNodeListBase::iterateForPreviousNode(Node* current) cons t 285 ALWAYS_INLINE Node* LiveNodeListBase::iterateForPreviousNode(Node* current) cons t
286 { 286 {
287 bool onlyIncludeDirectChildren = shouldOnlyIncludeDirectChildren(); 287 bool onlyIncludeDirectChildren = shouldOnlyIncludeDirectChildren();
288 CollectionType collectionType = type(); 288 CollectionType collectionType = type();
289 Node& rootNode = this->rootNode(); 289 Node& rootNode = this->rootNode();
290 for (; current; current = previousNode(rootNode, *current, onlyIncludeDirect Children)) { 290 for (; current; current = previousNode(rootNode, *current, onlyIncludeDirect Children)) {
291 if (isLiveNodeListType(collectionType)) { 291 if (isLiveNodeListType(collectionType)) {
292 if (current->isElementNode() && isMatchingElement(static_cast<const LiveNodeList*>(this), toElement(current))) 292 if (current->isElementNode() && isMatchingElement(static_cast<const LiveNodeList&>(*this), toElement(*current)))
293 return toElement(current); 293 return toElement(current);
294 } else { 294 } else {
295 if (current->isElementNode() && isMatchingElement(static_cast<const HTMLCollection*>(this), toElement(current))) 295 if (current->isElementNode() && isMatchingElement(static_cast<const HTMLCollection&>(*this), toElement(*current)))
296 return toElement(current); 296 return toElement(current);
297 } 297 }
298 } 298 }
299 return 0; 299 return 0;
300 } 300 }
301 301
302 ALWAYS_INLINE Node* LiveNodeListBase::itemBefore(Node* previous) const 302 ALWAYS_INLINE Node* LiveNodeListBase::itemBefore(const Node* previous) const
303 { 303 {
304 Node* current; 304 Node* current;
305 if (LIKELY(!!previous)) // Without this LIKELY, length() and item() can be 1 0% slower. 305 if (LIKELY(!!previous)) // Without this LIKELY, length() and item() can be 1 0% slower.
306 current = previousNode(rootNode(), *previous, shouldOnlyIncludeDirectChi ldren()); 306 current = previousNode(rootNode(), *previous, shouldOnlyIncludeDirectChi ldren());
307 else 307 else
308 current = lastNode(rootNode(), shouldOnlyIncludeDirectChildren()); 308 current = lastNode(rootNode(), shouldOnlyIncludeDirectChildren());
309 309
310 if (type() == ChildNodeListType) 310 if (type() == ChildNodeListType)
311 return current; 311 return current;
312 return iterateForPreviousNode(current); 312 return iterateForPreviousNode(current);
313 } 313 }
314 314
315 template <class NodeListType> 315 template <class NodeListType>
316 inline Element* firstMatchingElement(const NodeListType* nodeList, ContainerNode & root) 316 inline Element* firstMatchingElement(const NodeListType& nodeList, const Contain erNode& root)
317 { 317 {
318 Element* element = ElementTraversal::firstWithin(root); 318 Element* element = ElementTraversal::firstWithin(root);
319 while (element && !isMatchingElement(nodeList, element)) 319 while (element && !isMatchingElement(nodeList, *element))
320 element = ElementTraversal::next(*element, &root); 320 element = ElementTraversal::next(*element, &root);
321 return element; 321 return element;
322 } 322 }
323 323
324 template <class NodeListType> 324 template <class NodeListType>
325 inline Element* nextMatchingElement(const NodeListType* nodeList, Element& curre nt, ContainerNode* root) 325 inline Element* nextMatchingElement(const NodeListType& nodeList, Element& curre nt, const ContainerNode& root)
326 { 326 {
327 Element* next = &current; 327 Element* next = &current;
328 do { 328 do {
329 next = ElementTraversal::next(*next, root); 329 next = ElementTraversal::next(*next, &root);
330 } while (next && !isMatchingElement(nodeList, next)); 330 } while (next && !isMatchingElement(nodeList, *next));
331 return next; 331 return next;
332 } 332 }
333 333
334 template <class NodeListType> 334 template <class NodeListType>
335 inline Element* traverseMatchingElementsForwardToOffset(const NodeListType* node List, unsigned offset, Element& currentElement, unsigned& currentOffset, Contain erNode* root) 335 inline Element* traverseMatchingElementsForwardToOffset(const NodeListType& node List, unsigned offset, Element& currentElement, unsigned& currentOffset, const C ontainerNode& root)
336 { 336 {
337 ASSERT(currentOffset < offset); 337 ASSERT(currentOffset < offset);
338 Element* next = &currentElement; 338 Element* next = &currentElement;
339 while ((next = nextMatchingElement(nodeList, *next, root))) { 339 while ((next = nextMatchingElement(nodeList, *next, root))) {
340 if (++currentOffset == offset) 340 if (++currentOffset == offset)
341 return next; 341 return next;
342 } 342 }
343 return 0; 343 return 0;
344 } 344 }
345 345
346 static inline Node* traverseSiblingsForwardToOffset(unsigned offset, Node& curre ntNode, unsigned& currentOffset) 346 static inline Node* traverseSiblingsForwardToOffset(unsigned offset, Node& curre ntNode, unsigned& currentOffset)
347 { 347 {
348 ASSERT(currentOffset < offset); 348 ASSERT(currentOffset < offset);
349 Node* next = &currentNode; 349 Node* next = &currentNode;
350 while ((next = next->nextSibling())) { 350 while ((next = next->nextSibling())) {
351 if (++currentOffset == offset) 351 if (++currentOffset == offset)
352 return next; 352 return next;
353 } 353 }
354 return 0; 354 return 0;
355 } 355 }
356 356
357 // FIXME: This should be in LiveNodeList.cpp but it needs to stay here until fir stMatchingElement() 357 // FIXME: This should be in LiveNodeList.cpp but it needs to stay here until fir stMatchingElement()
358 // and others are moved to a separate header. 358 // and others are moved to a separate header.
359 inline Node* LiveNodeList::traverseToFirstElement(ContainerNode& root) const 359 inline Node* LiveNodeList::traverseToFirstElement(const ContainerNode& root) con st
360 { 360 {
361 ASSERT(isLiveNodeListType(type())); 361 ASSERT(isLiveNodeListType(type()));
362 switch (type()) { 362 switch (type()) {
363 case ChildNodeListType: 363 case ChildNodeListType:
364 return root.firstChild(); 364 return root.firstChild();
365 case HTMLTagNodeListType: 365 case HTMLTagNodeListType:
366 return firstMatchingElement(static_cast<const HTMLTagNodeList*>(this), r oot); 366 return firstMatchingElement(static_cast<const HTMLTagNodeList&>(*this), root);
367 case ClassNodeListType: 367 case ClassNodeListType:
368 return firstMatchingElement(static_cast<const ClassNodeList*>(this), roo t); 368 return firstMatchingElement(static_cast<const ClassNodeList&>(*this), ro ot);
369 default: 369 default:
370 return firstMatchingElement(static_cast<const LiveNodeList*>(this), root ); 370 return firstMatchingElement(static_cast<const LiveNodeList&>(*this), roo t);
371 } 371 }
372 } 372 }
373 373
374 // FIXME: This should be in LiveNodeList.cpp but it needs to stay here until tra verseMatchingElementsForwardToOffset() 374 // FIXME: This should be in LiveNodeList.cpp but it needs to stay here until tra verseMatchingElementsForwardToOffset()
375 // and others are moved to a separate header. 375 // and others are moved to a separate header.
376 inline Node* LiveNodeList::traverseForwardToOffset(unsigned offset, Node& curren tNode, unsigned& currentOffset, ContainerNode* root) const 376 inline Node* LiveNodeList::traverseForwardToOffset(unsigned offset, Node& curren tNode, unsigned& currentOffset, const ContainerNode& root) const
377 { 377 {
378 switch (type()) { 378 switch (type()) {
379 case ChildNodeListType: 379 case ChildNodeListType:
380 return traverseSiblingsForwardToOffset(offset, currentNode, currentOffse t); 380 return traverseSiblingsForwardToOffset(offset, currentNode, currentOffse t);
381 case HTMLTagNodeListType: 381 case HTMLTagNodeListType:
382 return traverseMatchingElementsForwardToOffset(static_cast<const HTMLTag NodeList*>(this), offset, toElement(currentNode), currentOffset, root); 382 return traverseMatchingElementsForwardToOffset(static_cast<const HTMLTag NodeList&>(*this), offset, toElement(currentNode), currentOffset, root);
383 case ClassNodeListType: 383 case ClassNodeListType:
384 return traverseMatchingElementsForwardToOffset(static_cast<const ClassNo deList*>(this), offset, toElement(currentNode), currentOffset, root); 384 return traverseMatchingElementsForwardToOffset(static_cast<const ClassNo deList&>(*this), offset, toElement(currentNode), currentOffset, root);
385 default: 385 default:
386 return traverseMatchingElementsForwardToOffset(this, offset, toElement(c urrentNode), currentOffset, root); 386 return traverseMatchingElementsForwardToOffset(*this, offset, toElement( currentNode), currentOffset, root);
387 } 387 }
388 } 388 }
389 389
390 bool ALWAYS_INLINE LiveNodeListBase::isLastItemCloserThanLastOrCachedItem(unsign ed offset) const 390 bool ALWAYS_INLINE LiveNodeListBase::isLastItemCloserThanLastOrCachedItem(unsign ed offset) const
391 { 391 {
392 ASSERT(isLengthCacheValid()); 392 ASSERT(isLengthCacheValid());
393 unsigned distanceFromLastItem = cachedLength() - offset; 393 unsigned distanceFromLastItem = cachedLength() - offset;
394 if (!cachedItem()) 394 if (!cachedItem())
395 return distanceFromLastItem < offset; 395 return distanceFromLastItem < offset;
396 396
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 setLengthCache(0); 448 setLengthCache(0);
449 return 0; 449 return 0;
450 } 450 }
451 setItemCache(firstItem, 0); 451 setItemCache(firstItem, 0);
452 ASSERT(!cachedItemOffset()); 452 ASSERT(!cachedItemOffset());
453 } 453 }
454 454
455 if (cachedItemOffset() == offset) 455 if (cachedItemOffset() == offset)
456 return cachedItem(); 456 return cachedItem();
457 457
458 return itemBeforeOrAfterCachedItem(offset, root); 458 return itemBeforeOrAfterCachedItem(offset, *root);
459 } 459 }
460 460
461 inline Node* LiveNodeListBase::itemBeforeOrAfterCachedItem(unsigned offset, Cont ainerNode* root) const 461 inline Node* LiveNodeListBase::itemBeforeOrAfterCachedItem(unsigned offset, cons t ContainerNode& root) const
462 { 462 {
463 unsigned currentOffset = cachedItemOffset(); 463 unsigned currentOffset = cachedItemOffset();
464 Node* currentItem = cachedItem(); 464 Node* currentItem = cachedItem();
465 ASSERT(currentItem); 465 ASSERT(currentItem);
466 ASSERT(currentOffset != offset); 466 ASSERT(currentOffset != offset);
467 467
468 if (offset < cachedItemOffset()) { 468 if (offset < cachedItemOffset()) {
469 ASSERT(!overridesItemAfter()); 469 ASSERT(!overridesItemAfter());
470 while ((currentItem = itemBefore(currentItem))) { 470 while ((currentItem = itemBefore(currentItem))) {
471 ASSERT(currentOffset); 471 ASSERT(currentOffset);
(...skipping 20 matching lines...) Expand all
492 setItemCache(currentItem, currentOffset); 492 setItemCache(currentItem, currentOffset);
493 return currentItem; 493 return currentItem;
494 } 494 }
495 495
496 Element* HTMLCollection::virtualItemAfter(Element*) const 496 Element* HTMLCollection::virtualItemAfter(Element*) const
497 { 497 {
498 ASSERT_NOT_REACHED(); 498 ASSERT_NOT_REACHED();
499 return 0; 499 return 0;
500 } 500 }
501 501
502 static inline bool nameShouldBeVisibleInDocumentAll(HTMLElement* element) 502 static inline bool nameShouldBeVisibleInDocumentAll(const HTMLElement& element)
503 { 503 {
504 // The document.all collection returns only certain types of elements by nam e, 504 // The document.all collection returns only certain types of elements by nam e,
505 // although it returns any type of element by id. 505 // although it returns any type of element by id.
506 return element->hasLocalName(appletTag) 506 return element.hasLocalName(appletTag)
507 || element->hasLocalName(embedTag) 507 || element.hasLocalName(embedTag)
508 || element->hasLocalName(formTag) 508 || element.hasLocalName(formTag)
509 || element->hasLocalName(imgTag) 509 || element.hasLocalName(imgTag)
510 || element->hasLocalName(inputTag) 510 || element.hasLocalName(inputTag)
511 || element->hasLocalName(objectTag) 511 || element.hasLocalName(objectTag)
512 || element->hasLocalName(selectTag); 512 || element.hasLocalName(selectTag);
513 } 513 }
514 514
515 bool HTMLCollection::checkForNameMatch(Element* element, bool checkName, const A tomicString& name) const 515 bool HTMLCollection::checkForNameMatch(const Element& element, bool checkName, c onst AtomicString& name) const
516 { 516 {
517 if (!element->isHTMLElement()) 517 if (!element.isHTMLElement())
518 return false; 518 return false;
519 519
520 HTMLElement* e = toHTMLElement(element); 520 const HTMLElement& e = toHTMLElement(element);
521 if (!checkName) 521 if (!checkName)
522 return e->getIdAttribute() == name; 522 return e.getIdAttribute() == name;
523 523
524 if (type() == DocAll && !nameShouldBeVisibleInDocumentAll(e)) 524 if (type() == DocAll && !nameShouldBeVisibleInDocumentAll(e))
525 return false; 525 return false;
526 526
527 return e->getNameAttribute() == name && e->getIdAttribute() != name; 527 return e.getNameAttribute() == name && e.getIdAttribute() != name;
528 } 528 }
529 529
530 inline Element* firstMatchingChildElement(const HTMLCollection* nodeList, Contai nerNode& root) 530 inline Element* firstMatchingChildElement(const HTMLCollection& nodeList, const ContainerNode& root)
531 { 531 {
532 Element* element = ElementTraversal::firstWithin(root); 532 Element* element = ElementTraversal::firstWithin(root);
533 while (element && !isMatchingElement(nodeList, element)) 533 while (element && !isMatchingElement(nodeList, *element))
534 element = ElementTraversal::nextSkippingChildren(*element, &root); 534 element = ElementTraversal::nextSkippingChildren(*element, &root);
535 return element; 535 return element;
536 } 536 }
537 537
538 inline Element* nextMatchingChildElement(const HTMLCollection* nodeList, Element & current, ContainerNode* root) 538 inline Element* nextMatchingChildElement(const HTMLCollection& nodeList, Element & current, const ContainerNode& root)
539 { 539 {
540 Element* next = &current; 540 Element* next = &current;
541 do { 541 do {
542 next = ElementTraversal::nextSkippingChildren(*next, root); 542 next = ElementTraversal::nextSkippingChildren(*next, &root);
543 } while (next && !isMatchingElement(nodeList, next)); 543 } while (next && !isMatchingElement(nodeList, *next));
544 return next; 544 return next;
545 } 545 }
546 546
547 inline Element* HTMLCollection::traverseToFirstElement(ContainerNode& root) cons t 547 inline Element* HTMLCollection::traverseToFirstElement(const ContainerNode& root ) const
548 { 548 {
549 if (overridesItemAfter()) 549 if (overridesItemAfter())
550 return virtualItemAfter(0); 550 return virtualItemAfter(0);
551 if (shouldOnlyIncludeDirectChildren()) 551 if (shouldOnlyIncludeDirectChildren())
552 return firstMatchingChildElement(static_cast<const HTMLCollection*>(this ), root); 552 return firstMatchingChildElement(*this, root);
553 return firstMatchingElement(static_cast<const HTMLCollection*>(this), root); 553 return firstMatchingElement(*this, root);
554 } 554 }
555 555
556 inline Element* HTMLCollection::traverseNextElement(Element& previous, Container Node* root) const 556 inline Element* HTMLCollection::traverseNextElement(Element& previous, const Con tainerNode& root) const
557 { 557 {
558 if (overridesItemAfter()) 558 if (overridesItemAfter())
559 return virtualItemAfter(&previous); 559 return virtualItemAfter(&previous);
560 if (shouldOnlyIncludeDirectChildren()) 560 if (shouldOnlyIncludeDirectChildren())
561 return nextMatchingChildElement(this, previous, root); 561 return nextMatchingChildElement(*this, previous, root);
562 return nextMatchingElement(this, previous, root); 562 return nextMatchingElement(*this, previous, root);
563 } 563 }
564 564
565 inline Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element & currentElement, unsigned& currentOffset, ContainerNode* root) const 565 inline Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element & currentElement, unsigned& currentOffset, const ContainerNode& root) const
566 { 566 {
567 ASSERT(currentOffset < offset); 567 ASSERT(currentOffset < offset);
568 if (overridesItemAfter()) { 568 if (overridesItemAfter()) {
569 Element* next = &currentElement; 569 Element* next = &currentElement;
570 while ((next = virtualItemAfter(next))) { 570 while ((next = virtualItemAfter(next))) {
571 if (++currentOffset == offset) 571 if (++currentOffset == offset)
572 return next; 572 return next;
573 } 573 }
574 return 0; 574 return 0;
575 } 575 }
576 if (shouldOnlyIncludeDirectChildren()) { 576 if (shouldOnlyIncludeDirectChildren()) {
577 Element* next = &currentElement; 577 Element* next = &currentElement;
578 while ((next = nextMatchingChildElement(this, *next, root))) { 578 while ((next = nextMatchingChildElement(*this, *next, root))) {
579 if (++currentOffset == offset) 579 if (++currentOffset == offset)
580 return next; 580 return next;
581 } 581 }
582 return 0; 582 return 0;
583 } 583 }
584 return traverseMatchingElementsForwardToOffset(this, offset, currentElement, currentOffset, root); 584 return traverseMatchingElementsForwardToOffset(*this, offset, currentElement , currentOffset, root);
585 } 585 }
586 586
587 Node* HTMLCollection::namedItem(const AtomicString& name) const 587 Node* HTMLCollection::namedItem(const AtomicString& name) const
588 { 588 {
589 // 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
590 // This method first searches for an object with a matching id 590 // This method first searches for an object with a matching id
591 // 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
592 // object with a matching name attribute, but only on those elements 592 // object with a matching name attribute, but only on those elements
593 // that are allowed a name attribute. 593 // that are allowed a name attribute.
594 594
595 ContainerNode* root = rootContainerNode(); 595 ContainerNode* root = rootContainerNode();
596 if (!root) 596 if (!root)
597 return 0; 597 return 0;
598 598
599 unsigned i = 0; 599 unsigned i = 0;
600 for (Element* element = traverseToFirstElement(*root); element; element = tr averseNextElement(*element, root)) { 600 for (Element* element = traverseToFirstElement(*root); element; element = tr averseNextElement(*element, *root)) {
601 if (checkForNameMatch(element, /* checkName */ false, name)) { 601 if (checkForNameMatch(*element, /* checkName */ false, name)) {
602 setItemCache(element, i); 602 setItemCache(element, i);
603 return element; 603 return element;
604 } 604 }
605 i++; 605 i++;
606 } 606 }
607 607
608 i = 0; 608 i = 0;
609 for (Element* element = traverseToFirstElement(*root); element; element = tr averseNextElement(*element, root)) { 609 for (Element* element = traverseToFirstElement(*root); element; element = tr averseNextElement(*element, *root)) {
610 if (checkForNameMatch(element, /* checkName */ true, name)) { 610 if (checkForNameMatch(*element, /* checkName */ true, name)) {
611 setItemCache(element, i); 611 setItemCache(element, i);
612 return element; 612 return element;
613 } 613 }
614 i++; 614 i++;
615 } 615 }
616 616
617 return 0; 617 return 0;
618 } 618 }
619 619
620 void HTMLCollection::updateNameCache() const 620 void HTMLCollection::updateNameCache() const
621 { 621 {
622 if (hasNameCache()) 622 if (hasNameCache())
623 return; 623 return;
624 624
625 ContainerNode* root = rootContainerNode(); 625 ContainerNode* root = rootContainerNode();
626 if (!root) 626 if (!root)
627 return; 627 return;
628 628
629 for (Element* element = traverseToFirstElement(*root); element; element = tr averseNextElement(*element, root)) { 629 for (Element* element = traverseToFirstElement(*root); element; element = tr averseNextElement(*element, *root)) {
630 const AtomicString& idAttrVal = element->getIdAttribute(); 630 const AtomicString& idAttrVal = element->getIdAttribute();
631 if (!idAttrVal.isEmpty()) 631 if (!idAttrVal.isEmpty())
632 appendIdCache(idAttrVal, element); 632 appendIdCache(idAttrVal, element);
633 if (!element->isHTMLElement()) 633 if (!element->isHTMLElement())
634 continue; 634 continue;
635 const AtomicString& nameAttrVal = element->getNameAttribute(); 635 const AtomicString& nameAttrVal = element->getNameAttribute();
636 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != Doc All || nameShouldBeVisibleInDocumentAll(toHTMLElement(element)))) 636 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != Doc All || nameShouldBeVisibleInDocumentAll(toHTMLElement(*element))))
637 appendNameCache(nameAttrVal, element); 637 appendNameCache(nameAttrVal, element);
638 } 638 }
639 639
640 setHasNameCache(); 640 setHasNameCache();
641 } 641 }
642 642
643 void HTMLCollection::namedItems(const AtomicString& name, Vector<RefPtr<Node> >& result) const 643 void HTMLCollection::namedItems(const AtomicString& name, Vector<RefPtr<Node> >& result) const
644 { 644 {
645 ASSERT(result.isEmpty()); 645 ASSERT(result.isEmpty());
646 if (name.isEmpty()) 646 if (name.isEmpty())
(...skipping 13 matching lines...) Expand all
660 660
661 void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element* element) 661 void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element* element)
662 { 662 {
663 OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->v alue; 663 OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->v alue;
664 if (!vector) 664 if (!vector)
665 vector = adoptPtr(new Vector<Element*>); 665 vector = adoptPtr(new Vector<Element*>);
666 vector->append(element); 666 vector->append(element);
667 } 667 }
668 668
669 } // namespace WebCore 669 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698