15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (C) 1999 Antti Koivisto (koivisto@kde.org) 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights reserved. 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful, 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details. 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB. If not, write to 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA. 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLCollection.h" 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "HTMLNames.h" 2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/ClassNodeList.h" 2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/NodeList.h" 2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/NodeRareData.h" 3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/NodeTraversal.h" 3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLElement.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLObjectElement.h" 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLOptionElement.h" 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace HTMLNames; 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool shouldOnlyIncludeDirectChildren(CollectionType type) 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (type) { 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocAll: 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocAnchors: 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocApplets: 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocEmbeds: 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocForms: 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocImages: 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocLinks: 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocScripts: 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocumentNamedItems: 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case MapAreas: 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TableRows: 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case SelectOptions: 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case SelectedOptions: 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DataListOptions: 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case WindowNamedItems: 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FormControls: 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case NodeChildren: 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TRCells: 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TSectionRows: 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TableTBodies: 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 64926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case ChildNodeListType: 65926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case ClassNodeListType: 66926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case NameNodeListType: 67926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case TagNodeListType: 68926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case HTMLTagNodeListType: 69926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case RadioNodeListType: 70926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case LabelsNodeListType: 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static NodeListRootType rootTypeFromCollectionType(CollectionType type) 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (type) { 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocImages: 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocApplets: 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocEmbeds: 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocForms: 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocLinks: 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocAnchors: 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocScripts: 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocAll: 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case WindowNamedItems: 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocumentNamedItems: 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FormControls: 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return NodeListIsRootedAtDocument; 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case NodeChildren: 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TableTBodies: 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TSectionRows: 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TableRows: 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TRCells: 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case SelectOptions: 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case SelectedOptions: 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DataListOptions: 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case MapAreas: 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return NodeListIsRootedAtNode; 102926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case ChildNodeListType: 103926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case ClassNodeListType: 104926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case NameNodeListType: 105926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case TagNodeListType: 106926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case HTMLTagNodeListType: 107926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case RadioNodeListType: 108926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case LabelsNodeListType: 109926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) break; 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return NodeListIsRootedAtNode; 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static NodeListInvalidationType invalidationTypeExcludingIdAndNameAttributes(CollectionType type) 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (type) { 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocImages: 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocEmbeds: 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocForms: 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocScripts: 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocAll: 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case NodeChildren: 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TableTBodies: 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TSectionRows: 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TableRows: 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TRCells: 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case SelectOptions: 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case MapAreas: 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return DoNotInvalidateOnAttributeChanges; 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocApplets: 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case SelectedOptions: 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DataListOptions: 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: We can do better some day. 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return InvalidateOnAnyAttrChange; 136926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case DocAnchors: 137926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return InvalidateOnNameAttrChange; 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocLinks: 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return InvalidateOnHRefAttrChange; 140926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case WindowNamedItems: 141926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return InvalidateOnIdNameAttrChange; 142926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case DocumentNamedItems: 143926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return InvalidateOnIdNameAttrChange; 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FormControls: 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return InvalidateForFormControls; 146926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case ChildNodeListType: 147926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case ClassNodeListType: 148926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case NameNodeListType: 149926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case TagNodeListType: 150926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case HTMLTagNodeListType: 151926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case RadioNodeListType: 152926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case LabelsNodeListType: 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return DoNotInvalidateOnAttributeChanges; 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)HTMLCollection::HTMLCollection(Node* ownerNode, CollectionType type, ItemAfterOverrideType itemAfterOverrideType) 160926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) : LiveNodeListBase(ownerNode, rootTypeFromCollectionType(type), invalidationTypeExcludingIdAndNameAttributes(type), 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) WebCore::shouldOnlyIncludeDirectChildren(type), type, itemAfterOverrideType) 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 16353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) ScriptWrappable::init(this); 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<HTMLCollection> HTMLCollection::create(Node* base, CollectionType type) 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return adoptRef(new HTMLCollection(base, type, DoesNotOverrideItemAfter)); 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)HTMLCollection::~HTMLCollection() 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 173926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // HTMLNameCollection removes cache by itself. 174926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (type() != WindowNamedItems && type() != DocumentNamedItems) 175926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ownerNode()->nodeLists()->removeCacheWithAtomicName(this, type()); 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 178926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)template <class NodeListType> 179926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)inline bool isMatchingElement(const NodeListType*, Element*); 180926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 181926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)template <> inline bool isMatchingElement(const HTMLCollection* htmlCollection, Element* element) 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 183926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) CollectionType type = htmlCollection->type(); 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!element->isHTMLElement() && !(type == DocAll || type == NodeChildren)) 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (type) { 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocImages: 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return element->hasLocalName(imgTag); 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocScripts: 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return element->hasLocalName(scriptTag); 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocForms: 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return element->hasLocalName(formTag); 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TableTBodies: 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return element->hasLocalName(tbodyTag); 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TRCells: 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return element->hasLocalName(tdTag) || element->hasLocalName(thTag); 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TSectionRows: 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return element->hasLocalName(trTag); 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case SelectOptions: 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return element->hasLocalName(optionTag); 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case SelectedOptions: 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return element->hasLocalName(optionTag) && toHTMLOptionElement(element)->selected(); 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DataListOptions: 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (element->hasLocalName(optionTag)) { 206591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch HTMLOptionElement* option = toHTMLOptionElement(element); 20753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (!option->isDisabledFormControl() && !option->value().isEmpty()) 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case MapAreas: 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return element->hasLocalName(areaTag); 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocApplets: 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return element->hasLocalName(appletTag) || (element->hasLocalName(objectTag) && static_cast<HTMLObjectElement*>(element)->containsJavaApplet()); 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocEmbeds: 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return element->hasLocalName(embedTag); 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocLinks: 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return (element->hasLocalName(aTag) || element->hasLocalName(areaTag)) && element->fastHasAttribute(hrefAttr); 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocAnchors: 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return element->hasLocalName(aTag) && element->fastHasAttribute(nameAttr); 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DocAll: 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case NodeChildren: 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 224f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) case FormControls: 225df95704c49daea886ddad70775bda23618d6274dBen Murdoch case DocumentNamedItems: 226f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) case TableRows: 227df95704c49daea886ddad70775bda23618d6274dBen Murdoch case WindowNamedItems: 228926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case ChildNodeListType: 229926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case ClassNodeListType: 230926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case NameNodeListType: 231926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case TagNodeListType: 232926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case HTMLTagNodeListType: 233926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case RadioNodeListType: 234926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case LabelsNodeListType: 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 240926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)template <> inline bool isMatchingElement(const LiveNodeList* nodeList, Element* element) 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 242926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return nodeList->nodeMatches(element); 243926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 244926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 245926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)template <> inline bool isMatchingElement(const HTMLTagNodeList* nodeList, Element* element) 246926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 247926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return nodeList->nodeMatchesInlined(element); 248926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 249926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 250926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)template <> inline bool isMatchingElement(const ClassNodeList* nodeList, Element* element) 251926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 252926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return nodeList->nodeMatchesInlined(element); 253926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 254926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 255926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static Node* previousNode(Node* base, Node* previous, bool onlyIncludeDirectChildren) 256926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 257926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return onlyIncludeDirectChildren ? previous->previousSibling() : NodeTraversal::previous(previous, base); 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline Node* lastDescendent(Node* node) 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) node = node->lastChild(); 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (Node* current = node; current; current = current->lastChild()) 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) node = current; 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return node; 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 268926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static Node* lastNode(Node* rootNode, bool onlyIncludeDirectChildren) 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 270926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return onlyIncludeDirectChildren ? rootNode->lastChild() : lastDescendent(rootNode); 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 273926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)ALWAYS_INLINE Node* LiveNodeListBase::iterateForPreviousNode(Node* current) const 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool onlyIncludeDirectChildren = shouldOnlyIncludeDirectChildren(); 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CollectionType collectionType = type(); 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Node* rootNode = this->rootNode(); 278926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (; current; current = previousNode(rootNode, current, onlyIncludeDirectChildren)) { 279926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (isNodeList(collectionType)) { 280926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (current->isElementNode() && isMatchingElement(static_cast<const LiveNodeList*>(this), toElement(current))) 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return toElement(current); 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 283926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (current->isElementNode() && isMatchingElement(static_cast<const HTMLCollection*>(this), toElement(current))) 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return toElement(current); 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 290926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)ALWAYS_INLINE Node* LiveNodeListBase::itemBefore(Node* previous) const 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Node* current; 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (LIKELY(!!previous)) // Without this LIKELY, length() and item() can be 10% slower. 294926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) current = previousNode(rootNode(), previous, shouldOnlyIncludeDirectChildren()); 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 296926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) current = lastNode(rootNode(), shouldOnlyIncludeDirectChildren()); 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 298926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (type() == ChildNodeListType) 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return current; 300926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return iterateForPreviousNode(current); 301926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 303926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)template <class NodeListType> 304926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)inline Element* firstMatchingElement(const NodeListType* nodeList, ContainerNode* root) 305926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 306926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) Element* element = ElementTraversal::firstWithin(root); 307926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) while (element && !isMatchingElement(nodeList, element)) 308926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) element = ElementTraversal::next(element, root); 309926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return element; 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 312926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)template <class NodeListType> 313926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)inline Element* nextMatchingElement(const NodeListType* nodeList, Element* current, ContainerNode* root) 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 315926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) do { 316926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) current = ElementTraversal::next(current, root); 317926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } while (current && !isMatchingElement(nodeList, current)); 318926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return current; 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 321926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)template <class NodeListType> 322926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)inline Element* traverseMatchingElementsForwardToOffset(const NodeListType* nodeList, unsigned offset, Element* currentElement, unsigned& currentOffset, ContainerNode* root) 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 324926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(currentOffset < offset); 325926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) while ((currentElement = nextMatchingElement(nodeList, currentElement, root))) { 326926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (++currentOffset == offset) 327926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return currentElement; 328926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 329926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return 0; 330926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 331926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 332926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// FIXME: This should be in ChildNodeList 333926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)inline Node* LiveNodeListBase::traverseChildNodeListForwardToOffset(unsigned offset, Node* currentNode, unsigned& currentOffset) const 334926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 335926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(type() == ChildNodeListType); 336926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(currentOffset < offset); 337926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) while ((currentNode = currentNode->nextSibling())) { 338926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (++currentOffset == offset) 339926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return currentNode; 340926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 341926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return 0; 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 344926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// FIXME: This should be in LiveNodeList 345926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)inline Element* LiveNodeListBase::traverseLiveNodeListFirstElement(ContainerNode* root) const 346926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 347926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(isNodeList(type())); 348926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(type() != ChildNodeListType); 349926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (type() == HTMLTagNodeListType) 350926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return firstMatchingElement(static_cast<const HTMLTagNodeList*>(this), root); 351926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (type() == ClassNodeListType) 352926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return firstMatchingElement(static_cast<const ClassNodeList*>(this), root); 353926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return firstMatchingElement(static_cast<const LiveNodeList*>(this), root); 354926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 355926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 356926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// FIXME: This should be in LiveNodeList 357926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)inline Element* LiveNodeListBase::traverseLiveNodeListForwardToOffset(unsigned offset, Element* currentElement, unsigned& currentOffset, ContainerNode* root) const 358926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 359926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(isNodeList(type())); 360926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(type() != ChildNodeListType); 361926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (type() == HTMLTagNodeListType) 362926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return traverseMatchingElementsForwardToOffset(static_cast<const HTMLTagNodeList*>(this), offset, currentElement, currentOffset, root); 363926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (type() == ClassNodeListType) 364926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return traverseMatchingElementsForwardToOffset(static_cast<const ClassNodeList*>(this), offset, currentElement, currentOffset, root); 365926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return traverseMatchingElementsForwardToOffset(static_cast<const LiveNodeList*>(this), offset, currentElement, currentOffset, root); 366926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 367926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 368926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool ALWAYS_INLINE LiveNodeListBase::isLastItemCloserThanLastOrCachedItem(unsigned offset) const 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isLengthCacheValid()); 3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned distanceFromLastItem = cachedLength() - offset; 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isItemCacheValid()) 3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return distanceFromLastItem < offset; 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return cachedItemOffset() < offset && distanceFromLastItem < offset - cachedItemOffset(); 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 37702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 378926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool ALWAYS_INLINE LiveNodeListBase::isFirstItemCloserThanCachedItem(unsigned offset) const 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isItemCacheValid()); 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cachedItemOffset() < offset) 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned distanceFromCachedItem = cachedItemOffset() - offset; 3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return offset < distanceFromCachedItem; 3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 388926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)ALWAYS_INLINE void LiveNodeListBase::setItemCache(Node* item, unsigned offset, unsigned elementsArrayOffset) const 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setItemCache(item, offset); 3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (overridesItemAfter()) { 392926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT_WITH_SECURITY_IMPLICATION(item->isElementNode()); 393926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) static_cast<const HTMLCollection*>(this)->m_cachedElementsArrayOffset = elementsArrayOffset; 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!elementsArrayOffset); 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 398926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)unsigned LiveNodeListBase::length() const 3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isLengthCacheValid()) 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return cachedLength(); 4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 403926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) item(UINT_MAX); 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isLengthCacheValid()); 40502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return cachedLength(); 4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 409926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// FIXME: It is silly that these functions are in HTMLCollection.cpp. 410926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)Node* LiveNodeListBase::item(unsigned offset) const 4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isItemCacheValid() && cachedItemOffset() == offset) 4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return cachedItem(); 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isLengthCacheValid() && cachedLength() <= offset) 4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 418926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ContainerNode* root = rootContainerNode(); 419926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!root) { 420926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // FIMXE: In someTextNode.childNodes case the root is Text. We shouldn't even make a LiveNodeList for that. 421926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) setLengthCache(0); 422926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return 0; 423926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 424926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isLengthCacheValid() && !overridesItemAfter() && isLastItemCloserThanLastOrCachedItem(offset)) { 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Node* lastItem = itemBefore(0); 4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(lastItem); 4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setItemCache(lastItem, cachedLength() - 1, 0); 4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (!isItemCacheValid() || isFirstItemCloserThanCachedItem(offset) || (overridesItemAfter() && offset < cachedItemOffset())) { 4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned offsetInArray = 0; 431926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) Node* firstItem; 432926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (type() == ChildNodeListType) 433926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) firstItem = root->firstChild(); 434926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) else if (isNodeList(type())) 435926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) firstItem = traverseLiveNodeListFirstElement(root); 436926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) else 437926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) firstItem = static_cast<const HTMLCollection*>(this)->traverseFirstElement(offsetInArray, root); 438926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!firstItem) { 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setLengthCache(0); 4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setItemCache(firstItem, 0, offsetInArray); 4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!cachedItemOffset()); 4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cachedItemOffset() == offset) 4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return cachedItem(); 4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 450926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return itemBeforeOrAfterCachedItem(offset, root); 4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 453926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)inline Node* LiveNodeListBase::itemBeforeOrAfterCachedItem(unsigned offset, ContainerNode* root) const 4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned currentOffset = cachedItemOffset(); 4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Node* currentItem = cachedItem(); 457926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(currentItem); 4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(currentOffset != offset); 4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (offset < cachedItemOffset()) { 4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!overridesItemAfter()); 4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while ((currentItem = itemBefore(currentItem))) { 4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(currentOffset); 4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currentOffset--; 4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (currentOffset == offset) { 4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setItemCache(currentItem, currentOffset, 0); 4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return currentItem; 4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 474926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) unsigned offsetInArray = 0; 475926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (type() == ChildNodeListType) 476926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) currentItem = traverseChildNodeListForwardToOffset(offset, currentItem, currentOffset); 477926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) else if (isNodeList(type())) 478926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) currentItem = traverseLiveNodeListForwardToOffset(offset, toElement(currentItem), currentOffset, root); 479926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) else 480926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) currentItem = static_cast<const HTMLCollection*>(this)->traverseForwardToOffset(offset, toElement(currentItem), currentOffset, offsetInArray, root); 4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 482926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!currentItem) { 483926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Did not find the item. On plus side, we now know the length. 484926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) setLengthCache(currentOffset + 1); 485926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return 0; 486926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 487926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) setItemCache(currentItem, currentOffset, offsetInArray); 488926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return currentItem; 4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Element* HTMLCollection::virtualItemAfter(unsigned&, Element*) const 4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline bool nameShouldBeVisibleInDocumentAll(HTMLElement* element) 4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The document.all collection returns only certain types of elements by name, 5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // although it returns any type of element by id. 5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return element->hasLocalName(appletTag) 5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || element->hasLocalName(embedTag) 5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || element->hasLocalName(formTag) 5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || element->hasLocalName(imgTag) 5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || element->hasLocalName(inputTag) 5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || element->hasLocalName(objectTag) 5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || element->hasLocalName(selectTag); 5085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 510df95704c49daea886ddad70775bda23618d6274dBen Murdochbool HTMLCollection::checkForNameMatch(Element* element, bool checkName, const AtomicString& name) const 511df95704c49daea886ddad70775bda23618d6274dBen Murdoch{ 512df95704c49daea886ddad70775bda23618d6274dBen Murdoch if (!element->isHTMLElement()) 513df95704c49daea886ddad70775bda23618d6274dBen Murdoch return false; 514df95704c49daea886ddad70775bda23618d6274dBen Murdoch 515df95704c49daea886ddad70775bda23618d6274dBen Murdoch HTMLElement* e = toHTMLElement(element); 516df95704c49daea886ddad70775bda23618d6274dBen Murdoch if (!checkName) 517df95704c49daea886ddad70775bda23618d6274dBen Murdoch return e->getIdAttribute() == name; 518df95704c49daea886ddad70775bda23618d6274dBen Murdoch 519df95704c49daea886ddad70775bda23618d6274dBen Murdoch if (type() == DocAll && !nameShouldBeVisibleInDocumentAll(e)) 520df95704c49daea886ddad70775bda23618d6274dBen Murdoch return false; 521df95704c49daea886ddad70775bda23618d6274dBen Murdoch 522df95704c49daea886ddad70775bda23618d6274dBen Murdoch return e->getNameAttribute() == name && e->getIdAttribute() != name; 523df95704c49daea886ddad70775bda23618d6274dBen Murdoch} 524df95704c49daea886ddad70775bda23618d6274dBen Murdoch 525926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)inline Element* firstMatchingChildElement(const HTMLCollection* nodeList, ContainerNode* root) 526926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 527926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) Element* element = ElementTraversal::firstWithin(root); 528926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) while (element && !isMatchingElement(nodeList, element)) 529926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) element = ElementTraversal::nextSkippingChildren(element, root); 530926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return element; 531926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 532926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 533926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)inline Element* nextMatchingChildElement(const HTMLCollection* nodeList, Element* current, ContainerNode* root) 534926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 535926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) do { 536926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) current = ElementTraversal::nextSkippingChildren(current, root); 537926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } while (current && !isMatchingElement(nodeList, current)); 538926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return current; 539926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 540926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 541926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)inline Element* HTMLCollection::traverseFirstElement(unsigned& offsetInArray, ContainerNode* root) const 542926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 543926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (overridesItemAfter()) 544926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return virtualItemAfter(offsetInArray, 0); 545926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(!offsetInArray); 546926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (shouldOnlyIncludeDirectChildren()) 547926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return firstMatchingChildElement(static_cast<const HTMLCollection*>(this), root); 548926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return firstMatchingElement(static_cast<const HTMLCollection*>(this), root); 549926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 550926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 551926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)inline Element* HTMLCollection::traverseNextElement(unsigned& offsetInArray, Element* previous, ContainerNode* root) const 552926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 553926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (overridesItemAfter()) 554926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return virtualItemAfter(offsetInArray, previous); 555926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(!offsetInArray); 556926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (shouldOnlyIncludeDirectChildren()) 557926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return nextMatchingChildElement(this, previous, root); 558926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return nextMatchingElement(this, previous, root); 559926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 560926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 561926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)inline Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element* currentElement, unsigned& currentOffset, unsigned& offsetInArray, ContainerNode* root) const 562926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 563926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(currentOffset < offset); 564926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (overridesItemAfter()) { 565926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) offsetInArray = m_cachedElementsArrayOffset; 566926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) while ((currentElement = virtualItemAfter(offsetInArray, currentElement))) { 567926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (++currentOffset == offset) 568926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return currentElement; 569926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 570926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return 0; 571926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 572926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (shouldOnlyIncludeDirectChildren()) { 573926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) while ((currentElement = nextMatchingChildElement(this, currentElement, root))) { 574926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (++currentOffset == offset) 575926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return currentElement; 576926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 577926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return 0; 578926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 579926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return traverseMatchingElementsForwardToOffset(this, offset, currentElement, currentOffset, root); 580926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 581926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node* HTMLCollection::namedItem(const AtomicString& name) const 5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/nameditem.asp 5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This method first searches for an object with a matching id 5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // attribute. If a match is not found, the method then searches for an 5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // object with a matching name attribute, but only on those elements 5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // that are allowed a name attribute. 5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 590926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ContainerNode* root = rootContainerNode(); 591df95704c49daea886ddad70775bda23618d6274dBen Murdoch if (!root) 592926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return 0; 593926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 594df95704c49daea886ddad70775bda23618d6274dBen Murdoch unsigned arrayOffset = 0; 595df95704c49daea886ddad70775bda23618d6274dBen Murdoch unsigned i = 0; 596df95704c49daea886ddad70775bda23618d6274dBen Murdoch for (Element* element = traverseFirstElement(arrayOffset, root); element; element = traverseNextElement(arrayOffset, element, root)) { 597df95704c49daea886ddad70775bda23618d6274dBen Murdoch if (checkForNameMatch(element, /* checkName */ false, name)) { 598df95704c49daea886ddad70775bda23618d6274dBen Murdoch setItemCache(element, i, arrayOffset); 599df95704c49daea886ddad70775bda23618d6274dBen Murdoch return element; 6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 601df95704c49daea886ddad70775bda23618d6274dBen Murdoch i++; 602f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) } 603f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 604df95704c49daea886ddad70775bda23618d6274dBen Murdoch i = 0; 605df95704c49daea886ddad70775bda23618d6274dBen Murdoch for (Element* element = traverseFirstElement(arrayOffset, root); element; element = traverseNextElement(arrayOffset, element, root)) { 606df95704c49daea886ddad70775bda23618d6274dBen Murdoch if (checkForNameMatch(element, /* checkName */ true, name)) { 607df95704c49daea886ddad70775bda23618d6274dBen Murdoch setItemCache(element, i, arrayOffset); 608df95704c49daea886ddad70775bda23618d6274dBen Murdoch return element; 609df95704c49daea886ddad70775bda23618d6274dBen Murdoch } 610df95704c49daea886ddad70775bda23618d6274dBen Murdoch i++; 6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void HTMLCollection::updateNameCache() const 6175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (hasNameCache()) 6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 621926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ContainerNode* root = rootContainerNode(); 622926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!root) 623926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return; 624926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 6255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned arrayOffset = 0; 626926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (Element* element = traverseFirstElement(arrayOffset, root); element; element = traverseNextElement(arrayOffset, element, root)) { 627926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!element->isHTMLElement()) 6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 629926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) HTMLElement* htmlElement = toHTMLElement(element); 630926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) const AtomicString& idAttrVal = htmlElement->getIdAttribute(); 631926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) const AtomicString& nameAttrVal = htmlElement->getNameAttribute(); 6325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!idAttrVal.isEmpty()) 633926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) appendIdCache(idAttrVal, htmlElement); 634926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != DocAll || nameShouldBeVisibleInDocumentAll(htmlElement))) 635926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) appendNameCache(nameAttrVal, htmlElement); 6365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setHasNameCache(); 6395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool HTMLCollection::hasNamedItem(const AtomicString& name) const 6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 643df95704c49daea886ddad70775bda23618d6274dBen Murdoch if (name.isEmpty()) 644df95704c49daea886ddad70775bda23618d6274dBen Murdoch return false; 645df95704c49daea886ddad70775bda23618d6274dBen Murdoch 646df95704c49daea886ddad70775bda23618d6274dBen Murdoch updateNameCache(); 647df95704c49daea886ddad70775bda23618d6274dBen Murdoch 648df95704c49daea886ddad70775bda23618d6274dBen Murdoch if (Vector<Element*>* cache = idCache(name)) { 649df95704c49daea886ddad70775bda23618d6274dBen Murdoch if (!cache->isEmpty()) 650df95704c49daea886ddad70775bda23618d6274dBen Murdoch return true; 651df95704c49daea886ddad70775bda23618d6274dBen Murdoch } 652df95704c49daea886ddad70775bda23618d6274dBen Murdoch 653df95704c49daea886ddad70775bda23618d6274dBen Murdoch if (Vector<Element*>* cache = nameCache(name)) { 654df95704c49daea886ddad70775bda23618d6274dBen Murdoch if (!cache->isEmpty()) 655df95704c49daea886ddad70775bda23618d6274dBen Murdoch return true; 656df95704c49daea886ddad70775bda23618d6274dBen Murdoch } 657df95704c49daea886ddad70775bda23618d6274dBen Murdoch 658df95704c49daea886ddad70775bda23618d6274dBen Murdoch return false; 6595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void HTMLCollection::namedItems(const AtomicString& name, Vector<RefPtr<Node> >& result) const 6625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(result.isEmpty()); 6645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (name.isEmpty()) 6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 6665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateNameCache(); 6685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Vector<Element*>* idResults = idCache(name); 6705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Vector<Element*>* nameResults = nameCache(name); 6715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; idResults && i < idResults->size(); ++i) 6735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.append(idResults->at(i)); 6745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; nameResults && i < nameResults->size(); ++i) 6765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.append(nameResults->at(i)); 6775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<NodeList> HTMLCollection::tags(const String& name) 6805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ownerNode()->getElementsByTagName(name); 6825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 684926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element* element) 6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->value; 6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!vector) 6885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) vector = adoptPtr(new Vector<Element*>); 6895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) vector->append(element); 6905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore 693