darin@apple.com | 6b16660 | 2007-12-03 04:57:59 +0000 | [diff] [blame] | 1 | /* |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 2 | * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 | * (C) 1999 Antti Koivisto (koivisto@kde.org) |
kling@webkit.org | f7ac4f2 | 2012-01-01 04:34:01 +0000 | [diff] [blame] | 4 | * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights reserved. |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 5 | * |
| 6 | * This library is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU Library General Public |
| 8 | * License as published by the Free Software Foundation; either |
| 9 | * version 2 of the License, or (at your option) any later version. |
| 10 | * |
| 11 | * This library is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 14 | * Library General Public License for more details. |
| 15 | * |
| 16 | * You should have received a copy of the GNU Library General Public License |
| 17 | * along with this library; see the file COPYING.LIB. If not, write to |
ddkilzer | c8eccec | 2007-09-26 02:29:57 +0000 | [diff] [blame] | 18 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 19 | * Boston, MA 02110-1301, USA. |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 20 | * |
| 21 | */ |
darin | 36d1136 | 2006-04-11 16:30:21 +0000 | [diff] [blame] | 22 | |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 23 | #include "config.h" |
| 24 | #include "HTMLCollection.h" |
darin | 36d1136 | 2006-04-11 16:30:21 +0000 | [diff] [blame] | 25 | |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 26 | #include "HTMLDocument.h" |
| 27 | #include "HTMLElement.h" |
darin | 98fa8b8 | 2006-03-20 08:03:57 +0000 | [diff] [blame] | 28 | #include "HTMLNames.h" |
beidson | 1564c5e | 2007-05-10 08:55:44 +0000 | [diff] [blame] | 29 | #include "HTMLObjectElement.h" |
eric@webkit.org | 40ddb7c | 2009-08-18 07:16:12 +0000 | [diff] [blame] | 30 | #include "HTMLOptionElement.h" |
weinig | 0d78994 | 2007-06-09 06:00:26 +0000 | [diff] [blame] | 31 | #include "NodeList.h" |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 32 | |
andersca | e4be095 | 2007-07-19 20:04:46 +0000 | [diff] [blame] | 33 | #include <utility> |
| 34 | |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 35 | namespace WebCore { |
| 36 | |
| 37 | using namespace HTMLNames; |
| 38 | |
kling@webkit.org | a3a65e3 | 2012-01-01 21:05:42 +0000 | [diff] [blame] | 39 | HTMLCollection::HTMLCollection(Node* base, CollectionType type) |
| 40 | : m_includeChildren(shouldIncludeChildren(type)) |
andreas.kling@nokia.com | c84be3e | 2011-11-09 18:14:09 +0000 | [diff] [blame] | 41 | , m_type(type) |
kling@webkit.org | f570466 | 2011-12-30 20:15:16 +0000 | [diff] [blame] | 42 | , m_base(base) |
darin@apple.com | 6b16660 | 2007-12-03 04:57:59 +0000 | [diff] [blame] | 43 | { |
kling@webkit.org | fe42004 | 2012-01-07 09:35:21 +0000 | [diff] [blame] | 44 | ASSERT(m_base); |
kling@webkit.org | 9740410 | 2012-01-02 08:42:50 +0000 | [diff] [blame] | 45 | m_cache.clear(); |
kling@webkit.org | 3e527e9 | 2011-12-16 23:11:11 +0000 | [diff] [blame] | 46 | } |
| 47 | |
kling@webkit.org | fccd206 | 2011-12-18 03:41:45 +0000 | [diff] [blame] | 48 | bool HTMLCollection::shouldIncludeChildren(CollectionType type) |
| 49 | { |
| 50 | switch (type) { |
| 51 | case DocAll: |
| 52 | case DocAnchors: |
| 53 | case DocApplets: |
| 54 | case DocEmbeds: |
| 55 | case DocForms: |
| 56 | case DocImages: |
| 57 | case DocLinks: |
| 58 | case DocObjects: |
| 59 | case DocScripts: |
| 60 | case DocumentNamedItems: |
| 61 | case MapAreas: |
| 62 | case OtherCollection: |
| 63 | case SelectOptions: |
| 64 | case DataListOptions: |
| 65 | case WindowNamedItems: |
| 66 | #if ENABLE(MICRODATA) |
| 67 | case ItemProperties: |
| 68 | #endif |
| 69 | return true; |
| 70 | case NodeChildren: |
| 71 | case TRCells: |
| 72 | case TSectionRows: |
| 73 | case TableTBodies: |
| 74 | return false; |
| 75 | } |
| 76 | ASSERT_NOT_REACHED(); |
| 77 | return false; |
| 78 | } |
| 79 | |
kling@webkit.org | fe42004 | 2012-01-07 09:35:21 +0000 | [diff] [blame] | 80 | PassOwnPtr<HTMLCollection> HTMLCollection::create(Node* base, CollectionType type) |
kling@webkit.org | 3e527e9 | 2011-12-16 23:11:11 +0000 | [diff] [blame] | 81 | { |
kling@webkit.org | fe42004 | 2012-01-07 09:35:21 +0000 | [diff] [blame] | 82 | return adoptPtr(new HTMLCollection(base, type)); |
darin@apple.com | 642f500 | 2008-06-07 22:51:37 +0000 | [diff] [blame] | 83 | } |
| 84 | |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 85 | HTMLCollection::~HTMLCollection() |
| 86 | { |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 87 | } |
| 88 | |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 89 | void HTMLCollection::invalidateCacheIfNeeded() const |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 90 | { |
eae@chromium.org | a01dd60 | 2011-03-11 01:46:48 +0000 | [diff] [blame] | 91 | uint64_t docversion = static_cast<HTMLDocument*>(m_base->document())->domTreeVersion(); |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 92 | |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 93 | if (m_cache.version == docversion) |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 94 | return; |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 95 | |
kling@webkit.org | 9740410 | 2012-01-02 08:42:50 +0000 | [diff] [blame] | 96 | m_cache.clear(); |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 97 | m_cache.version = docversion; |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 98 | } |
| 99 | |
kling@webkit.org | fccd206 | 2011-12-18 03:41:45 +0000 | [diff] [blame] | 100 | inline bool HTMLCollection::isAcceptableElement(Element* element) const |
| 101 | { |
| 102 | switch (m_type) { |
| 103 | case DocImages: |
| 104 | return element->hasLocalName(imgTag); |
| 105 | case DocScripts: |
| 106 | return element->hasLocalName(scriptTag); |
| 107 | case DocForms: |
| 108 | return element->hasLocalName(formTag); |
| 109 | case TableTBodies: |
| 110 | return element->hasLocalName(tbodyTag); |
| 111 | case TRCells: |
| 112 | return element->hasLocalName(tdTag) || element->hasLocalName(thTag); |
| 113 | case TSectionRows: |
| 114 | return element->hasLocalName(trTag); |
| 115 | case SelectOptions: |
| 116 | return element->hasLocalName(optionTag); |
| 117 | case DataListOptions: |
| 118 | if (element->hasLocalName(optionTag)) { |
| 119 | HTMLOptionElement* option = static_cast<HTMLOptionElement*>(element); |
| 120 | if (!option->disabled() && !option->value().isEmpty()) |
| 121 | return true; |
| 122 | } |
| 123 | return false; |
| 124 | case MapAreas: |
| 125 | return element->hasLocalName(areaTag); |
| 126 | case DocApplets: |
| 127 | return element->hasLocalName(appletTag) || (element->hasLocalName(objectTag) && static_cast<HTMLObjectElement*>(element)->containsJavaApplet()); |
| 128 | case DocEmbeds: |
| 129 | return element->hasLocalName(embedTag); |
| 130 | case DocObjects: |
| 131 | return element->hasLocalName(objectTag); |
| 132 | case DocLinks: |
| 133 | return (element->hasLocalName(aTag) || element->hasLocalName(areaTag)) && element->fastHasAttribute(hrefAttr); |
| 134 | case DocAnchors: |
| 135 | return element->hasLocalName(aTag) && element->fastHasAttribute(nameAttr); |
| 136 | case DocAll: |
| 137 | case NodeChildren: |
| 138 | return true; |
| 139 | #if ENABLE(MICRODATA) |
| 140 | case ItemProperties: |
| 141 | return element->isHTMLElement() && element->fastHasAttribute(itempropAttr); |
| 142 | #endif |
| 143 | case DocumentNamedItems: |
| 144 | case OtherCollection: |
| 145 | case WindowNamedItems: |
| 146 | ASSERT_NOT_REACHED(); |
| 147 | } |
| 148 | return false; |
| 149 | } |
| 150 | |
darin@apple.com | 6b16660 | 2007-12-03 04:57:59 +0000 | [diff] [blame] | 151 | static Node* nextNodeOrSibling(Node* base, Node* node, bool includeChildren) |
| 152 | { |
| 153 | return includeChildren ? node->traverseNextNode(base) : node->traverseNextSibling(base); |
| 154 | } |
| 155 | |
| 156 | Element* HTMLCollection::itemAfter(Element* previous) const |
| 157 | { |
darin@apple.com | 6b16660 | 2007-12-03 04:57:59 +0000 | [diff] [blame] | 158 | Node* current; |
| 159 | if (!previous) |
| 160 | current = m_base->firstChild(); |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 161 | else |
kling@webkit.org | fccd206 | 2011-12-18 03:41:45 +0000 | [diff] [blame] | 162 | current = nextNodeOrSibling(m_base, previous, m_includeChildren); |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 163 | |
kling@webkit.org | fccd206 | 2011-12-18 03:41:45 +0000 | [diff] [blame] | 164 | for (; current; current = nextNodeOrSibling(m_base, current, m_includeChildren)) { |
darin@apple.com | 6b16660 | 2007-12-03 04:57:59 +0000 | [diff] [blame] | 165 | if (!current->isElementNode()) |
| 166 | continue; |
kling@webkit.org | fccd206 | 2011-12-18 03:41:45 +0000 | [diff] [blame] | 167 | Element* element = static_cast<Element*>(current); |
| 168 | if (isAcceptableElement(element)) |
| 169 | return element; |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 170 | } |
darin@apple.com | 6b16660 | 2007-12-03 04:57:59 +0000 | [diff] [blame] | 171 | |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 172 | return 0; |
| 173 | } |
| 174 | |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 175 | unsigned HTMLCollection::calcLength() const |
| 176 | { |
| 177 | unsigned len = 0; |
darin@apple.com | 6b16660 | 2007-12-03 04:57:59 +0000 | [diff] [blame] | 178 | for (Element* current = itemAfter(0); current; current = itemAfter(current)) |
| 179 | ++len; |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 180 | return len; |
| 181 | } |
| 182 | |
| 183 | // since the collections are to be "live", we have to do the |
| 184 | // calculation every time if anything has changed |
| 185 | unsigned HTMLCollection::length() const |
| 186 | { |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 187 | invalidateCacheIfNeeded(); |
| 188 | if (!m_cache.hasLength) { |
| 189 | m_cache.length = calcLength(); |
| 190 | m_cache.hasLength = true; |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 191 | } |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 192 | return m_cache.length; |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 193 | } |
| 194 | |
darin@apple.com | 6b16660 | 2007-12-03 04:57:59 +0000 | [diff] [blame] | 195 | Node* HTMLCollection::item(unsigned index) const |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 196 | { |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 197 | invalidateCacheIfNeeded(); |
| 198 | if (m_cache.current && m_cache.position == index) |
| 199 | return m_cache.current; |
| 200 | if (m_cache.hasLength && m_cache.length <= index) |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 201 | return 0; |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 202 | if (!m_cache.current || m_cache.position > index) { |
| 203 | m_cache.current = itemAfter(0); |
| 204 | m_cache.position = 0; |
| 205 | if (!m_cache.current) |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 206 | return 0; |
| 207 | } |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 208 | Element* e = m_cache.current; |
| 209 | for (unsigned pos = m_cache.position; e && pos < index; pos++) |
darin@apple.com | 6b16660 | 2007-12-03 04:57:59 +0000 | [diff] [blame] | 210 | e = itemAfter(e); |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 211 | m_cache.current = e; |
| 212 | m_cache.position = index; |
| 213 | return m_cache.current; |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 214 | } |
| 215 | |
darin@apple.com | 6b16660 | 2007-12-03 04:57:59 +0000 | [diff] [blame] | 216 | Node* HTMLCollection::firstItem() const |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 217 | { |
| 218 | return item(0); |
| 219 | } |
| 220 | |
darin@apple.com | 6b16660 | 2007-12-03 04:57:59 +0000 | [diff] [blame] | 221 | Node* HTMLCollection::nextItem() const |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 222 | { |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 223 | invalidateCacheIfNeeded(); |
kling@webkit.org | f16278a | 2012-01-01 05:54:09 +0000 | [diff] [blame] | 224 | |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 225 | // Look for the 'second' item. The first one is currentItem, already given back. |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 226 | Element* retval = itemAfter(m_cache.current); |
| 227 | m_cache.current = retval; |
| 228 | m_cache.position++; |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 229 | return retval; |
| 230 | } |
| 231 | |
darin@apple.com | 2b0054e | 2011-12-06 17:30:00 +0000 | [diff] [blame] | 232 | static inline bool nameShouldBeVisibleInDocumentAll(HTMLElement* element) |
| 233 | { |
| 234 | // The document.all collection returns only certain types of elements by name, |
| 235 | // although it returns any type of element by id. |
| 236 | return element->hasLocalName(appletTag) |
| 237 | || element->hasLocalName(embedTag) |
| 238 | || element->hasLocalName(formTag) |
| 239 | || element->hasLocalName(imgTag) |
| 240 | || element->hasLocalName(inputTag) |
| 241 | || element->hasLocalName(objectTag) |
| 242 | || element->hasLocalName(selectTag); |
| 243 | } |
| 244 | |
darin@apple.com | 72b7bb5 | 2009-01-05 17:32:03 +0000 | [diff] [blame] | 245 | bool HTMLCollection::checkForNameMatch(Element* element, bool checkName, const AtomicString& name) const |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 246 | { |
darin@apple.com | 6b16660 | 2007-12-03 04:57:59 +0000 | [diff] [blame] | 247 | if (!element->isHTMLElement()) |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 248 | return false; |
| 249 | |
yael.aharon@nokia.com | 3be82c1 | 2011-02-09 23:13:27 +0000 | [diff] [blame] | 250 | HTMLElement* e = toHTMLElement(element); |
darin@apple.com | 72b7bb5 | 2009-01-05 17:32:03 +0000 | [diff] [blame] | 251 | if (!checkName) |
darin@apple.com | f5247d1 | 2010-06-13 17:29:10 +0000 | [diff] [blame] | 252 | return e->getIdAttribute() == name; |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 253 | |
darin@apple.com | 2b0054e | 2011-12-06 17:30:00 +0000 | [diff] [blame] | 254 | if (m_type == DocAll && !nameShouldBeVisibleInDocumentAll(e)) |
darin@apple.com | 72b7bb5 | 2009-01-05 17:32:03 +0000 | [diff] [blame] | 255 | return false; |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 256 | |
kling@webkit.org | 11744b1 | 2012-02-11 14:50:28 +0000 | [diff] [blame] | 257 | return e->getNameAttribute() == name && e->getIdAttribute() != name; |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 258 | } |
| 259 | |
darin@apple.com | 72b7bb5 | 2009-01-05 17:32:03 +0000 | [diff] [blame] | 260 | Node* HTMLCollection::namedItem(const AtomicString& name) const |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 261 | { |
| 262 | // http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/nameditem.asp |
| 263 | // This method first searches for an object with a matching id |
| 264 | // attribute. If a match is not found, the method then searches for an |
| 265 | // object with a matching name attribute, but only on those elements |
| 266 | // that are allowed a name attribute. |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 267 | invalidateCacheIfNeeded(); |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 268 | |
darin@apple.com | 6b16660 | 2007-12-03 04:57:59 +0000 | [diff] [blame] | 269 | for (Element* e = itemAfter(0); e; e = itemAfter(e)) { |
andreas.kling@nokia.com | f1b44fe | 2011-11-13 14:53:48 +0000 | [diff] [blame] | 270 | if (checkForNameMatch(e, /* checkName */ false, name)) { |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 271 | m_cache.current = e; |
darin@apple.com | 6b16660 | 2007-12-03 04:57:59 +0000 | [diff] [blame] | 272 | return e; |
| 273 | } |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 274 | } |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 275 | |
darin@apple.com | 6b16660 | 2007-12-03 04:57:59 +0000 | [diff] [blame] | 276 | for (Element* e = itemAfter(0); e; e = itemAfter(e)) { |
andreas.kling@nokia.com | f1b44fe | 2011-11-13 14:53:48 +0000 | [diff] [blame] | 277 | if (checkForNameMatch(e, /* checkName */ true, name)) { |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 278 | m_cache.current = e; |
darin@apple.com | 6b16660 | 2007-12-03 04:57:59 +0000 | [diff] [blame] | 279 | return e; |
| 280 | } |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 281 | } |
| 282 | |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 283 | m_cache.current = 0; |
darin@apple.com | 6b16660 | 2007-12-03 04:57:59 +0000 | [diff] [blame] | 284 | return 0; |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 285 | } |
| 286 | |
| 287 | void HTMLCollection::updateNameCache() const |
| 288 | { |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 289 | if (m_cache.hasNameCache) |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 290 | return; |
kling@webkit.org | f16278a | 2012-01-01 05:54:09 +0000 | [diff] [blame] | 291 | |
darin@apple.com | 6b16660 | 2007-12-03 04:57:59 +0000 | [diff] [blame] | 292 | for (Element* element = itemAfter(0); element; element = itemAfter(element)) { |
| 293 | if (!element->isHTMLElement()) |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 294 | continue; |
yael.aharon@nokia.com | 3be82c1 | 2011-02-09 23:13:27 +0000 | [diff] [blame] | 295 | HTMLElement* e = toHTMLElement(element); |
darin@apple.com | f5247d1 | 2010-06-13 17:29:10 +0000 | [diff] [blame] | 296 | const AtomicString& idAttrVal = e->getIdAttribute(); |
kling@webkit.org | 11744b1 | 2012-02-11 14:50:28 +0000 | [diff] [blame] | 297 | const AtomicString& nameAttrVal = e->getNameAttribute(); |
darin@apple.com | 2b0054e | 2011-12-06 17:30:00 +0000 | [diff] [blame] | 298 | if (!idAttrVal.isEmpty()) |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 299 | append(m_cache.idCache, idAttrVal, e); |
darin@apple.com | 2b0054e | 2011-12-06 17:30:00 +0000 | [diff] [blame] | 300 | if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (m_type != DocAll || nameShouldBeVisibleInDocumentAll(e))) |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 301 | append(m_cache.nameCache, nameAttrVal, e); |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 302 | } |
| 303 | |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 304 | m_cache.hasNameCache = true; |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 305 | } |
| 306 | |
kling@webkit.org | 5c2d0a2 | 2011-12-18 22:21:05 +0000 | [diff] [blame] | 307 | bool HTMLCollection::hasNamedItem(const AtomicString& name) const |
| 308 | { |
| 309 | if (name.isEmpty()) |
| 310 | return false; |
| 311 | |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 312 | invalidateCacheIfNeeded(); |
kling@webkit.org | 5c2d0a2 | 2011-12-18 22:21:05 +0000 | [diff] [blame] | 313 | updateNameCache(); |
kling@webkit.org | 5c2d0a2 | 2011-12-18 22:21:05 +0000 | [diff] [blame] | 314 | |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 315 | if (Vector<Element*>* idCache = m_cache.idCache.get(name.impl())) { |
kling@webkit.org | 5c2d0a2 | 2011-12-18 22:21:05 +0000 | [diff] [blame] | 316 | if (!idCache->isEmpty()) |
| 317 | return true; |
| 318 | } |
| 319 | |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 320 | if (Vector<Element*>* nameCache = m_cache.nameCache.get(name.impl())) { |
kling@webkit.org | 5c2d0a2 | 2011-12-18 22:21:05 +0000 | [diff] [blame] | 321 | if (!nameCache->isEmpty()) |
| 322 | return true; |
| 323 | } |
| 324 | |
| 325 | return false; |
| 326 | } |
| 327 | |
darin@apple.com | 6b16660 | 2007-12-03 04:57:59 +0000 | [diff] [blame] | 328 | void HTMLCollection::namedItems(const AtomicString& name, Vector<RefPtr<Node> >& result) const |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 329 | { |
andersca | 02b2f19 | 2006-11-16 21:22:48 +0000 | [diff] [blame] | 330 | ASSERT(result.isEmpty()); |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 331 | if (name.isEmpty()) |
andersca | 02b2f19 | 2006-11-16 21:22:48 +0000 | [diff] [blame] | 332 | return; |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 333 | |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 334 | invalidateCacheIfNeeded(); |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 335 | updateNameCache(); |
ap@apple.com | 5b3b14b | 2010-01-27 23:41:50 +0000 | [diff] [blame] | 336 | |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 337 | Vector<Element*>* idResults = m_cache.idCache.get(name.impl()); |
| 338 | Vector<Element*>* nameResults = m_cache.nameCache.get(name.impl()); |
| 339 | |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 340 | for (unsigned i = 0; idResults && i < idResults->size(); ++i) |
andersca | 02b2f19 | 2006-11-16 21:22:48 +0000 | [diff] [blame] | 341 | result.append(idResults->at(i)); |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 342 | |
| 343 | for (unsigned i = 0; nameResults && i < nameResults->size(); ++i) |
andersca | 02b2f19 | 2006-11-16 21:22:48 +0000 | [diff] [blame] | 344 | result.append(nameResults->at(i)); |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 345 | } |
| 346 | |
weinig | 0d78994 | 2007-06-09 06:00:26 +0000 | [diff] [blame] | 347 | PassRefPtr<NodeList> HTMLCollection::tags(const String& name) |
| 348 | { |
darin@apple.com | 6b16660 | 2007-12-03 04:57:59 +0000 | [diff] [blame] | 349 | return m_base->getElementsByTagName(name); |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 350 | } |
weinig | 0d78994 | 2007-06-09 06:00:26 +0000 | [diff] [blame] | 351 | |
kling@webkit.org | 048cb3d | 2012-01-02 00:37:59 +0000 | [diff] [blame] | 352 | void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element* element) |
| 353 | { |
| 354 | OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).first->second; |
| 355 | if (!vector) |
| 356 | vector = adoptPtr(new Vector<Element*>); |
| 357 | vector->append(element); |
| 358 | } |
| 359 | |
weinig | 0d78994 | 2007-06-09 06:00:26 +0000 | [diff] [blame] | 360 | } // namespace WebCore |